BAL and Maple Release 2.2
Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bal_release/.release_build b/bal_release/.release_build
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bal_release/.release_build
diff --git a/bal_release/3rdparty/bcm-sdk/Makefile b/bal_release/3rdparty/bcm-sdk/Makefile
new file mode 100644
index 0000000..5e0dfd6
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/Makefile
@@ -0,0 +1,30 @@
+# Switch SDK for KT2
+#
+
+ifneq ("$(TEST_SW_UTIL_LOOPBACK)", "y")
+
+MOD_NAME = switch_sdk
+MOD_TYPE = lib
+
+MOD_INC_DIRS = $(ING_SDK_DIR)/include
+MOD_INC_DIRS += $(ING_SDK_DIR)/libs/phymod/include
+MOD_LIBS_NOREC_BEFORE = $(shell cat ${ING_SDK_DIR}/.bcm_objs)
+MOD_LIBS = $(shell cat ${ING_SDK_DIR}/.bcm_libs)
+MOD_LIBS_NOREC_AFTER = $(shell cat ${ING_SDK_DIR}/.bcm_ldflags | sed -e 's/-static //') -lutil
+
+# Building with libnetconf requires special care because libxml in bcm_sdk conflicts
+# with newer libxml2
+ifeq ("$(NC_AGENT)", "libnetconf")
+ MOD_LIBS := $(subst -lxml,,$(MOD_LIBS))
+
+ # This is tricky again. SDK build can include multiple versions of xml_api.o
+ # built for different architectures. We need to pick the right one.
+ _all_xml_api := $(shell find $(ING_SDK_DIR) -name xml_api.o)
+ _arch := $(shell file $(firstword $(MOD_LIBS_NOREC_BEFORE)) | awk '{print $$7}')
+ _xml_api := $(shell for aa in $(_all_xml_api); do _test_arch=`file $$aa | awk '{print $$7}'`; if [[ \"$(_arch)\" = \"$$_test_arch\" ]]; then echo $$aa; fi; done)
+
+ MOD_LIBS_NOREC_AFTER += $(_xml_api)
+endif
+
+# end of ifneq ("$(TEST_SW_UTIL_LOOPBACK)", "y")
+endif
diff --git a/bal_release/3rdparty/bcm-sdk/Makefile.sdk b/bal_release/3rdparty/bcm-sdk/Makefile.sdk
new file mode 100644
index 0000000..5f1776d
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/Makefile.sdk
@@ -0,0 +1,60 @@
+# ING SDK
+#
+
+ifeq ("$(BOARD)", "wrx")
+ TARGET_DIR ?= systems/linux/user/wrx-3_7
+else
+ TARGET_DIR ?= systems/sim
+ export CONFIG_SWITCH_RPC=y
+endif
+
+export BUILD_ING_AS_LIB=1
+export SDK=$(ING_SDK_DIR)
+
+ifeq ("$(BOARD)", "wrx")
+ CMD_PARMS=platform=wrx-3_7 bldroot_suffix=/wrx-3_7 kernel_version=3_7 LINUX_MAKE_SHARED_LIB=0 SHAREDLIBVER=1 WRX_64BIT=1
+ $(info evaluating $(CMD_PARMS))
+ $(foreach _cmd,$(CMD_PARMS),$(eval export $(_cmd)))
+ include $(ING_SDK_DIR)/systems/linux/user/common/Makefile
+ BCM_LIBS_DEPS = user_libs $(BLDDIR)/socdiag.o $(BLDDIR)/version.o $(PLATFORM_DEFINES_OBJ) $(KERNEL_BDE) $(USER_BDE)
+ MAIN_LIB := $(BLDDIR)/socdiag.o $(MAIN_LIB)
+ CGLAGS += $(ARCH_FLAGS)
+
+$(BLDDIR)/socdiag.o:: $(ING_SDK_DIR)/systems/linux/user/common/socdiag.c
+ @mkdir -p $(BLDDIR)
+ $(CC) -c -o $@ $(CFLAGS) $<
+
+else
+
+ include $(ING_SDK_DIR)/$(TARGET_DIR)/Makefile
+
+ifdef DPP_CHIPS
+$(LIBDIR)/libchipsim_sim.$(libext):
+ make -C $(ING_SDK_DIR)/$(TARGET_DIR)/dpp/ChipSim
+endif
+
+ BCM_LIBS_DEPS = $(MAIN_LIB) _bde _bcm_libraries $(BLDDIR)/version.o $(PLATFORM_DEFINES_OBJ) $(BCM_LIBS_BLD)
+
+endif
+
+# ING SDK links very strange. Instead of using -l, all libraries are added to executable as objects
+# it is better to convert to -l directives
+BCM_LIB_PATH := $(dir $(firstword $(BCM_LIBS_BLD)))
+BCM_LIB_LIST := $(patsubst lib%.a,-l%,$(notdir $(BCM_LIBS_BLD)))
+EXTRA_CFLAGS += -Wno-error=unused-value -Wno-unused-but-set-variable -Wno-format-security
+export EXTRA_CFLAGS
+
+sdk: $(ING_SDK_DIR)/.bcm_libs
+ echo "done: `ls $(ING_SDK_DIR)/$(TARGET_DIR)/`"
+
+$(ING_SDK_DIR)/.bcm_libs: $(BCM_LIBS_DEPS)
+ echo "Building BCM SDK ... $(TARGET_DIR)"
+ @echo $(MAIN_LIB) $(BLDDIR)/version.o $(PLATFORM_DEFINES_OBJ) > $(ING_SDK_DIR)/.bcm_objs
+ @echo -L$(BCM_LIB_PATH) $(BCM_LIB_LIST) > $(ING_SDK_DIR)/.bcm_libs
+ @echo $(LDFLAGS) > $(ING_SDK_DIR)/.bcm_ldflags
+
+$(BLDDIR)/%.o:: $(ING_SDK_DIR)/$(TARGET_DIR)/%.c
+ @mkdir -p $(BLDDIR)
+ $(CC) -c -o $@ $(CFLAGS) $<
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/make/Make.local.all b/bal_release/3rdparty/bcm-sdk/make/Make.local.all
new file mode 100755
index 0000000..9fa470f
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make/Make.local.all
@@ -0,0 +1,571 @@
+# $Id: Make.local.template,v 1.181 Broadcom SDK $
+# $Copyright: Copyright 2012 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+
+# Usage for Make.local.template and Make.local:
+#
+# Make.local.template is checked into the tree, but Make.local is never
+# checked in. Copy Make.local.template to Make.local, then change
+# Make.local to select the desired compilation options (mostly debugging
+# features).
+#
+# Note on CFGFLAGS usage:
+#
+# Because CFGFLAGS may be used with other source preprocessing tools,
+# please limit the values added to CFGFLAGS to -D defines.
+#
+#
+# Table of Contents:
+#
+# Compiler Related Options
+# Boot and Debug Related Options
+# Operational and Policy Options
+# System Management and Multiple CPU Options
+# Selective Device Support (Switches and PHYs)
+# Miscellaneous Options
+#
+
+################################################################
+#
+# Compiler Related Options
+#
+################################################################
+
+# Compiling out #ifdef DEBUG code saves about 1.3% on executable size.
+# It is recommended to leave debug enabled when developing applications.
+#DEBUG_IFDEFS=FALSE
+
+# SAL resource usage tracking #ifdef control
+# DEBUG_IFDEFS should also be TRUE for this switch to take effect.
+#BCM_RESOURCE_USAGE_PROFILE_IFDEFS=TRUE
+
+# Uncomment to build without debug symbols
+#DEBUG_SYMBOLS=FALSE
+
+# Uncomment to add private CFLAGS
+#DEBUG_CFLAGS=
+
+# Uncomment to turn off the optimizer when debugging (recommended)
+#DEBUG_OPTIMIZE=FALSE
+
+# Compiling out assert() saves about 1.1% on executable size,
+# however do so is VERY MUCH discouraged.
+#DEBUG_ASSERTS=FALSE
+
+# Controlling GCC -pedantic flag
+#DEBUG_PEDANTIC=TRUE
+
+# compiler.h overrides, these disable various compiler
+# related features even if the compiler normally supports them
+
+# Disable use of long long for uint64
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_LONGLONG
+
+# Disable use of doubles
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_DOUBLE
+
+# Disable inlining of functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_INLINE
+
+# Disable use of const
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_CONST
+
+# Disable use of static functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_STATIC
+
+# Disable RPC flexible (long) bitmaps.
+# Warning: Disabling this changes the RPC version to 2 and
+# makes systems running this code incompatible with systems
+# running previous versions of BCM RPC code.
+#CFGFLAGS += -DBCM_RPC_PBMP_64
+
+#
+# Define if longs are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+#CFGFLAGS += -DLONGS_ARE_64BITS
+
+#
+# Define if pointers are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+# NOTE: This support works ONLY under conditions where the
+# upper 32 bits for ALL pointers are ZERO.
+#CFGFLAGS += -DPTRS_ARE_64BITS
+
+
+################################################################
+#
+# Boot and Debug Related Options
+#
+################################################################
+
+# Define this to add debug code for RX pool buffer tracking
+#CFGFLAGS += -DBCM_RXP_DEBUG
+
+# Allow debugging of PCI reads/writes (debug +pci)
+#CFGFLAGS += -DSOC_PCI_DEBUG
+
+# Make default debugging settings be 0 (very very quiet)
+#CFGFLAGS += -DNO_DEBUG_OUTPUT_DEFAULT
+
+# Don't use vxMemProbe
+#CFGFLAGS += -DVX_NO_MEM_PROBE
+
+# Allow debugging of Memory Allocation/Deallocation logging
+#CFGFLAGS += -DMEMLOG_SUPPORT
+
+################################################################
+################################################################
+#
+# Operational and Policy Options
+#
+################################################################
+
+# VLAN policy control:
+# NO_DEFAULT_ETHER do not init ether ports into vlan 1
+# NO_DEFAULT_CPU do not init cpu ports into vlan 1
+# NO_DEFAULT_SPI_SUBPORT do not init spi subports into vlan 1
+# NO_AUTO_STACK do not init stack/HG ports into created vlans
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_ETHER
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_CPU
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_SPI_SUBPORT
+#CFGFLAGS += -DBCM_VLAN_NO_AUTO_STACK
+
+# VLAN multicast flood Policy Control:
+# BCM_VLAN_MCAST_FLOOD_ALL Flood all multicast packets to the VLAN
+# BCM_VLAN_MCAST_FLOOD_UNKNOWN Flood unknown multicast packets to the vlan
+# BCM_VLAN_MCAST_FLOOD_NONE Forward multicast packets with known
+# destination addresses to the appropriate ports.
+# All packets destined to an unknown multicast
+# address are dropped.
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_ALL
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_UNKNOWN
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_NONE
+
+#Port Enable/Disable Policy control:
+# PORT_DEFAULT_DISABLE disable ports during switch initialization
+#CFGFLAGS += -DBCM_PORT_DEFAULT_DISABLE
+
+# sal thread priority override (this value used for all threads if defined)
+#CFGFLAGS += -DSAL_THREAD_PRIORITY=255
+
+# disable printing of thread name in messages
+#CFGFLAGS += -DSAL_THREAD_NAME_PRINT_DISABLE
+
+# disable runtime reading of flash config.bcm file (even if !NO_FILEIO)
+#CFGFLAGS += -DSAL_CONFIG_FILE_DISABLE
+
+# disable all Application SAL dependencies
+#NO_SAL_APPL=1
+
+
+# Prevent scheduling in SPL locks when interrupt code is run as a thread.
+# This option should not be necessary if all locks are implemented correctly,
+# however, some locks may still rely on the assumption that scheduling does
+# not occur when interrupts are disabled. If you experience any locking
+# problems in e.g. Linux User Mode, try enabling this option.
+# Please note that turning on this option will reduce performance by an
+# estimated 5 to 10 %.
+#CFGFLAGS += -DSAL_SPL_NO_PREEMPT
+
+# disable mapping of higig cosq when mapping priority to cosq
+# (use identity mapping instead : map prio0->cos0, prio1->cos1, ... , prio7->cos7)
+#CFGFLAGS += -DBCM_COSQ_HIGIG_MAP_DISABLE
+
+# Enable ukernel debugging module
+#CFGFLAGS += -DSOC_UKERNEL_DEBUG
+
+
+################################################################
+#
+# System Management and Multiple CPU Options
+#
+################################################################
+
+# Turn on BCMX inclusion
+# INCLUDE_BCMX for any support
+INCLUDE_BCMX=1
+
+# Telekinesis suite applications for CPU to CPU communication and discovery
+# CPUDB: Simple CPU data base manager
+# CPUTRANS: CPU to CPU communication mechanisms
+# DISCOVER: Simple discovery; will also include CPUTRANS
+# STKTASK: Stack manager application
+#
+#CFGFLAGS += -DINCLUDE_LIB_CPUDB
+#CFGFLAGS += -DINCLUDE_LIB_CPUTRANS
+#CFGFLAGS += -DINCLUDE_LIB_DISCOVER
+#CFGFLAGS += -DINCLUDE_LIB_STKTASK
+
+# Option for discovery to use the application-data field in routing
+# packets for Board-ID and CPU base flag information.
+#CFGFLAGS += -DDISCOVER_APP_DATA_BOARDID
+
+# Optionally override list of included dispatch modules
+# Note: including RPC automatically includes the Telekinesis suite libs
+# ESW is the enterprise platforms.
+# ROBO includes the managed devices.
+# SBX includes API support for bcm988020QSK24X2
+#DISPATCH_LIST = RPC ESW ASYNC SBX
+
+# Define to have end-to-end flow control enabled on boards that
+# support it
+#CFGFLAGS += -DBCM_BOARD_AUTO_E2E
+
+# Define the following to support per-CPU transmit pointers.
+# This allows the TX setup and send functions to be defined on a
+# per-CPU basis, allowing mixed in-band and out-of-band communication.
+#CFGFLAGS += -DBCM_C2C_TRANSPORT_SWITCHING
+
+# Options for feature list (INCLUDE_XXX)
+# If FEATURE_LIST is defined, it is a list of features to include.
+# See Make.config for the default feature list.
+#
+# Avaliable features:
+#
+# BCMX
+# BCMX_DIAG
+# CHASSIS
+# CUSTOMER
+# DRIVERS
+# EDITLINE
+# I2C
+# L3
+# MEM_SCAN
+# ATPTRANS_SOCKET
+# TELNET
+# TEST
+# ACL
+# RCPU
+# KNET - Linux user mode kernel network support
+# BCM_SAL_PROFILE - make available an API to track SAL usage.
+# CINT - Include the C Interpreter in the diagnostic shell.
+# Please note this cannot be used in Linux kernel mode.
+# C_UNIT - Include the C unit testing framework. If CINT is also included
+# then hooks will be provided for use from it.
+# PHY_SYM_DBG - PHY GUI MDIO read/write support. Socket interface
+# to PHY GUI for Symbolic debugging.
+# APIMODE - call SDK API functions from shell, requires CINT
+# DUNE_UI - dune legacy user interface. For debug only. Tested
+# on linux-user-gto-2.6 only.
+# KBP - include nlm2(11K)/nlm3(12K) KBP support
+# BHH - Include Support for BHH Application (MPLS-TP OAM based on Y.1731)
+# using BTE on select devices.
+# AVS - Include AVS support
+#FEATURE_LIST=ATPTRANS_SOCKET BCMX_DIAG L3 I2C BCMX MEM_SCAN EDITLINE \
+# CUSTOMER TELNET DRIVERS CHASSIS TEST ACL RCPU BCM_SAL_PROFILE CINT \
+# PTP CES FCMAP BOARD KNET REGEX MACSEC APIMODE BFD KBP AVS
+
+#FEATURE_LIST= ATPTRANS_SOCKET PTP CINT L3 I2C BCMX BCMX_DIAG MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU
+
+# ARAD + KT2
+FEATURE_LIST= ATPTRANS_SOCKET PTP CINT L3 I2C BCMX BCMX_DIAG MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU INTR BSAFE TELNET DRIVERS DUNE_UI
+#
+###############################################################
+# KBP supported devices
+#
+#Enable this for 11K device support
+#KBP_DEVICE = KBP_11K
+#
+#Enable this for 12K device support
+#KBP_DEVICE = KBP_ALG
+#
+###############################################################
+
+################################################################
+#
+# Selective Device Support (Switches and PHYs)
+#
+################################################################
+
+# Multiple Chip Support
+#
+# By default, the driver supports all Strata switch and fabric chips
+# included in this software release. It checks device IDs at runtime
+# to run the correct driver modules.
+#
+# To save space, the driver can be compiled to support just a subset of
+# the chips. To do this, uncomment the line for BCM_PTL_SPT (partial
+# support) and uncomment one line for each chip to support.
+#
+# Note that there are a lot more chips than drivers.
+# For example, the BCM5615 driver is also used for BCM5625 and BCM5645.
+#
+
+BCM_PTL_SPT = 1
+
+#BCM_5675_A0 = 1
+#BCM_56102_A0 = 1
+#BCM_56112_A0 = 1
+#BCM_56304_B0 = 1
+#BCM_56314_A0 = 1
+#BCM_56504_A0 = 1
+#BCM_56504_B0 = 1
+#BCM_56514_A0 = 1
+#BCM_56624_A0 = 1
+#BCM_56624_B0 = 1
+#BCM_56680_A0 = 1
+#BCM_56680_B0 = 1
+#BCM_56580_A0 = 1
+#BCM_56700_A0 = 1
+#BCM_56800_A0 = 1
+#BCM_56218_A0 = 1
+#BCM_56224_A0 = 1
+#BCM_56224_B0 = 1
+#BCM_56725_A0 = 1
+#BCM_56820_A0 = 1
+#BCM_53314_A0 = 1
+#BCM_53324_A0 = 1
+#BCM_56634_A0 = 1
+#BCM_56634_B0 = 1
+#BCM_56524_A0 = 1
+#BCM_56524_B0 = 1
+#BCM_56685_A0 = 1
+#BCM_56685_B0 = 1
+#BCM_56334_A0 = 1
+#BCM_56334_B0 = 1
+#BCM_56840_A0 = 1
+#BCM_56840_B0 = 1
+#BCM_56850_A0 = 1
+#BCM_56142_A0 = 1
+#BCM_56150_A0 = 1
+#BCM_56836_A0 = 1
+#BCM_56640_A0 = 1
+BCM_56440_A0 = 1
+BCM_56440_B0 = 1
+BCM_56450_A0 = 1
+BCM_56450_B0 = 1
+BCM_56450_B1 = 1
+#BCM_56960_A0 = 1
+#BCM_56860_A0 = 1
+
+#BCM_5338_A0 = 1
+#BCM_5380_A0 = 1
+#BCM_5338_B0 = 1
+#BCM_5325_A1 = 1
+
+#BCM_5324_A0 = 1
+#BCM_5396_A0 = 1
+#BCM_5389_A0 = 1
+#BCM_5398_A0 = 1
+#BCM_5324_A1 = 1
+#BCM_53115_A0 = 1
+#BCM_53118_A0 = 1
+#BCM_53280_A0 = 1
+#BCM_53280_B0 = 1
+#BCM_53101_A0 = 1
+#BCM_53125_A0 = 1
+#BCM_53128_A0 = 1
+#BCM_53600_A0 = 1
+#BCM_89500_A0 = 1
+
+#BCM_88030_A0 = 1
+#BCM_QE2000_A0 = 1
+#BCM_BME3200_B0 = 1
+#BCM_BM9600_A0 = 1
+#BCM_88230_A0 = 1
+#BCM_88230_B0 = 1
+#BCM_88230_C0 = 1
+
+# ARAD
+BCM_88640_A0=1
+BCM_88650_A0=1
+BCM_88650_B0=1
+BCM_88660_A0=1
+
+#BCM_TK371X_A0 = 1
+
+# Options for multiple PHY support
+# If BCM_PHY_LIST is defined, it is a list of PHYs to include.
+# The default is to include all of them.
+# If none of them should be included specify BCM_PHY_LIST=EMPTY
+#BCM_PHY_LIST=522X 54XX 5464 5421S 5482 54616 54680 54680E 52681E 54880E 54682 54684 54640 54640E 54880 SERDES SIMUL 8703 8705 8706 8072 8040 8481 8750 8729 84740 84756 84328 EMPTY
+
+# Options for BCM5338 5380
+#CFGFLAGS += -DROBO_OLD
+#ROBO_OLD = 1
+
+# Support for phy simulation
+#CFGFLAGS += -DINCLUDE_PHY_SIMUL
+#CFGFLAGS += -DSIM_ALL_PHYS # All phys use simulation driver
+#CFGFLAGS += -DSIM_CMIC_LINK_STAT # Get link status from CMIC register
+
+# Support for BOARD library
+# if BOARD_LIST is defined, it is a list of Board drivers to include.
+# The default is to include all board drivers appropriate for the devices
+# included in the build. If none of them should be included specify
+# BOARD_LIST=EMPTY.
+#BOARD_LIST=GENERIC
+
+# Support for event logging
+#CFGFLAGS += -DINCLUDE_SHARED_EVLOG
+
+# Support for BCM API port translation
+#CFGFLAGS += -DINCLUDE_BCM_API_XLATE_PORT
+
+# Support for callback error checks and abort in traverse api's
+#CFGFLAGS += -DBCM_CB_ABORT_ON_ERR
+################################################################
+#
+# Misc Options
+#
+################################################################
+#CFGFLAGS += -DSOC_MEM_L3_DEFIP_WAR
+
+# Compile out Register/Table descriptive strings to generate a
+# compact image
+#CFGFLAGS +=-DSOC_NO_NAMES
+#CFGFLAGS +=-DSOC_NO_ALIAS
+#CFGFLAGS +=-DSOC_NO_DESC
+
+# Reload/WarmBoot Support
+#
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
+#
+# Need this for validation using SOC scripts; Will move to tcl
+# someday
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
+#
+# Adds a CRC check on scache buffer: Calculate when saving,
+# and verify when loading.
+# When doing ISSU, both source and destination versions should either have
+# this flag enabled or disabled.
+#CFGFLAGS += -DSCACHE_CRC_CHECK
+
+################################################################
+#
+# Enable Easy Reload Support
+#
+################################################################
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT
+# For validation purposes
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT_SW_DUMP
+
+# Software Trunk failover Support
+#
+#CFGFLAGS += -DBCM_TRUNK_FAILOVER_SUPPORT
+
+################################################################
+#
+# Override default VXWORKS thread options to make set
+# VX_UNBREAKABLE flag in task creation.
+#
+################################################################
+#CFGFLAGS += -DVX_THREAD_OPT_UNBREAKABLE
+
+
+################################################################
+#
+# Use default priority for BDE interrupt thread.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_THREAD_PRIO_DEFAULT
+
+################################################################
+#
+# Use cached DMA memory when mapping kernel DMA memory to user
+# mode. Should only be enabled on cache-coherent platforms.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM
+
+################################################################
+#
+# Take the spl lock upon entering an ISR
+#
+################################################################
+#CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ
+
+################################################################
+#
+# Silently ignore NULL pointer free in sal_free API
+# Default behaviour is to assert if a NULL pointer is passed to sal_free
+#
+################################################################
+#CFGFLAGS += -DSAL_FREE_NULL_IGNORE
+
+################################################################
+# Enable SBX MPLS TP support
+################################################################
+#CFGFLAGS += -DBCM_SBX_MPLSTP_SUPPORT
+#CFGFLAGS += -DBCM_SBX_C1_MPLSTP_SUPPORT
+
+################################################################
+# Restrict SBX C2 Fte range to C2's range
+################################################################
+#CFGFLAGS += -DBCM_SBX_C1_C2_INTEROP
+
+################################################################
+# For historical reasons the PCI probe function skips device 12
+# by default to prevent a system hang on certain platforms.
+# Set this value to zero to probe all PCI devices.
+################################################################
+#CFGFLAGS += -DOVERRIDE_PCI_SKIP_DEV_MASK=0
+
+################################################################
+# Override max devices supported by PLI BDE
+################################################################
+#CFGFLAGS += -DPLI_MAX_DEVICES
+
+################################################################
+# Track BCM API calls to avoid deinitialization while calls active
+# This will incur a small time penalty for each BCM API call
+################################################################
+#CFGFLAGS += -DBCM_CONTROL_API_TRACKING
+
+################################################################
+# Override default retry time for detach to wait for executing
+# APIs to complete.
+################################################################
+#CFGFLAGS += -DBCM_DETACH_POLL_INTERVAL_USECS_DEFAULT=100000
+#CFGFLAGS += -DBCM_DETACH_NUM_RETRIES_DEFAULT=3000
+
+################################################################
+# Disable the RX module initialization
+################################################################
+#CFGFLAGS += -DBCM_RX_DISABLE
+
+################################################################
+# Enable TX callback in interrupt thread
+################################################################
+#CFGFLAGS += -DTX_CB_INTR
+
diff --git a/bal_release/3rdparty/bcm-sdk/make/Make.local.arad b/bal_release/3rdparty/bcm-sdk/make/Make.local.arad
new file mode 100755
index 0000000..67c11f5
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make/Make.local.arad
@@ -0,0 +1,565 @@
+# $Id: Make.local.template,v 1.181 Broadcom SDK $
+# $Copyright: Copyright 2012 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+
+# Usage for Make.local.template and Make.local:
+#
+# Make.local.template is checked into the tree, but Make.local is never
+# checked in. Copy Make.local.template to Make.local, then change
+# Make.local to select the desired compilation options (mostly debugging
+# features).
+#
+# Note on CFGFLAGS usage:
+#
+# Because CFGFLAGS may be used with other source preprocessing tools,
+# please limit the values added to CFGFLAGS to -D defines.
+#
+#
+# Table of Contents:
+#
+# Compiler Related Options
+# Boot and Debug Related Options
+# Operational and Policy Options
+# System Management and Multiple CPU Options
+# Selective Device Support (Switches and PHYs)
+# Miscellaneous Options
+#
+
+################################################################
+#
+# Compiler Related Options
+#
+################################################################
+
+# Compiling out #ifdef DEBUG code saves about 1.3% on executable size.
+# It is recommended to leave debug enabled when developing applications.
+#DEBUG_IFDEFS=FALSE
+
+# SAL resource usage tracking #ifdef control
+# DEBUG_IFDEFS should also be TRUE for this switch to take effect.
+#BCM_RESOURCE_USAGE_PROFILE_IFDEFS=TRUE
+
+# Uncomment to build without debug symbols
+#DEBUG_SYMBOLS=FALSE
+
+# Uncomment to add private CFLAGS
+#DEBUG_CFLAGS=
+
+# Uncomment to turn off the optimizer when debugging (recommended)
+#DEBUG_OPTIMIZE=FALSE
+
+# Compiling out assert() saves about 1.1% on executable size,
+# however do so is VERY MUCH discouraged.
+#DEBUG_ASSERTS=FALSE
+
+# Controlling GCC -pedantic flag
+#DEBUG_PEDANTIC=TRUE
+
+# compiler.h overrides, these disable various compiler
+# related features even if the compiler normally supports them
+
+# Disable use of long long for uint64
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_LONGLONG
+
+# Disable use of doubles
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_DOUBLE
+
+# Disable inlining of functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_INLINE
+
+# Disable use of const
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_CONST
+
+# Disable use of static functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_STATIC
+
+# Disable RPC flexible (long) bitmaps.
+# Warning: Disabling this changes the RPC version to 2 and
+# makes systems running this code incompatible with systems
+# running previous versions of BCM RPC code.
+#CFGFLAGS += -DBCM_RPC_PBMP_64
+
+#
+# Define if longs are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+#CFGFLAGS += -DLONGS_ARE_64BITS
+
+#
+# Define if pointers are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+# NOTE: This support works ONLY under conditions where the
+# upper 32 bits for ALL pointers are ZERO.
+#CFGFLAGS += -DPTRS_ARE_64BITS
+
+
+################################################################
+#
+# Boot and Debug Related Options
+#
+################################################################
+
+# Define this to add debug code for RX pool buffer tracking
+#CFGFLAGS += -DBCM_RXP_DEBUG
+
+# Allow debugging of PCI reads/writes (debug +pci)
+#CFGFLAGS += -DSOC_PCI_DEBUG
+
+# Make default debugging settings be 0 (very very quiet)
+#CFGFLAGS += -DNO_DEBUG_OUTPUT_DEFAULT
+
+# Don't use vxMemProbe
+#CFGFLAGS += -DVX_NO_MEM_PROBE
+
+# Allow debugging of Memory Allocation/Deallocation logging
+#CFGFLAGS += -DMEMLOG_SUPPORT
+
+################################################################
+################################################################
+#
+# Operational and Policy Options
+#
+################################################################
+
+# VLAN policy control:
+# NO_DEFAULT_ETHER do not init ether ports into vlan 1
+# NO_DEFAULT_CPU do not init cpu ports into vlan 1
+# NO_DEFAULT_SPI_SUBPORT do not init spi subports into vlan 1
+# NO_AUTO_STACK do not init stack/HG ports into created vlans
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_ETHER
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_CPU
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_SPI_SUBPORT
+#CFGFLAGS += -DBCM_VLAN_NO_AUTO_STACK
+
+# VLAN multicast flood Policy Control:
+# BCM_VLAN_MCAST_FLOOD_ALL Flood all multicast packets to the VLAN
+# BCM_VLAN_MCAST_FLOOD_UNKNOWN Flood unknown multicast packets to the vlan
+# BCM_VLAN_MCAST_FLOOD_NONE Forward multicast packets with known
+# destination addresses to the appropriate ports.
+# All packets destined to an unknown multicast
+# address are dropped.
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_ALL
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_UNKNOWN
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_NONE
+
+#Port Enable/Disable Policy control:
+# PORT_DEFAULT_DISABLE disable ports during switch initialization
+#CFGFLAGS += -DBCM_PORT_DEFAULT_DISABLE
+
+# sal thread priority override (this value used for all threads if defined)
+#CFGFLAGS += -DSAL_THREAD_PRIORITY=255
+
+# disable printing of thread name in messages
+#CFGFLAGS += -DSAL_THREAD_NAME_PRINT_DISABLE
+
+# disable runtime reading of flash config.bcm file (even if !NO_FILEIO)
+#CFGFLAGS += -DSAL_CONFIG_FILE_DISABLE
+
+# disable all Application SAL dependencies
+#NO_SAL_APPL=1
+
+
+# Prevent scheduling in SPL locks when interrupt code is run as a thread.
+# This option should not be necessary if all locks are implemented correctly,
+# however, some locks may still rely on the assumption that scheduling does
+# not occur when interrupts are disabled. If you experience any locking
+# problems in e.g. Linux User Mode, try enabling this option.
+# Please note that turning on this option will reduce performance by an
+# estimated 5 to 10 %.
+#CFGFLAGS += -DSAL_SPL_NO_PREEMPT
+
+# disable mapping of higig cosq when mapping priority to cosq
+# (use identity mapping instead : map prio0->cos0, prio1->cos1, ... , prio7->cos7)
+#CFGFLAGS += -DBCM_COSQ_HIGIG_MAP_DISABLE
+
+# Enable ukernel debugging module
+#CFGFLAGS += -DSOC_UKERNEL_DEBUG
+
+
+################################################################
+#
+# System Management and Multiple CPU Options
+#
+################################################################
+
+# Turn on BCMX inclusion
+# INCLUDE_BCMX for any support
+#INCLUDE_BCMX=1
+
+# Telekinesis suite applications for CPU to CPU communication and discovery
+# CPUDB: Simple CPU data base manager
+# CPUTRANS: CPU to CPU communication mechanisms
+# DISCOVER: Simple discovery; will also include CPUTRANS
+# STKTASK: Stack manager application
+#
+#CFGFLAGS += -DINCLUDE_LIB_CPUDB
+#CFGFLAGS += -DINCLUDE_LIB_CPUTRANS
+#CFGFLAGS += -DINCLUDE_LIB_DISCOVER
+#CFGFLAGS += -DINCLUDE_LIB_STKTASK
+
+# Option for discovery to use the application-data field in routing
+# packets for Board-ID and CPU base flag information.
+#CFGFLAGS += -DDISCOVER_APP_DATA_BOARDID
+
+# Optionally override list of included dispatch modules
+# Note: including RPC automatically includes the Telekinesis suite libs
+# ESW is the enterprise platforms.
+# ROBO includes the managed devices.
+# SBX includes API support for bcm988020QSK24X2
+#DISPATCH_LIST = RPC ESW ASYNC SBX
+
+# Define to have end-to-end flow control enabled on boards that
+# support it
+#CFGFLAGS += -DBCM_BOARD_AUTO_E2E
+
+# Define the following to support per-CPU transmit pointers.
+# This allows the TX setup and send functions to be defined on a
+# per-CPU basis, allowing mixed in-band and out-of-band communication.
+#CFGFLAGS += -DBCM_C2C_TRANSPORT_SWITCHING
+
+# Options for feature list (INCLUDE_XXX)
+# If FEATURE_LIST is defined, it is a list of features to include.
+# See Make.config for the default feature list.
+#
+# Avaliable features:
+#
+# BCMX
+# BCMX_DIAG
+# CHASSIS
+# CUSTOMER
+# DRIVERS
+# EDITLINE
+# I2C
+# L3
+# MEM_SCAN
+# ATPTRANS_SOCKET
+# TELNET
+# TEST
+# ACL
+# RCPU
+# KNET - Linux user mode kernel network support
+# BCM_SAL_PROFILE - make available an API to track SAL usage.
+# CINT - Include the C Interpreter in the diagnostic shell.
+# Please note this cannot be used in Linux kernel mode.
+# C_UNIT - Include the C unit testing framework. If CINT is also included
+# then hooks will be provided for use from it.
+# PHY_SYM_DBG - PHY GUI MDIO read/write support. Socket interface
+# to PHY GUI for Symbolic debugging.
+# APIMODE - call SDK API functions from shell, requires CINT
+# DUNE_UI - dune legacy user interface. For debug only. Tested
+# on linux-user-gto-2.6 only.
+# KBP - include nlm2(11K)/nlm3(12K) KBP support
+# BHH - Include Support for BHH Application (MPLS-TP OAM based on Y.1731)
+# using BTE on select devices.
+# AVS - Include AVS support
+#FEATURE_LIST=ATPTRANS_SOCKET BCMX_DIAG L3 I2C BCMX MEM_SCAN EDITLINE \
+# CUSTOMER TELNET DRIVERS CHASSIS TEST ACL RCPU BCM_SAL_PROFILE CINT \
+# PTP CES FCMAP BOARD KNET REGEX MACSEC APIMODE BFD KBP AVS
+
+FEATURE_LIST= INTR CINT BSAFE ATPTRANS_SOCKET L3 I2C MEM_SCAN EDITLINE TELNET DRIVERS CHASSIS TEST BCM_SAL_PROFILE RCPU DUNE_UI
+
+###############################################################
+# KBP supported devices
+#
+#Enable this for 11K device support
+#KBP_DEVICE = KBP_11K
+#
+#Enable this for 12K device support
+#KBP_DEVICE = KBP_ALG
+#
+###############################################################
+
+################################################################
+#
+# Selective Device Support (Switches and PHYs)
+#
+################################################################
+
+# Multiple Chip Support
+#
+# By default, the driver supports all Strata switch and fabric chips
+# included in this software release. It checks device IDs at runtime
+# to run the correct driver modules.
+#
+# To save space, the driver can be compiled to support just a subset of
+# the chips. To do this, uncomment the line for BCM_PTL_SPT (partial
+# support) and uncomment one line for each chip to support.
+#
+# Note that there are a lot more chips than drivers.
+# For example, the BCM5615 driver is also used for BCM5625 and BCM5645.
+#
+
+BCM_PTL_SPT = 1
+
+#BCM_5675_A0 = 1
+#BCM_56102_A0 = 1
+#BCM_56112_A0 = 1
+#BCM_56304_B0 = 1
+#BCM_56314_A0 = 1
+#BCM_56504_A0 = 1
+#BCM_56504_B0 = 1
+#BCM_56514_A0 = 1
+#BCM_56624_A0 = 1
+#BCM_56624_B0 = 1
+#BCM_56680_A0 = 1
+#BCM_56680_B0 = 1
+#BCM_56580_A0 = 1
+#BCM_56700_A0 = 1
+#BCM_56800_A0 = 1
+#BCM_56218_A0 = 1
+#BCM_56224_A0 = 1
+#BCM_56224_B0 = 1
+#BCM_56725_A0 = 1
+#BCM_56820_A0 = 1
+#BCM_53314_A0 = 1
+#BCM_53324_A0 = 1
+#BCM_56634_A0 = 1
+#BCM_56634_B0 = 1
+#BCM_56524_A0 = 1
+#BCM_56524_B0 = 1
+#BCM_56685_A0 = 1
+#BCM_56685_B0 = 1
+#BCM_56334_A0 = 1
+#BCM_56334_B0 = 1
+#BCM_56840_A0 = 1
+#BCM_56840_B0 = 1
+#BCM_56850_A0 = 1
+#BCM_56142_A0 = 1
+#BCM_56150_A0 = 1
+#BCM_56836_A0 = 1
+#BCM_56640_A0 = 1
+#BCM_56440_A0 = 1
+#BCM_56440_B0 = 1
+#BCM_56450_A0 = 1
+#BCM_56960_A0 = 1
+#BCM_56860_A0 = 1
+
+#BCM_5338_A0 = 1
+#BCM_5380_A0 = 1
+#BCM_5338_B0 = 1
+#BCM_5325_A1 = 1
+
+#BCM_5324_A0 = 1
+#BCM_5396_A0 = 1
+#BCM_5389_A0 = 1
+#BCM_5398_A0 = 1
+#BCM_5324_A1 = 1
+#BCM_53115_A0 = 1
+#BCM_53118_A0 = 1
+#BCM_53280_A0 = 1
+#BCM_53280_B0 = 1
+#BCM_53101_A0 = 1
+#BCM_53125_A0 = 1
+#BCM_53128_A0 = 1
+#BCM_53600_A0 = 1
+#BCM_89500_A0 = 1
+
+#BCM_88030_A0 = 1
+#BCM_QE2000_A0 = 1
+#BCM_BME3200_B0 = 1
+#BCM_BM9600_A0 = 1
+#BCM_88230_A0 = 1
+#BCM_88230_B0 = 1
+#BCM_88230_C0 = 1
+BCM_88640_A0=1
+BCM_88650_A0=1
+BCM_88650_B0=1
+BCM_88660_A0=1
+
+#BCM_TK371X_A0 = 1
+
+# Options for multiple PHY support
+# If BCM_PHY_LIST is defined, it is a list of PHYs to include.
+# The default is to include all of them.
+# If none of them should be included specify BCM_PHY_LIST=EMPTY
+#BCM_PHY_LIST=522X 54XX 5464 5421S 5482 54616 54680 54680E 52681E 54880E 54682 54684 54640 54640E 54880 SERDES SIMUL 8703 8705 8706 8072 8040 8481 8750 8729 84740 84756 84328 EMPTY
+
+# Options for BCM5338 5380
+#CFGFLAGS += -DROBO_OLD
+#ROBO_OLD = 1
+
+# Support for phy simulation
+#CFGFLAGS += -DINCLUDE_PHY_SIMUL
+#CFGFLAGS += -DSIM_ALL_PHYS # All phys use simulation driver
+#CFGFLAGS += -DSIM_CMIC_LINK_STAT # Get link status from CMIC register
+
+# Support for BOARD library
+# if BOARD_LIST is defined, it is a list of Board drivers to include.
+# The default is to include all board drivers appropriate for the devices
+# included in the build. If none of them should be included specify
+# BOARD_LIST=EMPTY.
+#BOARD_LIST=GENERIC
+
+# Support for event logging
+#CFGFLAGS += -DINCLUDE_SHARED_EVLOG
+
+# Support for BCM API port translation
+#CFGFLAGS += -DINCLUDE_BCM_API_XLATE_PORT
+
+# Support for callback error checks and abort in traverse api's
+#CFGFLAGS += -DBCM_CB_ABORT_ON_ERR
+################################################################
+#
+# Misc Options
+#
+################################################################
+#CFGFLAGS += -DSOC_MEM_L3_DEFIP_WAR
+
+# Compile out Register/Table descriptive strings to generate a
+# compact image
+#CFGFLAGS +=-DSOC_NO_NAMES
+#CFGFLAGS +=-DSOC_NO_ALIAS
+#CFGFLAGS +=-DSOC_NO_DESC
+
+# Reload/WarmBoot Support
+#
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
+#
+# Need this for validation using SOC scripts; Will move to tcl
+# someday
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
+#
+# Adds a CRC check on scache buffer: Calculate when saving,
+# and verify when loading.
+# When doing ISSU, both source and destination versions should either have
+# this flag enabled or disabled.
+#CFGFLAGS += -DSCACHE_CRC_CHECK
+
+################################################################
+#
+# Enable Easy Reload Support
+#
+################################################################
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT
+# For validation purposes
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT_SW_DUMP
+
+# Software Trunk failover Support
+#
+#CFGFLAGS += -DBCM_TRUNK_FAILOVER_SUPPORT
+
+################################################################
+#
+# Override default VXWORKS thread options to make set
+# VX_UNBREAKABLE flag in task creation.
+#
+################################################################
+#CFGFLAGS += -DVX_THREAD_OPT_UNBREAKABLE
+
+
+################################################################
+#
+# Use default priority for BDE interrupt thread.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_THREAD_PRIO_DEFAULT
+
+################################################################
+#
+# Use cached DMA memory when mapping kernel DMA memory to user
+# mode. Should only be enabled on cache-coherent platforms.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM
+
+################################################################
+#
+# Take the spl lock upon entering an ISR
+#
+################################################################
+#CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ
+
+################################################################
+#
+# Silently ignore NULL pointer free in sal_free API
+# Default behaviour is to assert if a NULL pointer is passed to sal_free
+#
+################################################################
+#CFGFLAGS += -DSAL_FREE_NULL_IGNORE
+
+################################################################
+# Enable SBX MPLS TP support
+################################################################
+#CFGFLAGS += -DBCM_SBX_MPLSTP_SUPPORT
+#CFGFLAGS += -DBCM_SBX_C1_MPLSTP_SUPPORT
+
+################################################################
+# Restrict SBX C2 Fte range to C2's range
+################################################################
+#CFGFLAGS += -DBCM_SBX_C1_C2_INTEROP
+
+################################################################
+# For historical reasons the PCI probe function skips device 12
+# by default to prevent a system hang on certain platforms.
+# Set this value to zero to probe all PCI devices.
+################################################################
+#CFGFLAGS += -DOVERRIDE_PCI_SKIP_DEV_MASK=0
+
+################################################################
+# Override max devices supported by PLI BDE
+################################################################
+#CFGFLAGS += -DPLI_MAX_DEVICES
+
+################################################################
+# Track BCM API calls to avoid deinitialization while calls active
+# This will incur a small time penalty for each BCM API call
+################################################################
+#CFGFLAGS += -DBCM_CONTROL_API_TRACKING
+
+################################################################
+# Override default retry time for detach to wait for executing
+# APIs to complete.
+################################################################
+#CFGFLAGS += -DBCM_DETACH_POLL_INTERVAL_USECS_DEFAULT=100000
+#CFGFLAGS += -DBCM_DETACH_NUM_RETRIES_DEFAULT=3000
+
+################################################################
+# Disable the RX module initialization
+################################################################
+#CFGFLAGS += -DBCM_RX_DISABLE
+
+################################################################
+# Enable TX callback in interrupt thread
+################################################################
+#CFGFLAGS += -DTX_CB_INTR
+
+override SBX_CHIPS=
diff --git a/bal_release/3rdparty/bcm-sdk/make/Make.local.kt2 b/bal_release/3rdparty/bcm-sdk/make/Make.local.kt2
new file mode 100755
index 0000000..d7876b1
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make/Make.local.kt2
@@ -0,0 +1,562 @@
+# $Id: Make.local.template,v 1.181 Broadcom SDK $
+# $Copyright: Copyright 2012 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+
+# Usage for Make.local.template and Make.local:
+#
+# Make.local.template is checked into the tree, but Make.local is never
+# checked in. Copy Make.local.template to Make.local, then change
+# Make.local to select the desired compilation options (mostly debugging
+# features).
+#
+# Note on CFGFLAGS usage:
+#
+# Because CFGFLAGS may be used with other source preprocessing tools,
+# please limit the values added to CFGFLAGS to -D defines.
+#
+#
+# Table of Contents:
+#
+# Compiler Related Options
+# Boot and Debug Related Options
+# Operational and Policy Options
+# System Management and Multiple CPU Options
+# Selective Device Support (Switches and PHYs)
+# Miscellaneous Options
+#
+
+################################################################
+#
+# Compiler Related Options
+#
+################################################################
+
+# Compiling out #ifdef DEBUG code saves about 1.3% on executable size.
+# It is recommended to leave debug enabled when developing applications.
+#DEBUG_IFDEFS=FALSE
+
+# SAL resource usage tracking #ifdef control
+# DEBUG_IFDEFS should also be TRUE for this switch to take effect.
+#BCM_RESOURCE_USAGE_PROFILE_IFDEFS=TRUE
+
+# Uncomment to build without debug symbols
+#DEBUG_SYMBOLS=FALSE
+
+# Uncomment to add private CFLAGS
+#DEBUG_CFLAGS=
+
+# Uncomment to turn off the optimizer when debugging (recommended)
+#DEBUG_OPTIMIZE=FALSE
+
+# Compiling out assert() saves about 1.1% on executable size,
+# however do so is VERY MUCH discouraged.
+#DEBUG_ASSERTS=FALSE
+
+# Controlling GCC -pedantic flag
+#DEBUG_PEDANTIC=TRUE
+
+# compiler.h overrides, these disable various compiler
+# related features even if the compiler normally supports them
+
+# Disable use of long long for uint64
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_LONGLONG
+
+# Disable use of doubles
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_DOUBLE
+
+# Disable inlining of functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_INLINE
+
+# Disable use of const
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_CONST
+
+# Disable use of static functions
+#CFGFLAGS += -DCOMPILER_OVERRIDE_NO_STATIC
+
+# Disable RPC flexible (long) bitmaps.
+# Warning: Disabling this changes the RPC version to 2 and
+# makes systems running this code incompatible with systems
+# running previous versions of BCM RPC code.
+#CFGFLAGS += -DBCM_RPC_PBMP_64
+
+#
+# Define if longs are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+#CFGFLAGS += -DLONGS_ARE_64BITS
+
+#
+# Define if pointers are 64 bits on your compiler;
+# this is typically true ONLY for 64-bit processors.
+# NOTE: This support works ONLY under conditions where the
+# upper 32 bits for ALL pointers are ZERO.
+#CFGFLAGS += -DPTRS_ARE_64BITS
+
+
+################################################################
+#
+# Boot and Debug Related Options
+#
+################################################################
+
+# Define this to add debug code for RX pool buffer tracking
+#CFGFLAGS += -DBCM_RXP_DEBUG
+
+# Allow debugging of PCI reads/writes (debug +pci)
+#CFGFLAGS += -DSOC_PCI_DEBUG
+
+# Make default debugging settings be 0 (very very quiet)
+#CFGFLAGS += -DNO_DEBUG_OUTPUT_DEFAULT
+
+# Don't use vxMemProbe
+#CFGFLAGS += -DVX_NO_MEM_PROBE
+
+# Allow debugging of Memory Allocation/Deallocation logging
+#CFGFLAGS += -DMEMLOG_SUPPORT
+
+################################################################
+################################################################
+#
+# Operational and Policy Options
+#
+################################################################
+
+# VLAN policy control:
+# NO_DEFAULT_ETHER do not init ether ports into vlan 1
+# NO_DEFAULT_CPU do not init cpu ports into vlan 1
+# NO_DEFAULT_SPI_SUBPORT do not init spi subports into vlan 1
+# NO_AUTO_STACK do not init stack/HG ports into created vlans
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_ETHER
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_CPU
+#CFGFLAGS += -DBCM_VLAN_NO_DEFAULT_SPI_SUBPORT
+#CFGFLAGS += -DBCM_VLAN_NO_AUTO_STACK
+
+# VLAN multicast flood Policy Control:
+# BCM_VLAN_MCAST_FLOOD_ALL Flood all multicast packets to the VLAN
+# BCM_VLAN_MCAST_FLOOD_UNKNOWN Flood unknown multicast packets to the vlan
+# BCM_VLAN_MCAST_FLOOD_NONE Forward multicast packets with known
+# destination addresses to the appropriate ports.
+# All packets destined to an unknown multicast
+# address are dropped.
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_ALL
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_UNKNOWN
+#CFGFLAGS += -DBCM_MCAST_FLOOD_DEFAULT=BCM_VLAN_MCAST_FLOOD_NONE
+
+#Port Enable/Disable Policy control:
+# PORT_DEFAULT_DISABLE disable ports during switch initialization
+#CFGFLAGS += -DBCM_PORT_DEFAULT_DISABLE
+
+# sal thread priority override (this value used for all threads if defined)
+#CFGFLAGS += -DSAL_THREAD_PRIORITY=255
+
+# disable printing of thread name in messages
+#CFGFLAGS += -DSAL_THREAD_NAME_PRINT_DISABLE
+
+# disable runtime reading of flash config.bcm file (even if !NO_FILEIO)
+#CFGFLAGS += -DSAL_CONFIG_FILE_DISABLE
+
+# disable all Application SAL dependencies
+#NO_SAL_APPL=1
+
+
+# Prevent scheduling in SPL locks when interrupt code is run as a thread.
+# This option should not be necessary if all locks are implemented correctly,
+# however, some locks may still rely on the assumption that scheduling does
+# not occur when interrupts are disabled. If you experience any locking
+# problems in e.g. Linux User Mode, try enabling this option.
+# Please note that turning on this option will reduce performance by an
+# estimated 5 to 10 %.
+#CFGFLAGS += -DSAL_SPL_NO_PREEMPT
+
+# disable mapping of higig cosq when mapping priority to cosq
+# (use identity mapping instead : map prio0->cos0, prio1->cos1, ... , prio7->cos7)
+#CFGFLAGS += -DBCM_COSQ_HIGIG_MAP_DISABLE
+
+# Enable ukernel debugging module
+#CFGFLAGS += -DSOC_UKERNEL_DEBUG
+
+
+################################################################
+#
+# System Management and Multiple CPU Options
+#
+################################################################
+
+# Turn on BCMX inclusion
+# INCLUDE_BCMX for any support
+INCLUDE_BCMX=1
+
+# Telekinesis suite applications for CPU to CPU communication and discovery
+# CPUDB: Simple CPU data base manager
+# CPUTRANS: CPU to CPU communication mechanisms
+# DISCOVER: Simple discovery; will also include CPUTRANS
+# STKTASK: Stack manager application
+#
+#CFGFLAGS += -DINCLUDE_LIB_CPUDB
+#CFGFLAGS += -DINCLUDE_LIB_CPUTRANS
+#CFGFLAGS += -DINCLUDE_LIB_DISCOVER
+#CFGFLAGS += -DINCLUDE_LIB_STKTASK
+
+# Option for discovery to use the application-data field in routing
+# packets for Board-ID and CPU base flag information.
+#CFGFLAGS += -DDISCOVER_APP_DATA_BOARDID
+
+# Optionally override list of included dispatch modules
+# Note: including RPC automatically includes the Telekinesis suite libs
+# ESW is the enterprise platforms.
+# ROBO includes the managed devices.
+# SBX includes API support for bcm988020QSK24X2
+#DISPATCH_LIST = RPC ESW ASYNC SBX
+
+# Define to have end-to-end flow control enabled on boards that
+# support it
+#CFGFLAGS += -DBCM_BOARD_AUTO_E2E
+
+# Define the following to support per-CPU transmit pointers.
+# This allows the TX setup and send functions to be defined on a
+# per-CPU basis, allowing mixed in-band and out-of-band communication.
+#CFGFLAGS += -DBCM_C2C_TRANSPORT_SWITCHING
+
+# Options for feature list (INCLUDE_XXX)
+# If FEATURE_LIST is defined, it is a list of features to include.
+# See Make.config for the default feature list.
+#
+# Avaliable features:
+#
+# BCMX
+# BCMX_DIAG
+# CHASSIS
+# CUSTOMER
+# DRIVERS
+# EDITLINE
+# I2C
+# L3
+# MEM_SCAN
+# ATPTRANS_SOCKET
+# TELNET
+# TEST
+# ACL
+# RCPU
+# KNET - Linux user mode kernel network support
+# BCM_SAL_PROFILE - make available an API to track SAL usage.
+# CINT - Include the C Interpreter in the diagnostic shell.
+# Please note this cannot be used in Linux kernel mode.
+# C_UNIT - Include the C unit testing framework. If CINT is also included
+# then hooks will be provided for use from it.
+# PHY_SYM_DBG - PHY GUI MDIO read/write support. Socket interface
+# to PHY GUI for Symbolic debugging.
+# APIMODE - call SDK API functions from shell, requires CINT
+# DUNE_UI - dune legacy user interface. For debug only. Tested
+# on linux-user-gto-2.6 only.
+# KBP - include nlm2(11K)/nlm3(12K) KBP support
+# BHH - Include Support for BHH Application (MPLS-TP OAM based on Y.1731)
+# using BTE on select devices.
+# AVS - Include AVS support
+#FEATURE_LIST=ATPTRANS_SOCKET BCMX_DIAG L3 I2C BCMX MEM_SCAN EDITLINE \
+# CUSTOMER TELNET DRIVERS CHASSIS TEST ACL RCPU BCM_SAL_PROFILE CINT \
+# PTP CES FCMAP BOARD KNET REGEX MACSEC APIMODE BFD KBP AVS
+
+FEATURE_LIST= ATPTRANS_SOCKET PTP CINT L3 I2C BCMX BCMX_DIAG MEM_SCAN EDITLINE BCM_SAL_PROFILE CUSTOMER TEST CHASSIS MSTP RCPU
+
+###############################################################
+# KBP supported devices
+#
+#Enable this for 11K device support
+#KBP_DEVICE = KBP_11K
+#
+#Enable this for 12K device support
+#KBP_DEVICE = KBP_ALG
+#
+###############################################################
+
+################################################################
+#
+# Selective Device Support (Switches and PHYs)
+#
+################################################################
+
+# Multiple Chip Support
+#
+# By default, the driver supports all Strata switch and fabric chips
+# included in this software release. It checks device IDs at runtime
+# to run the correct driver modules.
+#
+# To save space, the driver can be compiled to support just a subset of
+# the chips. To do this, uncomment the line for BCM_PTL_SPT (partial
+# support) and uncomment one line for each chip to support.
+#
+# Note that there are a lot more chips than drivers.
+# For example, the BCM5615 driver is also used for BCM5625 and BCM5645.
+#
+
+BCM_PTL_SPT = 1
+
+#BCM_5675_A0 = 1
+#BCM_56102_A0 = 1
+#BCM_56112_A0 = 1
+#BCM_56304_B0 = 1
+#BCM_56314_A0 = 1
+#BCM_56504_A0 = 1
+#BCM_56504_B0 = 1
+#BCM_56514_A0 = 1
+#BCM_56624_A0 = 1
+#BCM_56624_B0 = 1
+#BCM_56680_A0 = 1
+#BCM_56680_B0 = 1
+#BCM_56580_A0 = 1
+#BCM_56700_A0 = 1
+#BCM_56800_A0 = 1
+#BCM_56218_A0 = 1
+#BCM_56224_A0 = 1
+#BCM_56224_B0 = 1
+#BCM_56725_A0 = 1
+#BCM_56820_A0 = 1
+#BCM_53314_A0 = 1
+#BCM_53324_A0 = 1
+#BCM_56634_A0 = 1
+#BCM_56634_B0 = 1
+#BCM_56524_A0 = 1
+#BCM_56524_B0 = 1
+#BCM_56685_A0 = 1
+#BCM_56685_B0 = 1
+#BCM_56334_A0 = 1
+#BCM_56334_B0 = 1
+#BCM_56840_A0 = 1
+#BCM_56840_B0 = 1
+#BCM_56850_A0 = 1
+#BCM_56142_A0 = 1
+#BCM_56150_A0 = 1
+#BCM_56836_A0 = 1
+#BCM_56640_A0 = 1
+BCM_56440_A0 = 1
+BCM_56440_B0 = 1
+BCM_56450_A0 = 1
+BCM_56450_B0 = 1
+BCM_56450_B1 = 1
+#BCM_56960_A0 = 1
+#BCM_56860_A0 = 1
+
+#BCM_5338_A0 = 1
+#BCM_5380_A0 = 1
+#BCM_5338_B0 = 1
+#BCM_5325_A1 = 1
+
+#BCM_5324_A0 = 1
+#BCM_5396_A0 = 1
+#BCM_5389_A0 = 1
+#BCM_5398_A0 = 1
+#BCM_5324_A1 = 1
+#BCM_53115_A0 = 1
+#BCM_53118_A0 = 1
+#BCM_53280_A0 = 1
+#BCM_53280_B0 = 1
+#BCM_53101_A0 = 1
+#BCM_53125_A0 = 1
+#BCM_53128_A0 = 1
+#BCM_53600_A0 = 1
+#BCM_89500_A0 = 1
+
+#BCM_88030_A0 = 1
+#BCM_QE2000_A0 = 1
+#BCM_BME3200_B0 = 1
+#BCM_BM9600_A0 = 1
+#BCM_88230_A0 = 1
+#BCM_88230_B0 = 1
+#BCM_88230_C0 = 1
+
+#BCM_TK371X_A0 = 1
+
+# Options for multiple PHY support
+# If BCM_PHY_LIST is defined, it is a list of PHYs to include.
+# The default is to include all of them.
+# If none of them should be included specify BCM_PHY_LIST=EMPTY
+#BCM_PHY_LIST=522X 54XX 5464 5421S 5482 54616 54680 54680E 52681E 54880E 54682 54684 54640 54640E 54880 SERDES SIMUL 8703 8705 8706 8072 8040 8481 8750 8729 84740 84756 84328 EMPTY
+
+# Options for BCM5338 5380
+#CFGFLAGS += -DROBO_OLD
+#ROBO_OLD = 1
+
+# Support for phy simulation
+#CFGFLAGS += -DINCLUDE_PHY_SIMUL
+#CFGFLAGS += -DSIM_ALL_PHYS # All phys use simulation driver
+#CFGFLAGS += -DSIM_CMIC_LINK_STAT # Get link status from CMIC register
+
+# Support for BOARD library
+# if BOARD_LIST is defined, it is a list of Board drivers to include.
+# The default is to include all board drivers appropriate for the devices
+# included in the build. If none of them should be included specify
+# BOARD_LIST=EMPTY.
+#BOARD_LIST=GENERIC
+
+# Support for event logging
+#CFGFLAGS += -DINCLUDE_SHARED_EVLOG
+
+# Support for BCM API port translation
+#CFGFLAGS += -DINCLUDE_BCM_API_XLATE_PORT
+
+# Support for callback error checks and abort in traverse api's
+#CFGFLAGS += -DBCM_CB_ABORT_ON_ERR
+################################################################
+#
+# Misc Options
+#
+################################################################
+#CFGFLAGS += -DSOC_MEM_L3_DEFIP_WAR
+
+# Compile out Register/Table descriptive strings to generate a
+# compact image
+#CFGFLAGS +=-DSOC_NO_NAMES
+#CFGFLAGS +=-DSOC_NO_ALIAS
+#CFGFLAGS +=-DSOC_NO_DESC
+
+# Reload/WarmBoot Support
+#
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
+#
+# Need this for validation using SOC scripts; Will move to tcl
+# someday
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
+#
+# Adds a CRC check on scache buffer: Calculate when saving,
+# and verify when loading.
+# When doing ISSU, both source and destination versions should either have
+# this flag enabled or disabled.
+#CFGFLAGS += -DSCACHE_CRC_CHECK
+
+################################################################
+#
+# Enable Easy Reload Support
+#
+################################################################
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT
+# For validation purposes
+#CFGFLAGS += -DBCM_EASY_RELOAD_SUPPORT_SW_DUMP
+
+# Software Trunk failover Support
+#
+#CFGFLAGS += -DBCM_TRUNK_FAILOVER_SUPPORT
+
+################################################################
+#
+# Override default VXWORKS thread options to make set
+# VX_UNBREAKABLE flag in task creation.
+#
+################################################################
+#CFGFLAGS += -DVX_THREAD_OPT_UNBREAKABLE
+
+
+################################################################
+#
+# Use default priority for BDE interrupt thread.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_THREAD_PRIO_DEFAULT
+
+################################################################
+#
+# Use cached DMA memory when mapping kernel DMA memory to user
+# mode. Should only be enabled on cache-coherent platforms.
+#
+################################################################
+#CFGFLAGS += -DSAL_BDE_CACHE_DMA_MEM
+
+################################################################
+#
+# Take the spl lock upon entering an ISR
+#
+################################################################
+#CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ
+
+################################################################
+#
+# Silently ignore NULL pointer free in sal_free API
+# Default behaviour is to assert if a NULL pointer is passed to sal_free
+#
+################################################################
+#CFGFLAGS += -DSAL_FREE_NULL_IGNORE
+
+################################################################
+# Enable SBX MPLS TP support
+################################################################
+#CFGFLAGS += -DBCM_SBX_MPLSTP_SUPPORT
+#CFGFLAGS += -DBCM_SBX_C1_MPLSTP_SUPPORT
+
+################################################################
+# Restrict SBX C2 Fte range to C2's range
+################################################################
+#CFGFLAGS += -DBCM_SBX_C1_C2_INTEROP
+
+################################################################
+# For historical reasons the PCI probe function skips device 12
+# by default to prevent a system hang on certain platforms.
+# Set this value to zero to probe all PCI devices.
+################################################################
+#CFGFLAGS += -DOVERRIDE_PCI_SKIP_DEV_MASK=0
+
+################################################################
+# Override max devices supported by PLI BDE
+################################################################
+#CFGFLAGS += -DPLI_MAX_DEVICES
+
+################################################################
+# Track BCM API calls to avoid deinitialization while calls active
+# This will incur a small time penalty for each BCM API call
+################################################################
+#CFGFLAGS += -DBCM_CONTROL_API_TRACKING
+
+################################################################
+# Override default retry time for detach to wait for executing
+# APIs to complete.
+################################################################
+#CFGFLAGS += -DBCM_DETACH_POLL_INTERVAL_USECS_DEFAULT=100000
+#CFGFLAGS += -DBCM_DETACH_NUM_RETRIES_DEFAULT=3000
+
+################################################################
+# Disable the RX module initialization
+################################################################
+#CFGFLAGS += -DBCM_RX_DISABLE
+
+################################################################
+# Enable TX callback in interrupt thread
+################################################################
+#CFGFLAGS += -DTX_CB_INTR
+
diff --git a/bal_release/3rdparty/bcm-sdk/make/Make.local.qax b/bal_release/3rdparty/bcm-sdk/make/Make.local.qax
new file mode 100644
index 0000000..1a47e1b
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make/Make.local.qax
@@ -0,0 +1,28 @@
+FEATURE_LIST := CINT L3 I2C MEM_SCAN EDITLINE TEST BCM_SAL_PROFILE CHASSIS RCPU ATPTRANS_SOCKET DUNE_UI INTR APIMODE PTP
+
+DEBUG_CFLAGS=-Wdeclaration-after-statement
+
+BCM_PTL_SPT=1
+
+ALL_DPP_CHIPS = 1
+ALL_DFE_CHIPS = 1
+
+# Includes XML library and enables use of "diag pp dump" utility for PP import/export facilities
+DATAIO_SUPPORT = 1
+KERN_VER=3.7.10
+
+CFGFLAGS += -DSTATIC=static
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
+CFGFLAGS += -DBCM_EASY_RELOAD_WB_COMPAT_SUPPORT
+CFGFLAGS += -DBCM_CONTROL_API_TRACKING
+CFGFLAGS += -D__DUNE_LINUX_BCM_CPU_PCIE__
+CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS -DSAL_BDE_32BIT_USER_64BIT_KERNEL
+CFGFLAGS += -D_SIMPLE_MEMORY_ALLOCATION_=0 -DUSE_LINUX_BDE_MMAP=1
+CFGFLAGS += -DSCACHE_CRC_CHECK
+
+CFGFLAGS += -DBROADCOM_SVK
+
+
+VENDOR_LIST=CUSTOMER78 BROADCOM DNX
+
diff --git a/bal_release/3rdparty/bcm-sdk/make/Make.local.qax_sim b/bal_release/3rdparty/bcm-sdk/make/Make.local.qax_sim
new file mode 100644
index 0000000..9f2c402
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make/Make.local.qax_sim
@@ -0,0 +1,33 @@
+#FEATURE_LIST := CINT L3 I2C BCMX BCMX_DIAG MEM_SCAN EDITLINE TEST BCM_SAL_PROFILE CUSTOMER CHASSIS MSTP RCPU ATPTRANS_SOCKET DUNE_UI INTR APIMODE PTP KBP
+
+FEATURE_LIST := CINT L3 I2C MEM_SCAN EDITLINE TEST BCM_SAL_PROFILE CUSTOMER CHASSIS RCPU ATPTRANS_SOCKET DUNE_UI INTR APIMODE PTP
+
+DEBUG_CFLAGS=-Wdeclaration-after-statement
+
+BCM_PTL_SPT=1
+
+ALL_DPP_CHIPS = 1
+ALL_DFE_CHIPS = 1
+
+# Includes XML library and enables use of "diag pp dump" utility for PP import/export facilities
+DATAIO_SUPPORT = 1
+KERN_VER=3.7.10
+
+CFGFLAGS += -DSTATIC=static
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
+CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
+CFGFLAGS += -DBCM_EASY_RELOAD_WB_COMPAT_SUPPORT
+CFGFLAGS += -DBCM_CONTROL_API_TRACKING
+CFGFLAGS += -D__DUNE_LINUX_BCM_CPU_PCIE__
+CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS -DSAL_BDE_32BIT_USER_64BIT_KERNEL
+CFGFLAGS += -D_SIMPLE_MEMORY_ALLOCATION_=0 -DUSE_LINUX_BDE_MMAP=1
+CFGFLAGS += -DSCACHE_CRC_CHECK
+
+CFGFLAGS += -DBROADCOM_SVK
+
+CFGFLAGS += -Wno-format-security -Wno-unused-but-set-variable
+
+#KBP_DEVICE := KBP_ALG
+
+VENDOR_LIST=CUSTOMER78 BROADCOM DNX
+
diff --git a/bal_release/3rdparty/bcm-sdk/make_ing_dir.sh b/bal_release/3rdparty/bcm-sdk/make_ing_dir.sh
new file mode 100755
index 0000000..4f15b82
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/make_ing_dir.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# this shell script build the ING SDK with BAL switch app as a thread
+# Eventually this script will be replaced by a make file
+#set -x
+echo "Preparing ING SDK ${ING_SDK} source tree in ${ING_SDK_DIR}"
+
+# making build directory
+rm -fr ${ING_SDK_DIR}
+mkdir -p ${ING_SDK_DIR}
+cd ${ING_SDK_DIR}/..
+
+#untar the sdk tgz file
+echo "Untaring ${ING_SDK}.tar.gz"
+tar zxf ${ING_SDK_TOP_DIR}/${ING_SDK}.tar.gz
+
+#patch sdk with bal modifications - DO NOT change the patch order
+echo "Patching SDK ${ING_SDK}.tar.gz with patch file ${ING_SDK_PATCH}"
+patch -p0 < ${ING_SDK_TOP_DIR}/${ING_SDK_PATCH}
+
+#link switch app .h and .c files
+echo "Link Switch App Source files"
+cd ${ING_SDK_DIR}
+mkdir -p make/
+
+if [ "${SWITCH}" = "qax" ];
+then
+ ln -s ${ING_SDK_TOP_DIR}/make/Make.local.qax make/Make.local
+else
+ echo " SWITCH = ${SWITCH} is not specified or supported"
+ exit
+fi
+
+echo "Done"
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/arad.soc b/bal_release/3rdparty/bcm-sdk/rc/arad/arad.soc
new file mode 100755
index 0000000..58ff029
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/arad.soc
@@ -0,0 +1,156 @@
+#
+# $Id: arad.soc,v 1.90 Broadcom SDK $
+#
+# $Copyright: Copyright 2016 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+set RCError=off
+debug appl shell warn
+rcload /home/negev/bcm88650_dram_tune.soc
+debug appl shell =
+set RCError=on
+
+debug info
+debug appl rcload warn
+debug appl symtab warn
+debug bcm rx,tx,link,attach warn
+debug soc tests warn
+debug soc rx,phy,schan,reg,socmem,dma,mem,miim,mii,intr,counter,ddr warn
+debug soc common err
+debug sys verinet warn
+
+rcload arad_dram.soc
+
+# Set modid:
+# If diag_chassis is enabled (two line cards), and 'slot' is defined (slot is defined only when
+# working without a management card) - set modid to be 0 for slot 0, and 2 for slot 2
+# Otherwise (single line card, or management card), set modid to be 0 for unit 0, and 2 for unit 2
+# If module_id is set, then set modid to have module_id value
+if $?diag_chassis && $?slot "\
+ local modid $slot" \
+else "\
+ local modid $unit"
+expr $modid==1; if $? "local modid 2"
+
+if $?module_id " \
+ local modid $module_id"
+
+echo "$unit: modid=$modid"
+
+# Set base_modid:
+# Id base_module_id is set, then set base_modid to have base_module_id value.
+# Otherwise, set base_modid to be 0.
+if $?base_module_id " \
+ local base_modid $base_module_id" \
+else " \
+ local base_modid 0"
+
+expr $base_modid > 0
+if $? " \
+ echo '$unit: base_modid=$base_modid'"
+
+# Set nof_devices:
+# If diag_chassis is enabled (mgmt card) - set nof_devices to be 2.
+# Otherwise, set nof_devices to be 1.
+# If n_devices is set, then set nof_devices to have n_devices value.
+if $?diag_chassis " \
+ local nof_devices 2" \
+else "\
+ local nof_devices 1"
+
+if $?n_devices " \
+ local nof_devices $n_devices"
+
+expr $nof_devices > 1
+if $? " \
+ echo '$unit: nof_devices=$nof_devices'"
+
+if $?mng_cpu " \
+ echo '$unit:management card - polling is set on'; \
+ config add polled_irq_mode.BCM88650=1; \
+ config add schan_intr_enable.BCM88650=0; \
+ config add tdma_intr_enable.BCM88650=0; \
+ config add tslam_intr_enable.BCM88650=0; \
+ config add miim_intr_enable.BCM88650=0; \
+ config add polled_irq_mode.BCM88750=1; \
+ config add schan_intr_enable.BCM88750=0; \
+ config add tdma_intr_enable.BCM88750=0; \
+ config add tslam_intr_enable.BCM88750=0; \
+ config add miim_intr_enable.BCM88750=0; "
+
+#default values in a case which these parameters are not exist
+if !$?diag_cosq_disable "\
+ local diag_cosq_disable 0"
+if !$?warmboot "\
+ local warmboot 0"
+if !$?diag_disable "\
+ local diag_disable 0"
+if !$?diag_no_appl_stk "\
+ local diag_no_appl_stk 0"
+if !$?diag_no_itmh_prog_mode "\
+ local diag_no_itmh_prog_mode 0"
+if !$?l2_mode "\
+ local l2_mode 0"
+
+INIT_DNX ModID=$modid BaseModID=$base_modid NofDevices=$nof_devices CosqDisable=$diag_cosq_disable NoAppl=$diag_disable Warmboot=$warmboot NoApplStk=$diag_no_appl_stk NoItmhProgMode=$diag_no_itmh_prog_mode L2Mode=$l2_mode
+
+#LED support section start
+local ledcode '02 0D 67 31 67 1C 02 0E 67 31 67 1C 02 0F 67 31\
+ 67 1C 02 10 67 31 67 1C 86 E0 3A 08 67 37 75 3E\
+ 28 32 00 32 01 B7 97 75 3E 16 E0 CA 05 70 42 77\
+ 3E 67 37 75 3E 77 42 12 A0 F8 15 1A 00 57 32 0E\
+ 87 57 32 0F 87 57' #sdk88650.hex
+
+# Download LED code into LED processor and enable (if applicable).
+if $?feature_led_proc && $?ledcode && !$?simulator \
+ "led prog $ledcode; \
+ led auto on; led start"
+
+# If loading multiple rc.soc, upon loading the last unit, restart
+# all LED processors so any common blinking is in sync.
+# if !"expr $?feature_led_proc && !$?simulator && $unit == $units - 1" \
+# "*:led stop; *:led start"
+#LED support section end
+
+echo "arad.soc: Done."
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/arad_dram.soc b/bal_release/3rdparty/bcm-sdk/rc/arad/arad_dram.soc
new file mode 100755
index 0000000..f50e165
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/arad_dram.soc
@@ -0,0 +1,242 @@
+#
+# $Id: arad_dram.soc,v 1.0 Broadcom SDK $
+#
+# $Copyright: Copyright 2012 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+
+if $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800 "\
+ config add ext_ram_freq=800; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=21; \
+ config add ext_ram_t_rrd=7500; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=8; \
+ config add ext_ram_t_faw=40000; \
+ config add ext_ram_c_cas_latency=11; \
+ config add ddr3_mem_grade=0x111111"
+
+if $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933 "\
+ config add ext_ram_freq=933; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=25; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=9; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=13; \
+ config add ddr3_mem_grade=0x131313"
+
+if $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 "\
+ config add ext_ram_freq=1066; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=29; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=10; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=14; \
+ config add ddr3_mem_grade=0x141414"
+
+if $?dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066 "\
+ config add ext_ram_freq=1066; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=29; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46130; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=260000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=10; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=14; \
+ config add ddr3_mem_grade=0x141414"
+
+if $?dram_type_DDR3_MICRON_MT42J64M16LA_15E_667 "\
+ config add ext_ram_freq=667; \
+ config add ext_ram_rows=8192; \
+ config add ext_ram_jedec=21; \
+ config add ext_ram_t_rrd=7500; \
+ config add ext_ram_t_rc=49500; \
+ config add ext_ram_t_rcd_rd=13500; \
+ config add ext_ram_t_rcd_wr=13500; \
+ config add ext_ram_t_rp=13500; \
+ config add ext_ram_t_rfc=110000; \
+ config add ext_ram_t_ras=36000; \
+ config add ext_ram_c_wr_latency=7; \
+ config add ext_ram_t_faw=45000; \
+ config add ext_ram_c_cas_latency=9; \
+ config add ddr3_mem_grade=0x090909"
+
+if $?dram_type_DDR3_MICRON_MT41J128M16HA_125_800 "\
+ config add ext_ram_freq=800; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=21; \
+ config add ext_ram_t_rrd=7500; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=8; \
+ config add ext_ram_t_faw=40000; \
+ config add ext_ram_c_cas_latency=11; \
+ config add ddr3_mem_grade=0x111111"
+
+if $?dram_type_DDR3_MICRON_MT41J128M16HA_125_933 "\
+ config add ext_ram_freq=933; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=25; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=9; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=13; \
+ config add ddr3_mem_grade=0x131313"
+
+if $?dram_type_DDR3_MICRON_MT41J128M16HA_125_1066 "\
+ config add ext_ram_freq=1066; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=29; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=160000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=10; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=14; \
+ config add ddr3_mem_grade=0x141414"
+
+if $?dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066 "\
+ config add ext_ram_freq=1066; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_jedec=29; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=46090; \
+ config add ext_ram_t_rcd_rd=13090; \
+ config add ext_ram_t_rcd_wr=13090; \
+ config add ext_ram_t_rp=13090; \
+ config add ext_ram_t_rfc=260000; \
+ config add ext_ram_t_ras=33000; \
+ config add ext_ram_c_wr_latency=10; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=14; \
+ config add ddr3_mem_grade=0x141414"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646G_800 "\
+ config add ext_ram_freq=800; \
+ config add ext_ram_rows=8192; \
+ config add ext_ram_jedec=25; \
+ config add ext_ram_t_rrd=7500; \
+ config add ext_ram_t_rc=47910; \
+ config add ext_ram_t_rcd_rd=13910; \
+ config add ext_ram_t_rcd_wr=13910; \
+ config add ext_ram_t_rp=13910; \
+ config add ext_ram_t_rfc=110000; \
+ config add ext_ram_t_ras=34000; \
+ config add ext_ram_c_wr_latency=8; \
+ config add ext_ram_t_faw=40000; \
+ config add ext_ram_c_cas_latency=11; \
+ config add ddr3_mem_grade=0x111111"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646G_933 "\
+ config add ext_ram_freq=933; \
+ config add ext_ram_rows=8192; \
+ config add ext_ram_jedec=25; \
+ config add ext_ram_t_rrd=6000; \
+ config add ext_ram_t_rc=47910; \
+ config add ext_ram_t_rcd_rd=13910; \
+ config add ext_ram_t_rcd_wr=13910; \
+ config add ext_ram_t_rp=13910; \
+ config add ext_ram_t_rfc=110000; \
+ config add ext_ram_t_ras=34000; \
+ config add ext_ram_c_wr_latency=9; \
+ config add ext_ram_t_faw=35000; \
+ config add ext_ram_c_cas_latency=13; \
+ config add ddr3_mem_grade=0x131313"
+
+if $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800 || \
+ $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933 || \
+ $?dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 || \
+ $?dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066 || \
+ $?dram_type_DDR3_MICRON_MT41J128M16HA_125_800 || \
+ $?dram_type_DDR3_MICRON_MT41J128M16HA_125_933 || \
+ $?dram_type_DDR3_MICRON_MT41J128M16HA_125_1066 || \
+ $?dram_type_DDR3_MICRON_MT42J64M16LA_15E_667 || \
+ $?dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646G_933 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646G_800 "\
+ config add ext_ram_type=DDR3; \
+ config add ext_ram_columns=1024; \
+ config add ext_ram_banks=8; \
+ config add ext_ram_ap_bit_pos=10; \
+ config add ext_ram_burst_size=32; \
+ config add ext_ram_t_ref=3900000; \
+ config add ext_ram_t_wr=15000; \
+ config add ext_ram_t_wtr=7500; \
+ config add ext_ram_t_rtp=7500"
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/config.bcm b/bal_release/3rdparty/bcm-sdk/rc/arad/config.bcm
new file mode 100644
index 0000000..9fcb9ba
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/config.bcm
@@ -0,0 +1,1838 @@
+#
+# $Id: config-sand.bcm,v 1.140 2013/09/22 14:29:47 tomerma Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+
+#########################################
+##cfg for BCM88640 (PetraB) and BCM88650 (Arad)
+#########################################
+
+## temporary suppressing unknown soc properties warnings - till adding them unknown to property.h/propgen
+## (need to be the first soc property in the file).
+suppress_unknown_prop_warnings=1
+
+## Multi device system (Negev): 2 devices, fabric mode is FE, mod id is slot id
+## (Top line card is 0, button is 1).
+#diag_chassis=1
+
+## Disable diag init application. Should be used if one wants to run his own
+## application instead of the diag init example
+#diag_disable=1
+
+## Skip cosq configuration in diag_init
+#diag_cosq_disable=1
+
+#########################################
+##cfg for BCM88650 - Arad
+#########################################
+
+### Device configuration ###
+
+## Activate Emulation partial init. Values: 0 - Normal, 1 - Emulation .Default: 0x0.
+diag_emulator_partial_init.BCM88650=0
+
+## General
+# Set the FAP Device mode
+# Options: PP / TM / TDM_OPTIMIZED / TDM_STANDARD
+fap_device_mode.BCM88650=PP
+
+## Credit worth size (Bytes)
+credit_size.BCM88650=1024
+
+## Clock configurations
+# Core clock speed (MHz). Default: 600 MHz
+core_clock_speed_khz.BCM88650=600000
+# System reference clock (MHz). Default: 600 MHz
+system_ref_core_clock_khz.BCM88650=600000
+
+### Network Interface configuration ###
+## Use of the ucode_port_<Local-Port-Id>=<Interface-type>[<Interface-Id>][.<Channel-Id>]
+## Local port range: 0 - 255.
+## Interface types: XAUI/RXAUI/SGMII/ILKN/10GBase-R/XLGE/CGE/CPU
+
+# Map bcm local port to CPU[.channel] interfaces
+ucode_port_180.BCM88650=CPU.0
+
+pon_application_support_enabled_0.BCM88650=TRUE
+pon_application_support_enabled_1.BCM88650=TRUE
+pon_application_support_enabled_2.BCM88650=TRUE
+pon_application_support_enabled_3.BCM88650=TRUE
+#pon_application_support_enabled_4.BCM88650=TRUE
+#pon_application_support_enabled_5.BCM88650=TRUE
+#pon_application_support_enabled_6.BCM88650=TRUE
+#pon_application_support_enabled_7.BCM88650=TRUE
+
+vlan_match_criteria_mode=PON_PCP_ETHERTYPE
+
+#Firmware mode:
+# 0=DEFAULT
+# 1=SFP_OPT_SR4 - optical short range
+# 2=SFP_DAC - direct attach copper
+# 3=XLAUI - 40G XLAUI mode
+# 4=FORCE_OSDFE - force over sample digital feedback equalization
+# 5=FORCE_BRDFE - force baud rate digital feedback equalization
+# 6=SW_CL72 - software cl72 with AN on
+# 7=CL72_WITHOUT_AN - cl72 without AN
+#For Negev2 chassis enable DFE is recommended
+
+serdes_if_type=1024
+
+#serdes_firmware_mode.BCM88650=3
+serdes_firmware_mode_il.BCM88650=4
+serdes_firmware_mode_sfi.BCM88650=0
+
+#
+# Serdes firmware mode for Channelized PON interfaces
+#
+#serdes_firmware_mode_xe0.BCM88650=0
+#serdes_firmware_mode_xe1.BCM88650=0
+#serdes_firmware_mode_xe2.BCM88650=0
+#serdes_firmware_mode_xe3.BCM88650=0
+#serdes_firmware_mode_xe4.BCM88650=0
+#serdes_firmware_mode_xe5.BCM88650=0
+#serdes_firmware_mode_xe6.BCM88650=0
+#serdes_firmware_mode_xe7.BCM88650=0
+#serdes_firmware_mode_xe8.BCM88650=0
+#serdes_firmware_mode_xe9.BCM88650=0
+#serdes_firmware_mode_xe10.BCM88650=0
+#serdes_firmware_mode_xe11.BCM88650=0
+#serdes_firmware_mode_xe12.BCM88650=0
+#serdes_firmware_mode_xe13.BCM88650=0
+#serdes_firmware_mode_xe14.BCM88650=0
+#serdes_firmware_mode_xe15.BCM88650=0
+
+#
+# Serdes firmware mode for NNI interfaces
+#
+serdes_firmware_mode_xe128.BCM88650=2
+serdes_firmware_mode_xe129.BCM88650=2
+serdes_firmware_mode_xe130.BCM88650=2
+serdes_firmware_mode_xe131.BCM88650=2
+serdes_firmware_mode_xe0.BCM88650=2
+serdes_firmware_mode_xe1.BCM88650=2
+serdes_firmware_mode_xe2.BCM88650=2
+serdes_firmware_mode_xe3.BCM88650=2
+
+#
+# Set the speed for the PON-side ports (connected to Pioneer) to 12.5G
+#
+#port_init_speed_xe0.BCM88650=12500
+#port_init_speed_xe1.BCM88650=12500
+#IL# change xe3, xe2 speed to 2.5G and 1G
+port_init_speed_xe2.BCM88650=2500
+port_init_speed_xe3.BCM88650=1000
+#port_init_speed_xe4.BCM88650=12500
+#port_init_speed_xe5.BCM88650=12500
+#port_init_speed_xe6.BCM88650=12500
+#port_init_speed_xe7.BCM88650=12500
+#port_init_speed_xe8.BCM88650=12500
+#port_init_speed_xe9.BCM88650=12500
+#port_init_speed_xe10.BCM88650=12500
+#port_init_speed_xe11.BCM88650=12500
+#port_init_speed_xe12.BCM88650=12500
+#port_init_speed_xe13.BCM88650=12500
+#port_init_speed_xe14.BCM88650=12500
+#port_init_speed_xe15.BCM88650=12500
+
+#
+# Set the number of priorities for the PON-side ports (connected to
+# Pioneer) to '2'.
+#
+port_priorities_xe0.BCM88650=2
+port_priorities_xe1.BCM88650=2
+port_priorities_xe2.BCM88650=2
+port_priorities_xe3.BCM88650=2
+#port_priorities_xe4.BCM88650=2
+#port_priorities_xe5.BCM88650=2
+#port_priorities_xe6.BCM88650=2
+#port_priorities_xe7.BCM88650=2
+#port_priorities_xe8.BCM88650=2
+#port_priorities_xe9.BCM88650=2
+#port_priorities_xe10.BCM88650=2
+#port_priorities_xe11.BCM88650=2
+#port_priorities_xe12.BCM88650=2
+#port_priorities_xe13.BCM88650=2
+#port_priorities_xe14.BCM88650=2
+#port_priorities_xe15.BCM88650=2
+
+#
+# Map bcm local port to Network-Interface[.channel] interfaces
+#
+# PON Interfaces
+#
+
+#
+# Non-channelized PON Interfaces
+#
+# Uncomment the following if using non-channelized PON interfaces with
+# Pioneer.
+#
+#ucode_port_0.BCM88650=10GBase-R8
+#ucode_port_1.BCM88650=10GBase-R9
+#ucode_port_2.BCM88650=10GBase-R10
+#ucode_port_3.BCM88650=10GBase-R11
+#ucode_port_4.BCM88650=10GBase-R12
+#ucode_port_5.BCM88650=10GBase-R13
+#ucode_port_6.BCM88650=10GBase-R14
+#ucode_port_7.BCM88650=10GBase-R15
+
+#
+# Channelized PON Interfaces
+#
+# Define virtual ports for the 10G Channels
+#
+#ucode_port_0.BCM88650=10GBase-R8.0
+#ucode_port_1.BCM88650=10GBase-R9.0
+#ucode_port_2.BCM88650=10GBase-R10.0
+#ucode_port_3.BCM88650=10GBase-R11.0
+#ucode_port_4.BCM88650=10GBase-R12.0
+#ucode_port_5.BCM88650=10GBase-R13.0
+#ucode_port_6.BCM88650=10GBase-R14.0
+#ucode_port_7.BCM88650=10GBase-R15.0
+
+#
+# Define virtual ports for the 1G Channels
+#
+#ucode_port_8.BCM88650=10GBase-R8.1
+#ucode_port_9.BCM88650=10GBase-R9.1
+#ucode_port_10.BCM88650=10GBase-R10.1
+#ucode_port_11.BCM88650=10GBase-R11.1
+#ucode_port_12.BCM88650=10GBase-R12.1
+#ucode_port_13.BCM88650=10GBase-R13.1
+#ucode_port_14.BCM88650=10GBase-R14.1
+#ucode_port_15.BCM88650=10GBase-R15.1
+
+#
+# NNI Interfaces
+#
+ucode_port_128.BCM88650=10GBase-R0
+ucode_port_129.BCM88650=10GBase-R1
+ucode_port_130.BCM88650=10GBase-R2
+ucode_port_131.BCM88650=10GBase-R3
+ucode_port_0.BCM88650=10GBase-R4
+ucode_port_1.BCM88650=10GBase-R5
+ucode_port_2.BCM88650=10GBase-R6
+ucode_port_3.BCM88650=10GBase-R7
+
+#ucode_port_200.BCM88650=CPU.1
+#ucode_port_201.BCM88650=CPU.2
+#ucode_port_202.BCM88650=CPU.3
+#ucode_port_203.BCM88650=CPU.4
+
+#40G
+#ucode_port_1.BCM88650=XLGE0
+#ucode_port_2.BCM88650=XLGE1
+#ucode_port_3.BCM88650=XLGE2
+#ucode_port_4.BCM88650=XLGE3
+#ucode_port_5.BCM88650=XLGE4
+#ucode_port_6.BCM88650=XLGE5
+#ucode_port_7.BCM88650=XLGE6
+
+#ILKN configuration - basic config
+#ucode_port_31.BCM88650=ILKN0
+#ucode_port_32.BCM88650=ILKN1
+#ilkn_num_lanes_0.BCM88650=12
+#ilkn_num_lanes_1.BCM88650=12
+#port_init_speed_il.BCM88650=10312
+
+
+#ILKN per port channel stat
+#ilkn_counters_mode.BCM88650=PACKET_PER_CHANNEL
+
+#ILKN configuration - advanced
+#ilkn_metaframe_sync_period=2048
+# Enable\Disable ILKN status message sent through an out-of-band interface.
+# ilkn_interface_status_oob_ignore.BCM88650=1
+
+##ILKN retransmit
+#ilkn_retransmit_enable_rx.BCM88650=1
+#ilkn_retransmit_enable_tx.BCM88650=1
+#ilkn_retransmit_buffer_size.BCM88650=250
+#ilkn_retransmit_num_requests_resent.BCM88650=15
+#ilkn_retransmit_num_sn_repetitions_tx.BCM88650=1
+#ilkn_retransmit_num_sn_repetitions_rx.BCM88650=1
+#ilkn_retransmit_rx_timeout_words.BCM88650=3800
+#ilkn_retransmit_rx_timeout_sn.BCM88650=250
+#ilkn_retransmit_rx_ignore.BCM88650=80
+#ilkn_retransmit_rx_reset_when_error_enable.BCM88650=1
+#ilkn_retransmit_rx_watchdog.BCM88650=0
+#ilkn_retransmit_rx_reset_when_alligned_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_retry_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_after_disc_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_before_disc_error_enable.BCM88650=0
+#ilkn_retransmit_rx_reset_when_timout_error_enable.BCM88650=0
+#ilkn_retransmit_tx_wait_for_seq_num_change_enable.BCM88650=1
+#ilkn_retransmit_tx_ignore_requests_when_fifo_almost_empty.BCM88650=1
+
+#ucode_port_40.BCM88650=RCY.0
+#ucode_port_41.BCM88650=RCY.1
+#ucode_port_42.BCM88650=RCY.2
+
+## CAUI Configuration
+#ucode_port_41.BCM88650=CGE0
+#ucode_port_42.BCM88650=CGE1
+caui_num_lanes_0.BCM88650=10
+caui_num_lanes_1.BCM88650=10
+#Required for working IXIA 100G port:
+mld_lane_swap_lane20_ce.BCM88650=0
+mld_lane_swap_lane21_ce.BCM88650=1
+mld_lane_swap_lane0_ce.BCM88650=20
+mld_lane_swap_lane1_ce.BCM88650=21
+
+# This configures the lane polarity
+pb_serdes_lane_swap_polarity_tx_phy1.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy3.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy5.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy13.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy14.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy23.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy24.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy27.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy28.BCM88650=0
+
+pb_serdes_lane_swap_polarity_rx_phy1.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy3.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy5.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy13.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy14.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy23.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy24.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy27.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy28.BCM88650=0
+
+xgxs_tx_lane_map_quad0.BCM88650=0x3210
+xgxs_tx_lane_map_quad1.BCM88650=0x3210
+xgxs_tx_lane_map_quad2.BCM88650=0x3210
+xgxs_tx_lane_map_quad3.BCM88650=0x3210
+xgxs_tx_lane_map_quad4.BCM88650=0x3210
+xgxs_tx_lane_map_quad5.BCM88650=0x3210
+xgxs_tx_lane_map_quad6.BCM88650=0x3210
+
+xgxs_rx_lane_map_quad0.BCM88650=0x3210
+xgxs_rx_lane_map_quad1.BCM88650=0x3210
+xgxs_rx_lane_map_quad2.BCM88650=0x3210
+xgxs_rx_lane_map_quad3.BCM88650=0x3210
+xgxs_rx_lane_map_quad4.BCM88650=0x3210
+xgxs_rx_lane_map_quad5.BCM88650=0x3210
+xgxs_rx_lane_map_quad6.BCM88650=0x3210
+
+
+
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88650=1
+
+#Port init mode
+#port_init_duplex=0
+#port_init_adv=0
+#port_init_autoneg=0
+
+
+# This disables serdes initialization
+# phy_null.BCM88650=1
+
+## Number of Internal ports
+# Enable the ERP port. Values: 0 / 1.
+num_erp_tm_ports.BCM88650=1
+# Enable the OLP port. Values: 0 / 1.
+num_olp_tm_ports.BCM88650=1
+# Enable OAMP
+num_oamp_ports.BCM88650=0
+
+## Firmware Load Method
+load_firmware.BCM88650=0x102
+
+### Headers configuration ###
+
+## Use of the tm_port_header_type_<Local-Port-Id>=<Header-type>
+## Default header type is derived from fap_device_mode: If fap_device_mode is
+## PP, default header type is ETH. Otherwise, defualt header type is TM.
+## Header type per port can be overriden.
+## All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/UDH_ETH
+## Injected header types: if PTCH, INJECTED (local Port of type TM) or INJECTED_PP (PP)
+## if PTCH-2, INJECTED_2 (local Port of type TM) or INJECTED_2_PP (PP)
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88650=TM
+
+tm_port_header_type_in_180.BCM88650=INJECTED_2
+tm_port_header_type_out_180.BCM88650=CPU
+
+tm_port_header_type_in_200.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_200.BCM88650=ETH
+tm_port_header_type_in_201.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_201.BCM88650=ETH
+tm_port_header_type_in_202.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_202.BCM88650=ETH
+tm_port_header_type_in_203.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_203.BCM88650=ETH
+
+### Parser Configuration ###
+# Parser has 4 custom macros that are allocated dynamically and
+# configured according to the following features and soc properties:
+# Trill (1 macro) - trill_mode
+# FCoE (2 macros) - bcm886xx_fcoe_switch_mode
+# VxLAN (1 macro) - bcm886xx_vxlan_enable
+# IPv6-Extension-header (2 macros) - bcm886xx_ipv6_ext_hdr_enable
+# UDP (1 macro) - UDP parsing is enabled by default, and can be
+# disabled with soc property custom_feature_udp_parse_disable
+# When disabling UDP parsing VxLAN and 1588oUDP are affected
+
+# Enable IPv6 Extension Header, 0 - disable (default), 1 - enable
+#bcm886xx_ipv6_ext_hdr_enable=1
+
+# Disable UDP parsing, 0 - enable (default), 1 - disable
+#custom_feature_udp_parse_disable=1
+
+#OAMP port
+#tm_port_header_type_out_232.BCM88650=CPU
+
+#MPLS-TP channel types for OAM/BFD - If MPLS-TP used, channel should be specified
+#Available types: mplstp_bfd_control_channel_type
+# mplstp_pw_ach_channel_type
+# mplstp_dlm_channel_type
+# mplstp_ilm_channel_type
+# mplstp_dm_channel_type
+# mplstp_ipv4_channel_type
+# mplstp_cc_channel_type
+# mplstp_cv_channel_type
+# mplstp_on_demand_cv_channel_type
+# mplstp_pwe_oam_channel_type
+# mplstp_ipv6_channel_type
+# mplstp_fault_oam_channel_type
+# mplstp_g8113_channel_type
+#mplstp_g8113_channel_type=0x8902
+
+
+
+# Set the recycling port processing to be raw (static forwarding)
+tm_port_header_type_rcy.BCM88650=RAW
+
+### RCPU
+# Valid CPU local ports on which RCPU packets can be received by slave device.
+#rcpu_rx_pbmp=0xf00000000000000000000000000000000000000000000000001
+
+#tm_port_header_type_514.BCM88650=RAW
+
+## Header extensions
+# Set if an FTMH Out-LIF extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS
+fabric_ftmh_outlif_extension.BCM88650=IF_MC
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88660: ENABLED, FULL_HASH
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY /
+# STANDBY_MC_LB (available only for AradPlus)
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88650=DISABLED
+
+# Set if an OTMH Out-LIF (CUD) Extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS / DOUBLE_TAG (two hop scheduling)
+# Default: NEVER
+# tm_port_otmh_outlif_ext_mode_13.BCM88650=NEVER
+
+# Set if an OTMH Source-System-Port Extension is present.
+# Option: 0/1
+# Default: 0
+# tm_port_otmh_src_ext_enable_13.BCM88650=0
+
+#Trunk hash format, relevant only for AradPlus. Possible values: NORMAL (default) / INVERTED / DUPLICATED.
+#trunk_hash_format=NORMAL
+
+## Stacking Application
+#stacking_enable.BCM88650=1
+#custom_feature_stamp_uc_destination.BCM88650=1
+
+## System RED
+# Set System-Red functionality.
+#system_red_enable.BCM88650=1
+
+# Indicate the size (Bytes) of a first header to skip
+# before the major header at ingress (e.g. Ethernet, ITMH)
+# It can be set per port also
+first_header_size.BCM88650=0
+
+# Indicate the size (Bytes) of the PMF Extension Headers
+# to remove for TM header type ports (expecting ITMH)
+# Set per port
+#post_headers_size_0.BCM88650=4
+
+# Indicate the size (Bytes) of the User-Headers: configurable
+# headers located in the fabric between internal headers and
+# Ethernet. Their values are set by Ingress FP, and can be used
+# by Egress FP or Egress Editor.
+# units: bits. 4 values can be set:
+# 0 - size of the 1st User-Header, for the Egress PMF. 0b / 8b / 16b
+# 1 - size of the 2nd User-Header, for the Egress PMF. 0b / 8b / 16b
+# The sum of these 2 values should be under 16b
+# 2, 3 - size of the 1st/2nd User-Header, for the Egress Editor.
+# 0b / 8b / 16b / 24b / 32b
+# Each of the global User-Header size must be under 32 bits, but not 24 bits.
+# The Egress FP field is always at the MSB of the User-Header
+# Not available for 88650-A0.
+#field_class_id_size_0.BCM88650=8
+#field_class_id_size_1.BCM88650=0
+#field_class_id_size_2.BCM88650=24
+#field_class_id_size_3.BCM88650=0
+
+
+### Trunk - LAG configuration ###
+# Set Set the number of LAGs: 1024, 512, 256, 128 or 64
+number_of_trunks.BCM88650=256
+
+### SYNCE configuration ###
+## Synchronous Ethernet Signal Mode.
+## Options: TWO_DIFF_CLK, TWO_CLK_AND_VALID. Default: TWO_CLK_AND_VALID
+#sync_eth_mode.BCM88650=TWO_CLK_AND_VALID
+
+## Clock Source (single SerDes) lane in the specified NIF port.
+## Usage: sync_eth_clk_to_nif_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_nif_id_clk_0.BCM88650=1
+#sync_eth_clk_to_nif_id_clk_1.BCM88650=1
+
+## Clock Divider for the selected recovered clock. Valid values: 1/2/4. Default: 1.
+## Usage: sync_eth_clk_divider_clk_<clk_number>=<1/2/4>
+#sync_eth_clk_divider_clk_0.BCM88650=1
+#sync_eth_clk_divider_clk_1.BCM88650=1
+
+## Enable the automatic squelch function for the recovered clock. Valid values: 0/1. Default: 0.
+## Usage: sync_eth_clk_squelch_enable_clk_<clk_number>=<0/1>
+#sync_eth_clk_squelch_enable_clk_0.BCM88650=0
+#sync_eth_clk_squelch_enable_clk_1.BCM88650=0
+
+### ELK configuration ###
+## External lookup (TCAM) Device type select, Indicate the External lookup Device type.
+# Value Options: NONE/NL88650. Default: NONE.
+#ext_tcam_dev_type=NL88650
+
+## Set ELK FWD table Size.
+# format: ext_xxx_fwd_table_size.
+# where xxx replaced by FWD options: ip4_uc_rpf/ip4_mc/ip6_uc_rpf/ip6/ip6_mc/trill_uc/trill_mc/mpls/coup_mpls
+# Value Options: (0) - External table disabled, >0: number of entries. Default: 0.
+#ext_ip4_uc_rpf_fwd_table_size=8192
+#ext_ip4_mc_fwd_table_size=8192
+
+## Set ELK IP FWD use NetRoute ALG.
+# Value Options: ALG_LPM_LPM/ALG_LPM_NETROUTE/ALG_LPM_TCAM. Default: ALG_LPM_TCAM.
+#ext_fwd_algorithm_lpm=ALG_LPM_TCAM
+
+## Set ELK interface mode.
+# Change ELK interface configuration to support CAUI port.
+# Value Options: 0/1. 0 - Normal mode, 1 2 CAUI port + ELK mode. Default: 0.
+#ext_interface_mode=0
+
+### Configure MDIO interface
+# External MDIO clock rate divisor . Default: 0x24.
+#rate_ext_mdio_divisor=0x36
+# External MDIO clock rate divisor. Default: 0x1.
+#rate_ext_mdio_dividend=1
+
+### TDM - OTN configuration ###
+#fap_tdm_bypass.BCM88650=0
+
+# Indicate if a Petra-B device is connected to the actual device
+# For TDM/OTN applications,
+# system_is_petra_b_in_system.BCM88650=0
+##Indicate if TDM can arrive throgh primary pipe.
+#Should be 1 for a System with PetraB that connected to fabric over primary pipe.
+fabric_tdm_over_primary_pipe.BCM88650=0
+
+### Fabric configuration ###
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88650=2
+#SFI speed rate
+port_init_speed_sfi.BCM88650=10312
+#CL72
+#port_init_cl72_sfi=0
+fabric_segmentation_enable.BCM88650=1
+
+## Fabric transmission mode
+# Set the Connect mode to the Fabric
+# Options: FE - presence of a Fabric device (single stage) / MULT_STAGE_FE - Multi-stage /
+# SINGLE_FAP - stand-alone device / MESH - mesh / BACK2BACK - 2 devices in Mesh
+fabric_connect_mode.BCM88650=SINGLE_FAP
+#fabric_connect_mode.BCM88650=FE
+
+## Cell format configuration
+# Indicate if the traffic can be sent in dual pipe
+is_dual_mode.BCM88650=0
+# Indicate the format of the cell:
+# A VCS128 cell is used if system_is_vcs_128_in_system or system_is_fe600_in_system is TRUE
+system_is_vcs_128_in_system.BCM88650=0
+system_is_fe600_in_system.BCM88650=0
+
+### WRED ###
+
+# Set the maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88650=0
+
+### OCB (On-Chip Buffer) configuration ###
+# Enable the OCB
+# Enable MODES:
+# 0/FALSE --> OCB_DISABLED --> No OCB use
+# 1/TRUE --> OCB_ENABLED --> Like in Arad-A0/B0. Some packets may use both DRAM and OCB resources
+# ONE_WAY_BYPASS --> Depends on number of present drams (available only for AradPlus):
+# 0 drams: - OCB_ONLY
+# 1 drams: - OCB_ONLY_1_DRAM --> : OCB-only with 1 DRAM for the free pointers
+# 2-8 drams: - OCB_DRAM_SEPARATE --> : OCB and DRAM coexist separately
+# Default: TRUE.
+bcm886xx_ocb_enable.BCM88650=1
+
+# OCB Data Buffer size. Possible values: 128/256/512/1024. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88650=256
+# Repartition between Unicast and Full Multicast buffers.
+# 0: 80% Unicast and 20% Multicast, 1: Unicast-Only
+bcm886xx_ocb_repartition.BCM88650=0
+
+### PDM configuration ###
+# Set the PDM Mode.
+# 0: simple (default), 1: reduced (mandatory for LLFC-VSQ, PFC-VSQ, or ST-VSQ)
+bcm886xx_pdm_mode.BCM88650=0
+
+### Multicast Number of DBuff mode ###
+# Set IQM FMC buffers-replication sizes
+# Options for 88650: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE/ARAD_INIT_FMC_64_REP_128K_DBUFF_MODE
+# Default: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88650=ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+
+### Multicast configuration ###
+# Multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_min.BCM88650=0
+egress_multicast_direct_bitmap_max.BCM88650=4095
+
+### VOQ - Flow configuration ###
+
+# Set the VOQ mapping mode:
+# DIRECT: More than 4K System Ports are supported. System-level WRED is not supported.
+# INDIRECT: similar to Petra-B. Up to 4K System Ports.
+voq_mapping_mode.BCM88650=INDIRECT
+
+# Set the Base Queue to be added to the packet flow-id
+# when the Flow-Id is set explicitely either by the ITMH
+# or by the Destination resolution in the Packet processing
+flow_mapping_queue_base.BCM88650=0
+
+# Set the number of priorities supported at egress per Port
+# Options: 1 / 2 / 8
+port_priorities.BCM88650=8
+
+# Set the shared multicast resource mode: Strict / Discrete
+egress_shared_resources_mode.BCM88650=Strict
+
+# Define outgoing port rate mode in data rate or packet rate.
+# Options: DATA / PACKET
+otm_port_packet_rate.BCM88650=DATA
+
+# Set Port egress recycling scheduler configuration.
+# 0: Strict Priority Scheduler, 1: Round Robin Scheduler
+port_egress_recycling_scheduler_configuration.BCM88650=0
+
+# Set statically the region mode per region id
+# 0: queue connectors only (InterDigitated = FALSE, OddEven = TRUE)
+# 1: queue connectors, SE (InterDigitated =TRUE, OddEven = TRUE)
+# 2: queue connectors, SE (InterDigitated =TRUE, OddEven = FALSE)
+dtm_flow_mapping_mode_region_65.BCM88650=0
+dtm_flow_mapping_mode_region_66.BCM88650=0
+dtm_flow_mapping_mode_region_67.BCM88650=0
+dtm_flow_mapping_mode_region_68.BCM88650=0
+dtm_flow_mapping_mode_region_69.BCM88650=0
+dtm_flow_mapping_mode_region_70.BCM88650=0
+dtm_flow_mapping_mode_region_71.BCM88650=0
+dtm_flow_mapping_mode_region_72.BCM88650=0
+dtm_flow_mapping_mode_region_73.BCM88650=0
+dtm_flow_mapping_mode_region_74.BCM88650=0
+dtm_flow_mapping_mode_region_75.BCM88650=0
+dtm_flow_mapping_mode_region_76.BCM88650=0
+dtm_flow_mapping_mode_region_77.BCM88650=0
+dtm_flow_mapping_mode_region_78.BCM88650=0
+dtm_flow_mapping_mode_region_79.BCM88650=0
+dtm_flow_mapping_mode_region_80.BCM88650=0
+dtm_flow_mapping_mode_region_81.BCM88650=1
+dtm_flow_mapping_mode_region_82.BCM88650=1
+dtm_flow_mapping_mode_region_83.BCM88650=1
+dtm_flow_mapping_mode_region_84.BCM88650=1
+dtm_flow_mapping_mode_region_85.BCM88650=1
+dtm_flow_mapping_mode_region_86.BCM88650=1
+dtm_flow_mapping_mode_region_87.BCM88650=1
+dtm_flow_mapping_mode_region_88.BCM88650=1
+dtm_flow_mapping_mode_region_89.BCM88650=1
+dtm_flow_mapping_mode_region_90.BCM88650=1
+dtm_flow_mapping_mode_region_91.BCM88650=1
+dtm_flow_mapping_mode_region_92.BCM88650=1
+dtm_flow_mapping_mode_region_93.BCM88650=1
+dtm_flow_mapping_mode_region_94.BCM88650=1
+dtm_flow_mapping_mode_region_95.BCM88650=1
+dtm_flow_mapping_mode_region_96.BCM88650=1
+dtm_flow_mapping_mode_region_97.BCM88650=1
+dtm_flow_mapping_mode_region_98.BCM88650=1
+dtm_flow_mapping_mode_region_99.BCM88650=2
+dtm_flow_mapping_mode_region_100.BCM88650=2
+dtm_flow_mapping_mode_region_101.BCM88650=2
+dtm_flow_mapping_mode_region_102.BCM88650=2
+dtm_flow_mapping_mode_region_103.BCM88650=2
+dtm_flow_mapping_mode_region_104.BCM88650=2
+dtm_flow_mapping_mode_region_105.BCM88650=2
+dtm_flow_mapping_mode_region_106.BCM88650=2
+dtm_flow_mapping_mode_region_107.BCM88650=2
+dtm_flow_mapping_mode_region_108.BCM88650=2
+dtm_flow_mapping_mode_region_109.BCM88650=2
+dtm_flow_mapping_mode_region_110.BCM88650=2
+dtm_flow_mapping_mode_region_111.BCM88650=2
+dtm_flow_mapping_mode_region_112.BCM88650=2
+dtm_flow_mapping_mode_region_113.BCM88650=2
+dtm_flow_mapping_mode_region_114.BCM88650=2
+dtm_flow_mapping_mode_region_115.BCM88650=2
+dtm_flow_mapping_mode_region_116.BCM88650=2
+dtm_flow_mapping_mode_region_117.BCM88650=2
+dtm_flow_mapping_mode_region_118.BCM88650=2
+dtm_flow_mapping_mode_region_119.BCM88650=2
+dtm_flow_mapping_mode_region_120.BCM88650=2
+dtm_flow_mapping_mode_region_121.BCM88650=2
+dtm_flow_mapping_mode_region_122.BCM88650=2
+dtm_flow_mapping_mode_region_123.BCM88650=2
+dtm_flow_mapping_mode_region_124.BCM88650=2
+dtm_flow_mapping_mode_region_125.BCM88650=2
+dtm_flow_mapping_mode_region_126.BCM88650=2
+dtm_flow_mapping_mode_region_127.BCM88650=2
+dtm_flow_mapping_mode_region_128.BCM88650=2
+
+#IL# Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88650=2
+dtm_flow_nof_remote_cores_region_2.BCM88650=2
+dtm_flow_nof_remote_cores_region_3.BCM88650=2
+dtm_flow_nof_remote_cores_region_4.BCM88650=2
+dtm_flow_nof_remote_cores_region_5.BCM88650=2
+dtm_flow_nof_remote_cores_region_6.BCM88650=2
+dtm_flow_nof_remote_cores_region_7.BCM88650=2
+dtm_flow_nof_remote_cores_region_8.BCM88650=2
+dtm_flow_nof_remote_cores_region_9.BCM88650=2
+dtm_flow_nof_remote_cores_region_10.BCM88650=2
+dtm_flow_nof_remote_cores_region_11.BCM88650=2
+dtm_flow_nof_remote_cores_region_12.BCM88650=2
+dtm_flow_nof_remote_cores_region_13.BCM88650=2
+dtm_flow_nof_remote_cores_region_14.BCM88650=2
+dtm_flow_nof_remote_cores_region_15.BCM88650=2
+dtm_flow_nof_remote_cores_region_16.BCM88650=2
+dtm_flow_nof_remote_cores_region_17.BCM88650=2
+dtm_flow_nof_remote_cores_region_18.BCM88650=2
+dtm_flow_nof_remote_cores_region_19.BCM88650=2
+dtm_flow_nof_remote_cores_region_20.BCM88650=2
+dtm_flow_nof_remote_cores_region_21.BCM88650=2
+dtm_flow_nof_remote_cores_region_22.BCM88650=2
+dtm_flow_nof_remote_cores_region_23.BCM88650=2
+dtm_flow_nof_remote_cores_region_24.BCM88650=2
+dtm_flow_nof_remote_cores_region_25.BCM88650=2
+dtm_flow_nof_remote_cores_region_26.BCM88650=2
+dtm_flow_nof_remote_cores_region_27.BCM88650=2
+dtm_flow_nof_remote_cores_region_28.BCM88650=2
+dtm_flow_nof_remote_cores_region_29.BCM88650=2
+dtm_flow_nof_remote_cores_region_30.BCM88650=2
+dtm_flow_nof_remote_cores_region_31.BCM88650=2
+dtm_flow_nof_remote_cores_region_32.BCM88650=2
+dtm_flow_nof_remote_cores_region_33.BCM88650=2
+dtm_flow_nof_remote_cores_region_34.BCM88650=2
+dtm_flow_nof_remote_cores_region_35.BCM88650=2
+dtm_flow_nof_remote_cores_region_36.BCM88650=2
+dtm_flow_nof_remote_cores_region_37.BCM88650=2
+dtm_flow_nof_remote_cores_region_38.BCM88650=2
+dtm_flow_nof_remote_cores_region_39.BCM88650=2
+dtm_flow_nof_remote_cores_region_40.BCM88650=2
+dtm_flow_nof_remote_cores_region_41.BCM88650=2
+dtm_flow_nof_remote_cores_region_42.BCM88650=2
+dtm_flow_nof_remote_cores_region_43.BCM88650=2
+dtm_flow_nof_remote_cores_region_44.BCM88650=2
+dtm_flow_nof_remote_cores_region_45.BCM88650=2
+dtm_flow_nof_remote_cores_region_46.BCM88650=2
+dtm_flow_nof_remote_cores_region_47.BCM88650=2
+dtm_flow_nof_remote_cores_region_48.BCM88650=2
+dtm_flow_nof_remote_cores_region_49.BCM88650=2
+dtm_flow_nof_remote_cores_region_50.BCM88650=2
+dtm_flow_nof_remote_cores_region_51.BCM88650=2
+dtm_flow_nof_remote_cores_region_52.BCM88650=2
+dtm_flow_nof_remote_cores_region_53.BCM88650=2
+dtm_flow_nof_remote_cores_region_54.BCM88650=2
+dtm_flow_nof_remote_cores_region_55.BCM88650=2
+dtm_flow_nof_remote_cores_region_56.BCM88650=2
+dtm_flow_nof_remote_cores_region_57.BCM88650=2
+dtm_flow_nof_remote_cores_region_58.BCM88650=2
+dtm_flow_nof_remote_cores_region_59.BCM88650=2
+dtm_flow_nof_remote_cores_region_60.BCM88650=2
+
+dtm_flow_nof_remote_cores_region_core0_2.BCM88650=1
+dtm_flow_nof_remote_cores_region_core0_3.BCM88650=1
+
+### Flow Control configuration ###
+# Set the Flow control type per Port.
+# Options: LL (Link-level) / CB2 (Class-Based - 2 classes) /
+# CB8 (Class-Based - 8 classes)
+# flow_control_type.BCM88650=LL
+
+## Out-Of-Band Flow control configuration
+#spn_FC_OOB_TYPE, spn_FC_OOB_MODE, spn_FC_OOB_CALENDER_LENGTH, spn_FC_OOB_CALENDER_REP_COUNT,
+
+## Set voltage mode for oob interfaces
+#HSTL_1.5V
+#3.3V
+#HSTL_1.5V_VDDO_DIV_2
+ext_voltage_mode_oob=3.3V
+
+## Inband Interlaken configuration
+# spn_FC_INBAND_INTLKN_MODE, spn_FC_INBAND_INTLKN_CALENDER_LENGTH, spn_FC_INBAND_INTLKN_CALENDER_REP_COUNT
+# spn_FC_INBAND_INTLKN_CALENDER_LLFC_MODE, spn_FC_INBAND_INTLKN_LLFC_MUB_ENABLE_MASK
+
+### Meter engine configuration ###
+
+# Specify meter operation mode
+# 32 - Two meters per packet (32k total)
+# 64 - One meter per packet (64k total)
+# Options: 0, 32, 64
+policer_ingress_count.BCM88650=32
+
+# For meters in double 32k mode, determine the sharing mode
+# Options:
+# 0 - NONE (only for 64k mode)
+# 1 - SERIAL (only for 32k mode)
+# 2 - PARALLEL (only for 32k mode)
+policer_ingress_sharing_mode.BCM88650=1
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine the mapping
+# Options: BEST, WORST
+# policer_result_parallel_color_map.BCM88650=WORST
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine how the buckets are changed
+# Options: CONSTANT, TRANSPARENT, DEFERRED
+# policer_result_parallel_bucket_update.BCM88650=CONSTANT
+
+# Applies only to Arad+ (88660)
+# Set the Ethernet policer to work in color blind mode
+# rate_color_blind.BCM88650=1
+
+# L2 learn limit mode
+# Options: VLAN, VLAN_PORT, TUNNEL or the numeric equivalent 0-2.
+# Default: VLAN
+# l2_learn_limit_mode = VLAN_PORT
+
+# Applies only to Arad+ (88660)
+# Determines the L2 learn limit ranges when l2_learn_limit_mode is set to VLAN_PORT
+# Two range bases can be selected, each of 16K size.
+# Options: 0, 16K, 32K, 48K.
+# Default: 0 & 16K
+# l2_learn_lif_range_base_0 = 0
+# l2_learn_lif_range_base_1 = 16K
+
+### Counter engine configuration ###
+
+# Set the Counter source
+# Options: INGRESS_FIELD / INGRESS_VOQ / INGRESS_VSQ
+# INGRESS_CNM / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM (per queue) / EGRESS_TM_PORT (per port)
+# EGRESS_RECEIVE_VSI / EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM (per queue) / EGRESS_RECEIVE_TM_PORT (per port)
+# INGRESS_OAM / EGRESS_OAM
+# 2 Counter-Pointers can be set (with _0 and _1) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT
+# Range extension can be set (with _LSB and _MSB) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT /EGRESS_RECEIVE_VSI /
+# EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM / EGRESS_RECEIVE_TM_PORT
+counter_engine_source_0.BCM88650=INGRESS_FIELD
+counter_engine_source_1.BCM88650=INGRESS_FIELD_1
+counter_engine_source_2.BCM88650=INGRESS_VOQ
+###
+### DML
+###
+### For DML applications, counter engine 3 is used for VOQ
+### counters. This in combination with configuring the engines used for
+### VOQs for FWD_DROP allows for counters for 32K VOQs.
+###
+#counter_engine_source_3.BCM88650=EGRESS_FIELD
+counter_engine_source_3.BCM88650=INGRESS_VOQ
+
+# Configure the statistic interface egress source
+# Options: EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT (the default is TM)
+# valid just when there is no conflict with the other counter engines
+#counter_engine_source_stat0.BCM88650=EGRESS_TM
+#counter_engine_source_stat1.BCM88650=EGRESS_TM
+
+
+# Set the Counter engine resolution
+# SIMPLE_COLOR = green, not green
+# SIMPLE_COLOR_FWD = fwd green, fwd not green (BCM88660_A0 only)
+# SIMPLE_COLOR_DROP = drop green, drop not green (BCM88660_A0 only)
+# FWD_DROP = forwarded, dropped
+# GREEN_NOT_GREEN = fwd grn, drop grn, fwd not grn, drop not grn
+# FULL_COLOR = fwd grn, drop grn, fwd not grn, drop yel, drop red
+# ALL = received
+# FWD = forwarded, DROP = droped (not supported by ARAD_A0)
+# CONFIGURABLE = defined by counter_engine_map_ SOC properties (BCM88660_A0 only)
+counter_engine_statistics_0.BCM88650=FULL_COLOR
+counter_engine_statistics_1.BCM88650=FULL_COLOR
+###
+### DML
+###
+### For DML applications, counter engine 3 is used for VOQ
+### counters. This in combination with configuring the engines used for
+### VOQs for FWD_DROP allows for counters for 32K VOQs.
+###
+#counter_engine_statistics_2.BCM88650=FULL_COLOR
+#counter_engine_statistics_3.BCM88650=FULL_COLOR
+counter_engine_statistics_2.BCM88650=FWD_DROP
+counter_engine_statistics_3.BCM88650=FWD_DROP
+
+# Set the Counter format
+# Options: PACKETS_AND_BYTES / PACKETS / BYTES
+# / MAX_QUEUE_SIZE / PACKETS_AND_PACKETS(supported just in FWD_DROP statistic in BCM88660_A0)
+# If not PACKETS_AND_BYTES or PACKETS_AND_PACKETS, the HW Counter width is 59 bits, thus
+# no background SW operation is performed
+counter_engine_format_0.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_1.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_2.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_3.BCM88650=PACKETS_AND_BYTES
+
+# #enable/disable counter processor background thread (default:1-enable)
+# counter_engine_sampling_interval=1
+
+### Configurable mode configuration (BCM88660_A0 only)###
+# counter_engine_statistics_0.BCM88660_A0=CONFIGURABLE
+# counter_engine_map_enable_0.BCM88660_A0=1
+# counter_engine_map_size_0.BCM88660_A0=4
+# counter_engine_map_fwd_green_offset_0.BCM88660_A0=0
+# counter_engine_map_fwd_yellow_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_red_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_black_offset_0.BCM88660_A0=2
+# counter_engine_map_drop_green_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_yellow_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_red_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_black_offset_0.BCM88660_A0=3
+
+### Statistic-Report configuration ###
+# Enable the Statistic-Interface configuration
+# stat_if_enable_<port> - not supported by ARAD_A0
+# stat_if_enable.BCM88650=1
+
+# ## Statistic-Report Properties
+# # Set the Statistic-Report mode
+# # Options: BILLING / BILLING_QUEUE_NUMBER (not supported by ARAD_A0)/ QSIZE
+# stat_if_report_mode.BCM88650=QSIZE
+# #Indicate if idle reports must be sent
+# #when the Statistic-report rate is too low
+# stat_if_idle_reports_present.BCM88650=0
+# # Indicate if the reported packet size is the original packet size
+# stat_if_report_original_pkt_size.BCM88650=1
+# #If set then a single ingress-billing report will be generated
+# #for the whole set of the multicast copies
+# stat_if_report_multicast_single_copy=1
+# ## Statistic Packet configurations
+# # Set the Statistic Packet size (Bytes)
+# # Valid valued: 65B/126B/248B/492B (Queue-Size), 64B/128B/256B/512B/1024B (Billing)
+# stat_if_pkt_size=64B
+#
+# ## Scrubber configuration
+# # Set the range of VOQs to scrub. Range: 0 - 96K-1.
+# stat_if_scrubber_queue_min.BCM88650=0
+# stat_if_scrubber_queue_max.BCM88650=0
+#
+# # Set the scrubber rate range
+# # If set to 0 (default), the scrubber is disabled. Units: nanoseconds
+# stat_if_scrubber_rate_min.BCM88650=0
+# stat_if_scrubber_rate_max.BCM88650=0
+#
+# # Set the thresholds (thresh_id 0 - 15) defining
+# # occupancy range per resource type:
+# # DRAM Buffers, Buffer descriptors, Buffer descriptors buffers
+# stat_if_scrubber_bdb_th.BCM88650=0
+# stat_if_scrubber_buffer_descr_th.BCM88650=0
+# stat_if_uc_dram_buffer_descr_th.BCM88650=0
+#
+# #Relective report for queue size mode - not supported by ARAD_A0
+# #Reports will be created for queue num range (stat_if_selective_report_queue_min -stat_if_selective_report_queue_max)
+# #Default - all range
+# stat_if_selective_report_queue_min.BCM88650_B0=0
+# stat_if_selective_report_queue_max.BCM88650_B0=98303
+
+### Transaction - DMA configuration ###
+# Time to wait for SCHAN channel response (from CMIC). Units: microseconds.
+
+# TODO
+### Counter threads ###
+# spn_BCM_STAT_PBMP, spn_BCM_STAT_INTERVAL, spn_BCM_STAT_FLAGS
+
+### Interrupts ###
+## Set interrupts global parameters.
+# Options: 1 - Polling interrupt mode, 0 - Line/MSI interrupt mode. Default: 1.
+polled_irq_mode.BCM88650=0
+# Set the delay in microsecond between the polling, relevant only to Polling mode. Default: 0x0.
+polled_irq_delay.BCM88650=50000
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling, relevant only to Polling completion mode.
+# SCHAN:
+#schan_intr_enable.0=1
+schan_timeout_usec.BCM88650=300000
+# TDMA
+tdma_intr_enable.BCM88650=1
+tdma_timeout_usec.BCM88650=80000000
+# TSLAM
+tslam_intr_enable.BCM88650=1
+tslam_timeout_usec.BCM88650=80000000
+# MIIM
+#miim_intr_enable.0=1
+miim_timeout_usec.0=300000
+
+### DRAM configuration ###
+
+# DRAM buffer (Dbuff) size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88650=1024
+
+# Number of external DRAMs.
+# Allowed values for 88650: 0/2/3/4/6/8. A value of 0 disables the DRAM.
+# Allowed values for 88660: 0/1/2/3/4/6/8. A value of 0 disables the DRAM.
+# A value of 1 is permitted only in ONE WAY BYPASS ocb mode.
+ext_ram_present.BCM88650=8
+
+### Dram Tuning (Shmoo)
+# 2 = Use Dram saved config Parameters, if no Parameters Perform Shmoo on init. Default option.
+# 1 = Perform Shmoo on init.
+# 0 = Use Dram saved config Parameters, if no Parameters do nothing.
+ddr3_auto_tune.BCM88650=2
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Defult: 1.
+# bist_enable_dram.BCM88650=1
+
+### Example for Dram Saved config Parameters.
+## This example is for ci=14 (Dram=7).
+#ddr3_tune_addrc_ci14=0x000000ae
+#ddr3_tune_wr_dq_wl1_ci14=0x92929292,0x92929292,0x92929292,0x92929292
+#ddr3_tune_wr_dq_wl0_ci14=0x93939393,0x93939393,0x92929292,0x92929292
+#ddr3_tune_wr_dq_ci14=0x80808080
+#ddr3_tune_vref_ci14=0x000007df
+#ddr3_tune_rd_dqs_ci14=0x96969191,0x90909191
+#ddr3_tune_rd_dq_wl1_rn_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rn_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_dq_wl1_rp_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rp_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_en_ci14=0x009d9e9d,0x00a2a3a1
+#ddr3_tune_rd_data_dly_ci14=0x00000505
+ ddr3_tune_rd_dq_wl1_rp_ci8.0=0x82828282,0x82828282,0x8b8b8b8b,0x8b8b8b8b
+ ddr3_tune_wr_dq_wl0_ci4.0=0x93939393,0x93939393,0x92929292,0x92929292
+ ddr3_tune_vref_ci10.0=0x0000079e
+ ddr3_tune_wr_dq_wl1_ci2.0=0x92929292,0x92929292,0x92929292,0x92929292
+ ddr3_tune_wr_dq_ci6.0=0x80808080
+ ddr3_tune_rd_dq_wl0_rn_ci6.0=0x80808080,0x80808080,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_rd_dq_wl1_rp_ci10.0=0x83838383,0x83838383,0x84848484,0x84848484
+ ddr3_tune_rd_dqs_ci8.0=0x96969797,0x94949090
+ ddr3_tune_vref_ci6.0=0x0000079e
+ ddr3_tune_rd_dq_wl0_rp_ci14.0=0x83838383,0x83838383,0x83838383,0x83838383
+ ddr3_tune_rd_en_ci10.0=0x009fa09f,0x009a9c99
+ ddr3_tune_rd_data_dly_ci4.0=0x00000404
+ ddr3_tune_addrc_ci8.0=0x000000ab
+ ddr3_tune_rd_dq_wl0_rp_ci2.0=0x81818181,0x81818181,0x84848484,0x84848484
+ ddr3_tune_rd_dqs_ci10.0=0x96969090,0x90909090
+ ddr3_tune_rd_en_ci2.0=0x009c9c9c,0x009a9c98
+ ddr3_tune_wr_dq_wl0_ci12.0=0x93939393,0x93939393,0x93939393,0x93939393
+ ddr3_tune_rd_dq_wl1_rn_ci4.0=0x84848484,0x84848484,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_addrc_ci10.0=0x000000af
+ ddr3_tune_wr_dq_wl0_ci6.0=0x90909090,0x90909090,0x93939393,0x93939393
+ ddr3_tune_vref_ci12.0=0x0000079e
+ ddr3_tune_rd_dq_wl0_rn_ci10.0=0x83838383,0x83838383,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_wr_dq_wl1_ci4.0=0x93939393,0x93939393,0x94949494,0x94949494
+ ddr3_tune_wr_dq_ci8.0=0x80808080
+ ddr3_tune_rd_dq_wl1_rp_ci0.0=0x83838383,0x83838383,0x84848484,0x84848484
+ ddr3_tune_wr_dq_wl1_ci10.0=0x95959595,0x95959595,0x95959595,0x95959595
+ ddr3_tune_rd_dq_wl0_rn_ci8.0=0x8a8a8a8a,0x8a8a8a8a,0x89898989,0x89898989
+ ddr3_tune_rd_dq_wl1_rp_ci12.0=0x84848484,0x84848484,0x84848484,0x84848484
+ ddr3_tune_wr_dq_ci10.0=0x80808080
+ ddr3_tune_vref_ci8.0=0x000007df
+ ddr3_tune_rd_en_ci12.0=0x009c9c9d,0x00a0a29f
+ ddr3_tune_rd_data_dly_ci6.0=0x00000505
+ ddr3_tune_rd_dq_wl0_rp_ci4.0=0x83838383,0x83838383,0x81818181,0x81818181
+ ddr3_tune_rd_dqs_ci12.0=0x91919292,0x92929393
+ ddr3_tune_rd_dqs_ci0.0=0x96969292,0x91919191
+ ddr3_tune_rd_en_ci4.0=0x00979798,0x009c9e9a
+ ddr3_tune_rd_data_dly_ci10.0=0x00000505
+ ddr3_tune_addrc_ci0.0=0x000000ad
+ ddr3_tune_wr_dq_wl0_ci14.0=0x94949494,0x94949494,0x93939393,0x93939393
+ ddr3_tune_rd_dq_wl1_rn_ci6.0=0x89898989,0x89898989,0x8b8b8b8b,0x8b8b8b8b
+ ddr3_tune_addrc_ci12.0=0x000000b3
+ ddr3_tune_wr_dq_wl0_ci8.0=0x93939393,0x93939393,0x93939393,0x93939393
+ ddr3_tune_vref_ci14.0=0x0000079e
+ ddr3_tune_rd_dq_wl0_rn_ci12.0=0x83838383,0x83838383,0x83838383,0x83838383
+ ddr3_tune_wr_dq_wl1_ci6.0=0x94949494,0x94949494,0x94949494,0x94949494
+ ddr3_tune_rd_dq_wl1_rp_ci2.0=0x83838383,0x83838383,0x89898989,0x89898989
+ ddr3_tune_wr_dq_wl1_ci12.0=0x94949494,0x94949494,0x94949494,0x94949494
+ ddr3_tune_rd_dq_wl1_rp_ci14.0=0x81818181,0x81818181,0x83838383,0x83838383
+ ddr3_tune_wr_dq_ci12.0=0x80808080
+ ddr3_tune_wr_dq_ci0.0=0x80808080
+ ddr3_tune_rd_en_ci14.0=0x009f9f9f,0x00a2a4a1
+ ddr3_tune_rd_dq_wl0_rn_ci0.0=0x83838383,0x83838383,0x89898989,0x89898989
+ ddr3_tune_rd_data_dly_ci8.0=0x00000505
+ ddr3_tune_rd_dq_wl0_rp_ci6.0=0x80808080,0x80808080,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_rd_dqs_ci14.0=0x91919292,0x90909090
+ ddr3_tune_rd_dqs_ci2.0=0x90908f8f,0x95959090
+ ddr3_tune_rd_en_ci6.0=0x009c9d9b,0x009ea09d
+ ddr3_tune_rd_data_dly_ci12.0=0x00000505
+ ddr3_tune_vref_ci0.0=0x000007df
+ ddr3_tune_addrc_ci2.0=0x000000ae
+ ddr3_tune_rd_dq_wl1_rn_ci8.0=0x82828282,0x82828282,0x8b8b8b8b,0x8b8b8b8b
+ ddr3_tune_addrc_ci14.0=0x000000b0
+ ddr3_tune_rd_dq_wl1_rn_ci10.0=0x83838383,0x83838383,0x84848484,0x84848484
+ ddr3_tune_rd_dq_wl0_rn_ci14.0=0x83838383,0x83838383,0x83838383,0x83838383
+ ddr3_tune_wr_dq_wl1_ci8.0=0x93939393,0x93939393,0x94949494,0x94949494
+ ddr3_tune_rd_dq_wl1_rp_ci4.0=0x84848484,0x84848484,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_wr_dq_wl1_ci14.0=0x95959595,0x95959595,0x95959595,0x95959595
+ ddr3_tune_wr_dq_wl0_ci0.0=0x93939393,0x93939393,0x92929292,0x92929292
+ ddr3_tune_wr_dq_ci14.0=0x80808080
+ ddr3_tune_wr_dq_ci2.0=0x80808080
+ ddr3_tune_rd_dq_wl0_rn_ci2.0=0x81818181,0x81818181,0x84848484,0x84848484
+ ddr3_tune_rd_dq_wl0_rp_ci8.0=0x8a8a8a8a,0x8a8a8a8a,0x89898989,0x89898989
+ ddr3_tune_rd_dqs_ci4.0=0x8f8f9090,0x95959191
+ ddr3_tune_rd_en_ci8.0=0x00a0a0a0,0x009b9e99
+ ddr3_tune_rd_data_dly_ci14.0=0x00000505
+ ddr3_tune_vref_ci2.0=0x000007df
+ ddr3_tune_rd_dq_wl0_rp_ci10.0=0x83838383,0x83838383,0x8c8c8c8c,0x8c8c8c8c
+ ddr3_tune_rd_data_dly_ci0.0=0x00000505
+ ddr3_tune_addrc_ci4.0=0x000000af
+ ddr3_tune_rd_dq_wl1_rn_ci12.0=0x84848484,0x84848484,0x84848484,0x84848484
+ ddr3_tune_rd_dq_wl1_rn_ci0.0=0x83838383,0x83838383,0x84848484,0x84848484
+ ddr3_tune_rd_dq_wl1_rp_ci6.0=0x89898989,0x89898989,0x8b8b8b8b,0x8b8b8b8b
+ ddr3_tune_wr_dq_wl0_ci2.0=0x92929292,0x92929292,0x92929292,0x92929292
+ ddr3_tune_wr_dq_wl1_ci0.0=0x92929292,0x92929292,0x92929292,0x92929292
+ ddr3_tune_wr_dq_ci4.0=0x80808080
+ ddr3_tune_rd_dq_wl0_rn_ci4.0=0x83838383,0x83838383,0x81818181,0x81818181
+ ddr3_tune_rd_dqs_ci6.0=0x94948f8f,0x93939393
+ ddr3_tune_vref_ci4.0=0x0000079e
+ ddr3_tune_rd_dq_wl0_rp_ci12.0=0x83838383,0x83838383,0x83838383,0x83838383
+ ddr3_tune_rd_data_dly_ci2.0=0x00000404
+ ddr3_tune_addrc_ci6.0=0x000000ab
+ ddr3_tune_rd_dq_wl0_rp_ci0.0=0x83838383,0x83838383,0x89898989,0x89898989
+ ddr3_tune_rd_dq_wl1_rn_ci14.0=0x81818181,0x81818181,0x83838383,0x83838383
+ ddr3_tune_rd_en_ci0.0=0x009fa09f,0x00999b98
+ ddr3_tune_wr_dq_wl0_ci10.0=0x94949494,0x94949494,0x96969696,0x96969696
+ ddr3_tune_rd_dq_wl1_rn_ci2.0=0x83838383,0x83838383,0x89898989,0x89898989
+
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram related parameteres per type.
+# Dram Type for Arad:
+dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800=1
+#dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_933=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_800=1
+#dram_type_DDR3_MICRON_MT42J64M16LA_15E_667=1
+#dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_933=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_800=1
+
+### Setting dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 Parameters as Default:
+## All other dram types parameter resides in arad.soc. choosing another Dram Type will override the following parameters.
+ext_ram_t_rrd=6000
+ext_ram_columns=1024
+ext_ram_banks=8
+ext_ram_ap_bit_pos=10
+ext_ram_burst_size=32
+ext_ram_t_ref=3900000
+ext_ram_t_wr=15000
+ext_ram_t_wtr=7500
+ext_ram_t_rtp=7500
+ext_ram_freq=1066
+ext_ram_rows=16384
+ext_ram_jedec=29
+ext_ram_t_rc=46090
+ext_ram_t_rcd_rd=13090
+ext_ram_t_rcd_wr=13090
+ext_ram_t_rp=13090
+ext_ram_t_rfc=160000
+ext_ram_t_ras=33000
+ext_ram_c_wr_latency=10
+ext_ram_t_faw=35000
+ext_ram_c_cas_latency=14
+ddr3_mem_grade=0x141414
+
+# DRAM pre-configurations according to config variables which defines
+# Dram Type. supports only DDR3:
+ext_ram_type.BCM88650=DDR3
+
+# Total Dram Size (MBytes)
+# For 8 drams interfaces, 2 channel each, Each channel 2Gbit Dram. the total DRAM size is 32GBits=4000MBytes.
+ext_ram_total_size.BCM88650=4000
+
+# Total buffer size allocated for User buffer. Units: Mbytes. Default: '0x0'.
+# Supported suffix:
+# dram - the buffer size will be subtracted from the DRAM size available for packet memory.
+#user_buffer_size=0
+#user_buffer_size_dram=50
+
+# DRAM ClamShell (interface swap its HW PIN pairs during init. Note: Only one of DRAMs can have its PIN swapped)
+# Valid values: 0/1
+#dram0_clamshell_enable.BCM88650=1
+#dram1_clamshell_enable.BCM88650=1
+
+# DRAM maximum number of crc error per buffer, buffer deleted by interrupt application.
+#dram_crc_del_buffer_max_reclaims=0
+
+### Warmboot ###
+## Scache initialization for warmboot persistent storage.
+#Save the warm boot data in a file. Allowed values: 3.
+#stable_location.BCM88650=3
+#Set the warm boot data filename.
+#stable_filename.BCM88650=./warmboot_data
+#Set the warm boot data file size (At least 10MB for PETRA-B, 4MB for ARAD)
+#stable_size.BCM88650=1000000000
+
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+## If set, always configures synthesizers, even if the configured rate is equal to
+## their nominal rate. Can be disabled to speedup bringup time (keep in mind that if
+## disabled, changing a synt to a non-nominal freq and than back to nominal will not
+## work
+#synt_over.BCM88650=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88650=100000000
+synt_ddr.BCM88650=125000000
+synt_phy.BCM88650=156250000
+synth_dram_freq.BCM88650=25
+
+#Configure the reference clock frequencies for NIF and Fabric SerDes
+# Options: 0 - 125MHZ, 1 - 156.25MHz
+serdes_nif_clk_freq.BCM88650=1
+serdes_fabric_clk_freq.BCM88650=1
+# IEEE 1588 -
+# configure clock (for 1588 debug, when Broadsync is disabled):
+# DPLL mode/lock: 0 - eci ts pll clk disabled, 1 - configure eci ts pll clk
+# DPLL phase/freq. Default initial: lo = 0x40000000, hi = 0x10000000.
+#phy_1588_dpll_frequency_lock.BCM88650=1
+#phy_1588_dpll_phase_initial_lo.BCM88650=0x40000000
+#phy_1588_dpll_phase_initial_hi.BCM88650=0x10000000
+# port external MAC
+# indication whether external MAC exists or not.
+# 0: 1588 external MAC does not exist
+# 1: 1588 external MAC exists
+# the external MAC substracts the RX time from the correction field
+# and adds the TX time to the correction field.
+#ext_1588_mac_enable_14.BCM88650=1
+
+## Trill configurations
+# Trill mode: 0 (disabled) / 1 (coarse-grained) / 2 (fine-grained)
+#trill_mode.BCM88650=1
+
+# Trill multicast prunning mode:
+# 0: no prunning - vsi is not part of the key
+# 1: VSI prunning: Key is dist-tree,esadit-bit,VSI.
+trill_mc_prune_mode.BCM88650=0
+
+# Enable SA authentication
+#sa_auth_enabled=1
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88650=0
+logical_port_drop.BCM88650=1
+
+#logical_port_mim_in.BCM88650=2
+#logical_port_mim_out.BCM88650=4096
+
+# Enable EVB application
+#evb_enable=1
+
+# Enable Flexible QinQ application
+#vlan_translation_match_ipv4=1
+
+
+# Prepend tag to be 4 bytes or 8 bytes. Default: 4B.
+# Applicable only from ARAD+
+#prepend_tag_bytes=4B
+
+# The Prepend Tag is located at (12 + 2*offset) bytes from the start of the packet.
+# Range: 0-7. Default: 0
+#prepend_tag_offset=0
+
+# Enable ARP (next hop mac extension) feature
+bcm886xx_next_hop_mac_extension_enable.BCM88650=0
+
+# Set VLAN translate mode.
+# 0: normal
+# 1: advanced mode. Enable vlan edit settings with enhanced user control
+#bcm886xx_vlan_translate_mode=0
+
+# Set MPLS termination database mode
+# Set MPLS databases location for each MPLS namespace (L1,L2,L3)
+#bcm886xx_mpls_termination_database_mode=0
+
+# Enable , Disable MPLS indexed.
+# MPLS termination with known label stack location.
+# Must be enabled in case device supports more than 2 MPLS label terminations (L1,L2,L3)
+#mpls_termination_label_index_enable=1
+
+# Enable FastReRoute labels in device.
+#fast_reroute_labels_enable=0
+
+# Enable MPLS Context specific. Upstream label assignment in device.
+#mpls_context_specific_label_enable=0
+
+# MPLS context.
+# Can be global, per port , per interface or per port,interface.
+#mpls_context=global
+
+# MPLS TP MC reserved mac address (01-00-5E-90-00-00).
+# If set device will support My-MAC termination of reserved MC Ethernet
+#mpls_tp_mymac_reserved_address=0
+
+# MPLS ELI enable disable
+mpls_entropy_label_indicator_enable=0
+
+
+#########################################
+##cfg for BCM88640_A0 - Petra
+#########################################
+
+force_clk_m_n_divisors_zero_nif0.BCM88640_A0=0
+force_clk_m_n_divisors_zero_fabric0.BCM88640_A0=1
+force_clk_m_n_divisors_zero_comb0.BCM88640_A0=0
+
+combo_ref_clock.BCM88640=312500
+
+nif_ref_clock.BCM88640_A0=312500
+
+# Use variable cell size
+system_cell_format.BCM88640_A0=VCS128
+
+# Core clock speed (MHz)
+core_clock_speed.BCM88640_A0=300
+
+# Map bcm local port to CPU/NIF interfaces
+ucode_port_0.BCM88640_A0=CPU.0
+ucode_port_73.BCM88640_A0=CPU.1
+ucode_port_74.BCM88640_A0=CPU.2
+ucode_port_75.BCM88640_A0=CPU.3
+ucode_port_76.BCM88640_A0=CPU.4
+ucode_port_77.BCM88640_A0=CPU.5
+ucode_port_78.BCM88640_A0=CPU.6
+
+# Interlaken ports basic configuration (temporary).
+# This configuration replaces the above XAUI/RXAUI ports config
+# The following PB design constraint is not enforced in SW, so must be taken
+# care of here, when mapping ports to interfaces:
+# If using ilkn0, port 1 (if used) must be mapped to ilkn0
+# If using ilkn1, port 2 (if used) must be mapped to ilkn1
+# Note that in our default mapping, port 2 is mapped to RXAUI 6, thus won't
+# work. If one wants to use front panel port 2 with ilkn1, he should be map
+# RAXUI6 to a port != 2.
+#ilkn_num_lanes_0.BCM88640_A0=12
+#ucode_port_1.BCM88640_A0=ILKN0.0
+#ucode_port_2.BCM88640_A0=ILKN0.1
+#ucode_port_3.BCM88640_A0=ILKN0.2
+#ilkn_num_lanes_1.BCM88640_A0=12
+#ucode_port_4.BCM88640_A0=RXAUI6
+#ucode_port_5.BCM88640_A0=ILKN1.0
+#ucode_port_6.BCM88640_A0=ILKN1.1
+#ucode_port_7.BCM88640_A0=ILKN1.2
+
+# Default header type is derived from fap_device_mode: If fap_device_mode is
+# PP, default header type is ETH. Otherwise, defualt header type is TM.
+# Header type per port can be overriden.
+# All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/INJECTED
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88640_A0=TM
+tm_port_header_type_in_0.BCM88640_A0=TM
+tm_port_header_type_out_0.BCM88640_A0=CPU
+tm_port_header_type_73.BCM88640_A0=TM
+tm_port_header_type_74.BCM88640_A0=TM
+tm_port_header_type_75.BCM88640_A0=TM
+tm_port_header_type_76.BCM88640_A0=TM
+tm_port_header_type_77.BCM88640_A0=TM
+tm_port_header_type_78.BCM88640_A0=TM
+# recycling port
+tm_port_header_type_40.BCM88640_A0=RAW
+ucode_port_40.BCM88640_A0=RCY.0
+
+# Enable ERP and OLP ports
+num_erp_tm_ports.BCM88640_A0=1
+num_olp_tm_ports.BCM88640_A0=1
+num_recycle_tm_ports.BCM88640_A0=1
+
+# Dram configuration
+# 600 Mhz
+ext_ram_pll_r.BCM88640_A0=4
+ext_ram_pll_f.BCM88640_A0=47
+ext_ram_pll_q.BCM88640_A0=1
+ext_ram_freq.BCM88640_A0=600
+
+# Dbuff size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88640_A0=1024
+
+# Number of external DRAMs.
+# Allowed values for 88x4x: 0/2/3/4/6.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# ext_ram_total_size below assumed this value is 6 for 88x4x and 8 for
+ext_ram_present.BCM88640_A0=6
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram
+# related parameteres per type.
+# Dram Type for Pb:
+dram_type_DDR3_MICRON_MT41J64M16_15E.BCM88640_A0=1
+#dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600.BCM88640_A0=1
+#dram_type_GDDR3_SAMSUNG_K4J52324QE.BCM88640_A0=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G.BCM88640_A0=1
+
+# QDR configuration
+# Parity. Allowed values: PARITY/ECC.
+ext_qdr_protection_type.BCM88640_A0=PARITY
+ext_qdr_size_mbit.BCM88640_A0=72
+#QDR type: QDR/QDR2P/QDR3/NONE.
+ext_qdr_type.BCM88640_A0=QDR
+
+# QDR can use the core clock, or using it's own pll. Current example is for 250MHz pll (if used).
+# QDR using own pll configuration
+#ext_qdr_use_core_clock_freq.BCM88640_A0=0
+#ext_qdr_pll_m.BCM88640_A0=4
+#ext_qdr_pll_n.BCM88640_A0=4
+#ext_qdr_pll_p.BCM88640_A0=0
+
+# QDR using core clock
+ext_qdr_use_core_clock_freq.BCM88640_A0=1
+
+#Configure MDIO. If parameter is not defined, MDIO is disabled.
+mdio_clock_freq_khz.BCM88640_A0=1000
+
+# Streaming interface configuration
+streaming_if_enable_timeoutcnt.BCM88640_A0=1
+streaming_if_timeout_prd.BCM88640_A0=70
+streaming_if_quiet_mode.BCM88640_A0=0
+streaming_if_discard_bad_parity.BCM88640_A0=0
+
+# maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88640_A0=0
+
+# multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_min.BCM88640_A0=0
+egress_multicast_direct_bitmap_max.BCM88640_A0=4095
+
+# configure flow mapping base to 0
+flow_mapping_queue_base.BCM88640_A0=0
+
+dtm_flow_mapping_mode_region_25.BCM88640_A0=0
+dtm_flow_mapping_mode_region_26.BCM88640_A0=0
+dtm_flow_mapping_mode_region_27.BCM88640_A0=0
+dtm_flow_mapping_mode_region_28.BCM88640_A0=0
+dtm_flow_mapping_mode_region_29.BCM88640_A0=0
+dtm_flow_mapping_mode_region_30.BCM88640_A0=0
+dtm_flow_mapping_mode_region_31.BCM88640_A0=0
+dtm_flow_mapping_mode_region_32.BCM88640_A0=0
+dtm_flow_mapping_mode_region_33.BCM88640_A0=1
+dtm_flow_mapping_mode_region_34.BCM88640_A0=1
+dtm_flow_mapping_mode_region_35.BCM88640_A0=1
+dtm_flow_mapping_mode_region_36.BCM88640_A0=1
+dtm_flow_mapping_mode_region_37.BCM88640_A0=1
+dtm_flow_mapping_mode_region_38.BCM88640_A0=1
+dtm_flow_mapping_mode_region_39.BCM88640_A0=1
+dtm_flow_mapping_mode_region_40.BCM88640_A0=1
+dtm_flow_mapping_mode_region_41.BCM88640_A0=1
+dtm_flow_mapping_mode_region_42.BCM88640_A0=2
+dtm_flow_mapping_mode_region_43.BCM88640_A0=2
+dtm_flow_mapping_mode_region_44.BCM88640_A0=2
+dtm_flow_mapping_mode_region_45.BCM88640_A0=2
+dtm_flow_mapping_mode_region_46.BCM88640_A0=2
+dtm_flow_mapping_mode_region_47.BCM88640_A0=2
+dtm_flow_mapping_mode_region_48.BCM88640_A0=2
+dtm_flow_mapping_mode_region_49.BCM88640_A0=2
+dtm_flow_mapping_mode_region_50.BCM88640_A0=2
+dtm_flow_mapping_mode_region_51.BCM88640_A0=2
+dtm_flow_mapping_mode_region_52.BCM88640_A0=2
+dtm_flow_mapping_mode_region_53.BCM88640_A0=2
+dtm_flow_mapping_mode_region_54.BCM88640_A0=2
+dtm_flow_mapping_mode_region_55.BCM88640_A0=2
+
+# Power up state (DOWN/UP/UP_AND_RELOCK). Can be configured per lane.
+pb_serdes_lane_power_state.BCM88640_A0=UP_AND_RELOCK
+
+# SeDes media type: Pre-configuration for tx params, according to
+# media type.
+# Allowed values: SHORT_BACKPLANE/LONG_BACKPLANE/CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type.BCM88640_A0=SHORT_BACKPLANE
+pb_serdes_lane_tx_phys_media_type_28.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_29.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_30.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_31.BCM88640_A0=CHIP2CHIP
+
+system_is_fe1600_in_system.BCM88640_A0=0
+
+# Counter engine configuration
+counter_engine_source_1.BCM88640_A0=0
+counter_engine_statistics_1.BCM88640_A0=4
+counter_engine_source_2.BCM88640_A0=1
+counter_engine_statistics_2.BCM88640_A0=4
+
+# Statistic Reporting
+stat_if_enable=0
+
+# Clock Phases: 0/90/180/270
+stat_if_phase=0
+
+# Rate in nm
+stat_if_sync_rate=0
+
+# TRUE/FALSE
+stat_if_parity_enable=FALSE
+
+# BILLING/FAP20V
+stat_if_report_mode=BILLING
+
+# Billing Mode
+# EGR_Q_NB/CUD/VSI_VLAN/BOTH_LIFS
+stat_if_report_billing_mode=VSI_VLAN
+
+# Fap20V Mode
+# QUEUE/PACKET
+stat_if_report_fap20v_mode=QUEUE
+
+# QUEUE_NUM/MC_ID (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_fabric_mc=QUEUE_NUM
+stat_if_report_fap20v_ing_mc=QUEUE_NUM
+
+# TRUE/FALSE (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_cnm_report=FALSE
+
+# TRUE/FALSE
+stat_if_report_fap20v_count_snoop=FALSE
+stat_if_report_original_pkt_size=FALSE
+stat_if_report_fap20v_single_copy_reported=FALSE
+
+schan_timeout_usec.BCM88640_A0=300000
+
+
+polled_irq_mode.BCM88640_A0=0
+polled_irq_delay.BCM88640_A0=1000
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88640=DISABLED
+
+#########################################
+##cfg for BCM88750
+#########################################
+
+fabric_device_mode.BCM88750=SINGLE_STAGE_FE2
+
+is_dual_mode.BCM88750=0
+system_is_vcs_128_in_system.BCM88750=0
+
+system_is_dual_mode_in_system.BCM88750=0
+system_is_single_mode_in_system.BCM88750=1
+
+system_is_fe600_in_system.BCM88750=0
+
+system_ref_core_clock_khz.BCM88750=600000
+
+fabric_merge_cells.BCM88750=0
+fabric_multicast_mode.BCM88750=DIRECT
+fabric_load_balancing_mode.BCM88750=NORMAL_LOAD_BALANCE
+fabric_tdm_fragment.BCM88750=0x180
+##Allows single pipe device to send TDM traffic over the fabric primary pipe - available for Fe1600_B0 only
+#change vcs128_unicast_priority to be lower than 2 - when enabling
+fabric_tdm_over_primary_pipe.BCM88750=0
+fabric_optimize_partial_links.BCM88750=0
+vcs128_unicast_priority.BCM88750=2
+
+polled_irq_mode.BCM88750=0
+polled_irq_delay.BCM88750=1000
+
+#Selects if to run MBIST (Memory Built In Self Test) of internal memory (tables) during startup.
+#Supported values: 0=don't run, 1=run, 2=run with extra logs
+#bist_enable.BCM88650=1
+bist_enable.BCM88750=1
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88750=0
+load_firmware.BCM88750=2
+
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88750=2
+
+#enable\disable CL72
+port_init_cl72.BCM88750=0
+#Avaliable speeds for BCM88750: 5750, 6250, 10312, 11500, 12500
+port_init_speed.BCM88750=10312
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88750=1
+serdes_fabric_clk_freq_out.BCM88750=1
+serdes_mixed_rate_enable.BCM88750_B0=0
+
+# VSC128 or VSC256
+fabric_cell_format.BCM88750=VSC256
+
+# Core clock speed (MHz)
+core_clock_speed_khz.BCM88750=533333
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88750=0
+schan_timeout_usec.BCM88750=300000
+# TDMA
+tdma_intr_enable.BCM88750=0
+tdma_timeout_usec.BCM88750=80000000
+# TSLAM
+tslam_intr_enable.BCM88750=0
+tslam_timeout_usec.BCM88750=80000000
+# MIIM
+miim_intr_enable.BCM88750=0
+miim_timeout_usec.BCM88750=300000
+
+
+##initialization for warmboot
+stable_location.BCM88750=3
+stable_size.BCM88750=200000
+scache_filename.BCM88750=fe1600_warmboot.mem
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+# Support (and configure on init) packet processing features.
+# If not defined - only traffic management capabilities are enabled.
+packet_processing=1
+
+## PCP (Petra Co-Processor) features
+#pcp_elk.BCM88640_A0=1
+#pcp_oam.BCM88640_A0=1
+#pcp_dma.BCM88640_A0=1
+
+## Set/Override TDM related config variables
+#tdm.BCM88640_A0=1
+
+# If set, always configures synthesizers, even if the configured rate is
+# equal to
+# their nominal rate. Can be disabled to speedup bringup time
+# (keep in mind that if disabled, changing a synt to a non-nominal freq and
+# than back to nominal will not work
+#synt_over.BCM88640_A0=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88640_A0=100000000
+synt_ddr.BCM88640_A0=125000000
+synt_phy.BCM88640_A0=156250000
+
+## Scache initialization for warmboot persistent storage.
+## Valid values: 2: Store in dram. 3: Store in a file.
+stable_location=3
+stable_filename=./warmboot_data
+stable_flags=0
+stable_size=1000000000
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88640=1
+logical_port_drop.BCM88640=-1
+
+#logical_port_mim_in.BCM88640=2
+#logical_port_mim_out.BCM88640=3
+
+## IPV6 tunnel
+bcm886xx_ipv6_tunnel_enable=1
+
+## Inlif Profile Management Mode - QoS L3 L2 marking mode
+#
+# BCM88660 ONLY
+#
+# QoS L3 L2 marking allows changing the DSCP and/or EXP values
+# of IP and/or MPLS packets according to the incoming port
+# (or inlif), and the Traffic Class/Drop Precedence.
+#
+# The inlif profile is used to control the DSCP/EXP marking.
+# This SOC property controls which mode is used for the inlif profile:
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the DSCP/EXP marking).
+# 0: Advanced mode (the user controls which inlif profile values perform DSCP/EXP marking directly).
+#bcm886xx_qos_l3_l2_marking=1
+
+## Unicast RPF mode per RIF
+#
+# This SOC property allows the user to set the unicast RPF mode - loose, strict or disabled - per RIF.
+# If disabled, the unicast RPF mode of a RIF is set globally.
+# Options: 0 / 1
+
+# bcm886xx_l3_ingress_urpf_enable=1
+
+## BOS handling mode
+# BCM8866X ONLY
+#
+# There are two ways to handle BOS, controlled by bcm886xx_mpls_termination_mode:
+# 0 - Use BOS as key in lookup.
+# 1 - Don't use it (except for reserved labels).
+#
+#bcm886xx_mpls_termination_key_mode=0
+
+# Color resolution mode allows the user to have more detailed metering color information.
+# BCM88660 ONLY
+#
+# Options: 0/1
+# 0: A red result from both Ethernet policer and policer implies DP=3.
+# 1: A red result from the policer implies that DP=2, while a red result from rate (Ethernet policer) implies DP=3.
+#policer_color_resolution_mode=1
+
+## Inlif Profile Management Mode - Disable Same Interface Filter
+# BCM8866X ONLY
+#
+# Controls which mode is used for the inlif profile management.
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the same-interface filter).
+# 0: Advanced mode (the user controls which inlif profile values have the same-interface filter disabled for them).
+#bcm886xx_logical_interface_bridge_filter_enable=1
+
+## Default Block Forwarding Strength
+#
+# Configure the default forwarding strength of blocks.
+#
+# SOC Properties:
+#block_trap_strength_vtt - VTT block forwarding strength
+#block_trap_strength_flp - FLP block forwarding strength
+#block_trap_strength_hash - SLB block forwarding strength (BCM8866X ONLY)
+#block_trap_strength_pmf_0 - PMF 1st lookup forwarding strength
+#block_trap_strength_pmf_1 - PMF 2nd lookup forwarding strength
+#
+# Options: 0-7
+
+## Stateful Load Balancing
+# BCM8866X ONLY
+#
+# Stateful Load Balancing (SLB) allows the load balancing of ECMP and LAG
+# groups to become stateful.
+# In standard load balancing, removing a member from the ECMP/LAG
+# group may affect the selected member, since the formula
+# depends on group size.
+# In stateful load balancing the member is selected once and saved.
+# Later, the member is always retrieved, and does not depend on
+# the size of the LAG/ECMP group.
+#
+# resilient_hash_enable - Enable/disable SLB. Values:
+# 1 - Enable SLB.
+# 0 - Disable SLB.
+#resilient_hash_enable=1
+
+
+#Make Arad SOC properties work for Arad+, by mapping the BCM88660 suffix to BCM88650
+soc_family.BCM88660=BCM88650
+#Make Arad SOC properties work for Ardon, by mapping the BCM88202 suffix to BCM88650
+soc_family.BCM88202=BCM88650
+
+# Use different mymac addresses for ipv4 and ipv6 when using vrrp for mymac termination.
+#l3_vrrp_ipv6_distinct=1
+
+# Enable multiple mymac termination mode. In order to enable it, also set
+# l3_vrrp_ipv6_distinct=0 and l3_vrrp_max_vid=0 since vrrp and
+# multiple mymac mode can't co exist.
+#l3_multiple_mymac_termination_enable=1
+
+# Distinguish between ipv4 and all other l3 protocols when multiple mymac terminating
+#l3_multiple_mymac_termination_mode=1
+
+# Usually the final DP given by the meter (or the In-DP) is unchanged, and can be from 0-3.
+# When this SOC property is set to 1, when the final INGRESS DP is 2, it is mapped to 1 instead,
+# and thus only the values 0-1 and 3 can be output.
+# This has no effect when policer_color_resolution_mode=1.
+#custom_feature_always_map_result_dp_2_to_1=1
+
+############################
+### Warmboot & SW State ####
+############################
+
+
+ha_hw_journal_size=15728640
+ha_sw_journal_size=15728640
+ha_crash_recovery=1
+
+
+# stable_size - a strict bound on the application's external storage size
+stable_size.BCM88650=281000000
+stable_size=420000000
+
+# determine the memory size pre-allocated for the SDK's SW State
+sw_state_max_size.BCM88650=160000000
+sw_state_max_size=350000000
+
+# stable location
+## part of scache initialization for warmboot persistent storage.
+## values: 1-2:Not Valid for dnx 3: Store in a file 4: Use Shared Mem.
+# 4 is the preffered option, using 3 for Arad and FE in order to regress both modes.
+ stable_location.BCM88650=3
+ stable_location.BCM88660=3
+
+#
+# Enable L3 Source Binds for DPoE SAV
+#
+l3_source_bind_mode=IP
+l3_source_bind_subnet_mode=IP
+ipv4_num_vrfs = 4096
+
+#
+# Enable ARP checking for L3 Source Binds
+#
+# This feature is not currently used.
+#
+# Valid values for custom_feature_l3_source_bind_arp_relay:
+# 0 - disabled
+# 1 - downstream ARP checking
+# 2 - upstream ARP checking
+# 3 - both downstream and upstream ARP checking
+#
+#custom_feature_l3_source_bind_arp_relay=2
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/rc.soc b/bal_release/3rdparty/bcm-sdk/rc/arad/rc.soc
new file mode 100755
index 0000000..12003a3
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/rc.soc
@@ -0,0 +1,1811 @@
+# $Id: rc.soc,v 1.192 Broadcom SDK $
+# $Copyright: Copyright 2016 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+# Initialization RC (run commands) file
+#
+# These are default commands that are read and executed by default
+# when BCM boots up. Typically this file is called rc.soc and resides
+# in the flash filesystem, NVRAM, or disk.
+#
+# Board Configuration Setting
+#
+# This file uses configuration properties to know on which board
+# it is running. Currently one of following settings must be made:
+#
+# BCM95670K8 config add herc8=1
+# BCM95690K24 config add draco_b2b=1
+# BCM95690K24S config add draco_stk=1
+# BCM95690R24 config add galahad=1
+# BCM95690R24S config add merlin=1
+# BCM95690R48S config add lancelot=1
+# BCM95691K12 config add draco_k12=1
+# White Knight config add white_knight=1 (not shipping)
+# Black Knight config add black_knight=1 (not shipping)
+# BCM95673K2S config add twolynx=1
+# BCM95673R8 config add herculynx=1
+# BCM95673R24S config add lynxalittle=1
+# BCM95673R48S config add lynxalot=1
+# BCM95695P24SX_10 config add guenevere=1
+# BCM95650K24 config add magnum=1 (automatic for 5650L)
+# BCM95675 config add herc8_15=1
+# BCM95650R24 config add tuc24_ref=1
+# BCM95695P48LM config add lm48p=1
+# BCM95695P48LM-10 config add lm48p_B=1
+# BCM956504P48LM-10 config add lm48p_C=1
+# BCM956504P48LM-20 config add lm48p_C=1
+# BCM956504P48LM-50 config add lm48p_D=1
+# BCM956504P48POEREF config add fbpoe=1
+# BCM956504P24REF P0 config add fb24=1
+# BCM956504P24 P0 config add fb24=1
+# BCM956102P48 config add felix48=1
+# BCM953300P24REF config add mirage24=1
+# BCM956800K20C config add bradley_1g=1
+# BCM956700K16 config add humv=1
+# BCM956800K20 config add bradley=1
+# BCM956580K16 config add goldwing=1
+# BCM956314P24REF config add bcm56314p24ref=1
+# BCM956024P48REF config add BCM956024P48REF=1
+# BCM956224P48REF config add BCM956224P48REF=1
+# BCM956224R50T config add BCM956224R50T=1
+# BCM956024R50T config add BCM956024R50T=1
+# BCM56820K24XG config add BCM56820K24XG=1
+# BCM953314R24GS config add BCM953314R24GS=1
+# BCM953314K24 config add BCM953314K24=1
+# BCM956820R24XG config add BCM956820R24XG=1
+# BCM956160R config add bcm956160r=1
+
+if $?BCM56146_A0 \
+ 'local BCM56146 1'
+
+if $?BCM56147_A0 \
+ 'local BCM56147 1'
+
+
+if $?1 "echo rc: arguments not supported; exit"
+if !$?unit "echo rc: no current unit; exit"
+
+echo "rc: unit $unit device $devname"
+local quiet no
+local echo echo
+local rcdone \$rc$unit
+if !"expr $rcdone + 0" "local echo noecho; local quiet yes"
+
+# Set convenience local variables
+
+# simulation related
+#if $?plisim \
+# "local no_bcm 1"
+if $?quickturn || $?plisim \
+ "local simulator 1"
+
+# board related
+if $?galahad \
+ "local draco_b2b 1"
+if $?black_knight || $?white_knight || $?merlin \
+ "local draco_herc4 1"
+
+# chip related
+if $?PETRAB_A0 \
+ 'rcload dune.soc ; exit'
+
+#if $?QUX_A0 \
+# 'echo blablabla;der 0x40 4 ; exit'
+
+if $?FLAIR_A0 \
+ 'echo blablabla;der 0x40 4 ; exit'
+
+if $?BCM88750_A0 || $?BCM88750_B0 || $?BCM88753_A0 || $?BCM88753_B0 || $?BCM88752_A0 || $?BCM88752_B0 || $?BCM88755_B0 || $?BCM88754_A0 || $?BCM88770_A1 || $?BCM88773_A1 || $?BCM88774_A1 || $?BCM88775_A1 || $?BCM88776_A1 || $?BCM88950_A0 || $?BCM88950_A1 || $?BCM88953_A1 || $?BCM88954_A1 || $?BCM88955_A1 || $?BCM88956_A1 || $?BCM88952_A0 || $?BCM88952_A1 || $?BCM88772_A1 \
+ 'rcload dfe.soc ; exit'
+
+if $?ARAD_A0 || $?ARAD_B0 || $?ARAD_B1 || $?ARADPLUS_A0 || $?BCM88650_A0 || $?BCM88650_B0 || $?BCM88650_B1 || $?BCM88652_A0 || $?BCM88652_B0 || $?BCM88350_B1 || $?BCM88351_B1 || \
+ $?BCM88450_B1 || $?BCM88451_B1 || $?BCM88550_B1 || $?BCM88551_B1 || $?BCM88552_B1 || $?BCM88651_B1 || $?BCM88654_B1 || $?BCM88660_A0 || $?BCM88360_A0 || $?BCM88361_A0 || $?BCM88363_A0 ||\
+ $?BCM88460_A0 || $?BCM88461_A0 || $?BCM88560_A0 || $?BCM88561_A0 || $?BCM88562_A0 || $?BCM88661_A0 || $?BCM88664_A0 \
+ 'rcload arad.soc ; rcload rpc.soc ; exit'
+
+if $?BCM88850_P3 \
+ 'exit'
+
+if $?QAX_A0 || $?BCM88470P_A0 || $?BCM88470_A0 || $?BCM88470M_A0 || $?BCM88471P_A0 || $?BCM88471_A0 || $?BCM88472_A0 || \
+ $?BCM88473_A0 || $?BCM88471D_A0 || $?BCM88476P_A0 || $?BCM88476_A0 || $?BCM88476D_A0 || $?BCM88476T_A0 || $?BCM88477_A0 \
+ 'setenv QAX 1'
+
+if $?QUX_A0 || $?BCM88270_A0 \
+ 'setenv QUX 1'
+
+if $?JERICHO_A0 || $?BCM88670_A0 || $?BCM88671_A0 || $?BCM88671M_A0 || $?BCM88672_A0 || $?BCM88673_A0 || $?BCM88674_A0 || $?BCM88675_A0 || $?BCM88675M_A0 || $?BCM88676_A0 || $?BCM88676M_A0 || $?BCM88678_A0 || $?BCM88679_A0 || \
+ $?JERICHO_A1 || $?BCM88670_A1 || $?BCM88671_A1 || $?BCM88671M_A1 || $?BCM88672_A1 || $?BCM88673_A1 || $?BCM88674_A1 || $?BCM88675_A1 || $?BCM88675M_A1 || $?BCM88676_A1 || $?BCM88676M_A1 || $?BCM88678_A1 || $?BCM88679_A1 || \
+ $?QMX_A0 || $?BCM88370_A0 || $?BCM88371_A0 || $?BCM88371M_A0 || $?BCM88375_A0 || $?BCM88376_A0 || $?BCM88376M_A0 || $?BCM88377_A0 || $?BCM88378_A0 || $?BCM88379_A0 || \
+ $?QMX_A1 || $?BCM88370_A1 || $?BCM88371_A1 || $?BCM88371M_A1 || $?BCM88375_A1 || $?BCM88376_A1 || $?BCM88376M_A1 || $?BCM88377_A1 || $?BCM88378_A1 || $?BCM88379_A1 || \
+ $?JERICHO_B0 || $?BCM88670_B0 || $?BCM88671_B0 || $?BCM88671M_B0 || $?BCM88672_B0 || $?BCM88673_B0 || $?BCM88674_B0 || $?BCM88675_B0 || $?BCM88675M_B0 || $?BCM88676_B0 || $?BCM88676M_B0 || $?BCM88678_B0 || $?BCM88679_B0 || $?BCM88680_A0 || \
+ $?QMX_B0 || $?BCM88370_B0 || $?BCM88371_B0 || $?BCM88371M_B0 || $?BCM88375_B0 || $?BCM88376_B0 || $?BCM88376M_B0 || $?BCM88377_B0 || $?BCM88378_B0 || $?BCM88379_B0 || $?BCM88379_A1 || \
+ $?JERPLUS || $?BCM88680_A0 || $?BCM88682_A0 || $?BCM88683_A0 || $?BCM88381_A0 || $?BCM88382_A0 || $?BCM88385_A0 || $?BCM88686_A0 \
+ 'rcload jer.soc ; exit'
+
+if $?QAX || $?QUX\
+ 'rcload qax.soc ; exit'
+
+
+if $?BCM88202_A0 || $?ARDON_A0 || $?BCM88202_A1 || $?ARDON_A1 || $?BCM88202_A2 || $?ARDON_A2\
+ 'rcload atmf.soc ; exit'
+
+if $?ACP \
+ 'exit'
+
+if $?BCM88690_A0\
+ 'exit'
+
+if !"expr $pcidev + 0 == 0x5650" \
+ "local magnum 1"
+if $?drac || $?drac15 \
+ "local drac_any 1"
+if $?lynx || $?lynx15 \
+ "local lynx_any 1"
+if $?tucana || $?magnum \
+ "local tucana_any 1"
+if $?herc || $?herc15 \
+ "local herc_any 1"
+if $?firebolt || $?firebolt2 || $?helix || \
+ $?felix || $?helix15 || $?felix15 || $?raptor || $?raven || $?hawkeye\
+ "local firebolt_any 1"
+if !"expr $pcidev + 0 == 0xb501" \
+ "local firebolt_10x4 1"
+if $?easyrider \
+ "local easyrider_any 1"
+if !"expr $pcidev + 0 == 0xb602" \
+ "local easyrider_1x1 1"
+if $?bradley || $?humv || $?goldwing \
+ "local bradley_any 1"
+if $?drac_any || $?lynx_any || $?tucana_any \
+ "local xgs12_switch 1"
+if $?firebolt_any || $?easyrider_any || $?bradley_any \
+ "local xgs3_switch 1"
+if $?xgs12_switch || $?xgs3_switch \
+ "local xgs_switch 1"
+if $?herc_any \
+ "local xgs_fabric 1"
+if $?xgs_fabric || $?xgs_switch \
+ "local xgs 1"
+if !$?xgs \
+ "local strata 1"
+if $?strata && !$?gsl \
+ "local PBMP_ALL 0x0bffffff"
+if $?strata && $?gsl \
+ "local PBMP_ALL 0x080000ff"
+if $?BCM56214_A0 || $?BCM56014_A0 || $?BCM56215_A0 || \
+ $?BCM56214_A1 || $?BCM56014_A1 || $?BCM56215_A1 && \
+ !$?BCM956024P48REF \
+ "local rap24_ref 1"
+
+if $?BCM5655_A0 || $?BCM5655_B0 \
+ "local tucana_nohg 1"
+
+if $?BCM956024P48REF || $?BCM956224P48REF || $?BCM956024R50T || \
+ $?BCM956224R50T \
+ "local raven_eb_48p 1"
+
+if $?BCM953314R24GS \
+ "local hawkeye_p24 1"
+
+if $?BCM953314K24 \
+ "local hawkeye_k24 1"
+
+if $?firebolt_any && $?lm48p || $?lm48p_D \
+ "config add lmfb48=1"
+
+# Set software's wait for S-Channel response to 3 seconds for QuickTurn
+# (Recommend at least 10 seconds if the ARL is 100% busy with inserts.)
+if $?quickturn "stimeout 3000000"
+if $?plisim "stimeout 60000000"
+
+# Direct phy led programming: 5464 activity led becomes link/activity
+if $?drac_any && $?lancelot || $?lynxalot || $?guenevere \
+ "config add phy_led_ctrl=0x18"
+
+# Shutdown threads if system is already running
+if $?triumph3 \
+ "ibodSync off"
+counter off
+linkscan off
+if $?feature_arl_hashed && !$?simulator \
+ "l2mode off"
+if $?feature_ces && $?BCM56440_A0 \
+ "ces off"
+
+# Test on-chip memory before initializing
+#if !$?simulator "init soc; bist l3 arl cbp"
+init soc
+
+# Initialize miscellaneous chip registers
+init misc
+
+# Initialize external TCAM if necessary
+# NOTE : tcam is initialized during "init misc" unless
+# tcam_reset_toggle = 1 is configured
+if "expr $rcdone + 0" && !"expr $tcam_reset_toggle + 0" \
+ "dispatch attach 0 esw 0"
+if !"expr $tcam_reset_toggle + 0" "muxsel 0; muxsel 0x80"
+if !"expr $tcam_reset_toggle + 0" "init tcam; $echo rc: TCAM initialized"
+
+# Initialize the StrataSwitch MMU registers
+init mmu
+if $?katana2 \
+ kt2config.soc
+
+
+# Uncomment to turn off Single-Bit Error reporting on 5670
+#if $?herc "m mmu_intcntl pp_sbe_en=0"
+
+# Initialize Cell Free Address Pool
+# NOTE: this should NOT be done unless chip is known to have bad CFAP
+# memory entries that need to be mapped out.
+if $?cfap_tests "$echo rc: Initializing CFAP; cfapinit"
+
+$echo rc: MMU initialized
+
+#
+# Load uKernel
+#
+
+# Pick default FW names if not set already by config
+if !$?fw_core_0 \
+ 'local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec; \
+ if $?greyhound || $?hurricane2 || $?hurricane3 "local fw_core_0 ${fw_prefix}_0_ptpfull.srec"; \
+ if $?caladan3 "local fw_core_0 ${fw_prefix}_0.srec"; \
+ if $?helix4 && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?helix4 && $?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec"; \
+ if $?tomahawk && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?trident2plus && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ '
+
+if !$?fw_core_1 \
+ 'local fw_core_1 ${fw_prefix}_1_ptpfull.srec; \
+ if $?caladan3 "local fw_core_1 ${fw_prefix}_1_bs.srec"; \
+ '
+
+if !$?fw_core_2 \
+ "local fw_core_2 ${fw_prefix}_2_eth_lmdm.srec"
+
+# Load the firmwares
+if $?feature_cmicm && !$?rcpu_only && !$ihost_mode && !$?feature_iproc \
+ "mcsload 0 ${fw_core_0} InitMCS=true; \
+ mcsload 1 ${fw_core_1};"
+
+if $?hurricane2 \
+ "mcsload 0 ${fw_core_0} InitMCS=true;"
+
+if $?feature_iproc && !$?hurricane2 && !$?hurricane3 && !$?rcpu_only && !$?feature_uc_mhost && !$ihost_mode\
+ "mcsload 0 ${fw_core_0} InitMCS=true TwoStage=true TwoStageAddr=0x60000000;\
+ mcsload 1 ${fw_core_1} TwoStage=true TwoStageAddr=0x6002c000;"
+
+if $?feature_iproc && !$?rcpu_only && $?feature_uc_mhost && $?num_ucs\
+ 'if !"expr $num_ucs > 0" "mcsload 0 ${fw_core_0} InitMCS=true"; \
+ if !"expr $num_ucs > 1" "mcsload 1 ${fw_core_1}"; \
+ if !"expr $num_ucs > 2" "mcsload 2 ${fw_core_2}";'
+
+#
+# Init CLI and BCM API
+#
+# This must be done after the raw register writes to avoid having state
+# clobbered. NOTE: Tables are cleared by "init bcm" below. If
+# table modifications are required, put them after "init bcm". Some
+# registers might also be affected.
+#
+
+if !$?no_bcm \
+ "init bcm; \
+ $echo rc: BCM driver initialized"
+
+if $?no_bcm \
+ "$echo rc: *** NOT initializing BCM driver ***"
+
+if $?no_bcm && $?strata \
+ 'write vtable 0 1 VLAN_TAG=0,PORT_BITMAP=0,UT_PORT_BITMAP=0; \
+ insert vtable VLAN_TAG=1,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ local pv \
+ VLAN_TAG=1,SP_ST=3,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ write ptable 0 32 PTYPE=0; \
+ if !$?gsl "write ptable 0 24 $pv,PTYPE=1"; \
+ if !$?gsl "write ptable 24 2 $pv,PTYPE=2"; \
+ if $?gsl "write ptable 0 8 $pv,PTYPE=2"; \
+ write ptable 27 1 $pv,PTYPE=3; \
+ local pv'
+
+# Turn on mirroring of hardware ARL operations into software ARL table.
+if $?feature_arl_sorted \
+ "arlmode intr_dma; \
+ $echo rc: ARL DMA shadowing enabled"
+
+if $?feature_arl_hashed && !$?simulator && !$?rcpu_only \
+ "l2mode interval=3000000; \
+ $echo rc: L2 Table shadowing enabled"
+
+# If running BCM library, start linkscan task and set port modes
+
+if !$?no_bcm && !$?rcpu_only \
+ "linkscan 250000; \
+ port fe,ge linkscan=on autoneg=on \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port st linkscan=on txpause=false rxpause=false; \
+ port xe,ce linkscan=on autoneg=off \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port hg linkscan=on fullduplex=true txpause=false rxpause=false; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?rcpu_only \
+ "linkscan 250000; \
+ port e linkscan=on; \
+ port st linkscan=on; \
+ port xe linkscan=on; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?shadow \
+ "port il linkscan=on; \
+ $echo rc: Interlaken Port mode initialized"
+
+# Selectively re-enable Auto Negotiation based on config port_force_an_list.
+#if $?port_force_an_list \
+# "port $port_force_an_list autoneg=on"
+
+# No spanning tree is running, so put ports all in the forwarding state
+# stp support not available for shadow device.
+
+if !$?no_bcm && !$?shadow \
+ "stg stp 1 all forward"
+
+# Start counter task unless already started by "init bcm" above.
+if $?plisim "local dma false"
+if !$?plisim "local dma true"
+if $?device_eb_vli "local dma false"
+if $?no_bcm && !$?rcpu_only\
+ "counter Interval=1000 Pbm=all Dma=$dma; \
+ $echo rc: Counter collection enabled"
+if $?rcpu_only \
+ "counter Interval=2000000 Pbm=all Dma=false; \
+ $echo rc: Counter collection enabled"
+
+# Resynchronize the saved values kept by the 'show counter' command.
+if !$?simulator \
+ "counter sync"
+
+# By default, dump data of packets that go to CPU.
+if !$?testinit \
+ "pw report +raw"
+
+# Default LED processor program for various SDKs and reference designs.
+# Source code can be found in $SDK/led/examples.
+
+if !$?p48 "local ledcode '\
+ E0 28 60 7F 67 2F 67 6B 06 7F 80 D2 1A 74 01 12 \
+ 7E 85 05 D2 0F 71 19 52 00 12 7D 85 05 D2 1F 71 \
+ 23 52 00 12 7C 85 05 D2 05 71 2D 52 00 3A 68 32 \
+ 00 97 75 3B 12 A0 FE 7F 02 0A 50 32 01 97 75 47 \
+ 12 BA FE 7F 02 0A 50 12 BA FE 7F 95 75 59 85 12 \
+ A0 FE 7F 95 75 A8 85 77 9A 12 A0 FE 7F 95 75 63 \
+ 85 77 A1 16 7C DA 02 71 A1 77 A8 32 05 97 71 76 \
+ 06 7D D2 01 71 9A 06 7F 67 93 75 9A 32 02 97 71 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 7E D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5605.hex
+
+if $?p48 "local ledcode '\
+ E0 28 60 7F 67 43 67 3C 67 35 67 2F 06 7F 80 D2 \
+ 18 74 01 28 60 7F 67 9B 67 89 67 BF 67 83 67 3C \
+ 67 73 67 68 67 5D 06 7F 80 D2 1A 74 13 3A 70 67 \
+ AD 71 C3 77 BF 32 03 97 71 C3 77 BF 32 05 97 71 \
+ C3 77 BF 12 BA FE 7F 32 01 97 75 4F 02 06 50 32 \
+ 00 97 75 57 02 06 50 95 75 C3 85 77 BF 67 AD 75 \
+ BF 32 04 97 71 C3 77 BF 67 AD 75 BF 32 03 97 71 \
+ C3 77 BF 67 AD 75 BF 32 03 97 71 BF 32 04 97 71 \
+ BF 77 C3 67 B6 71 C3 77 BF 12 A0 FE 7F 32 00 97 \
+ 75 95 02 06 50 95 75 C3 85 77 BF 12 BA FE 7F 32 \
+ 01 97 75 A7 02 06 50 95 75 C3 85 77 BF 06 7F 12 \
+ 80 F8 15 1A 00 57 06 7F 12 80 F8 15 1A 07 57 32 \
+ 0F 87 57 32 0E 87 57'" # p48.hex
+
+if $?herc && !$?black_knight "local ledcode '\
+ 02 01 67 36 29 32 08 D7 87 32 07 D7 87 32 01 D7 \
+ 87 32 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 \
+ 74 24 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 \
+ 87 91 74 2D 3A 28 10 DA 07 75 3E FA 02 57 EA 06 \
+ 57'" # sdk5670.hex
+
+if $?herc && $?black_knight "local ledcode '\
+ 2A 03 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 00 \
+ D7 87 2A 06 32 08 D7 87 32 07 D7 87 32 01 D7 87 \
+ 32 00 D7 87 3A 08'" # knigget.hex
+
+if $?drac_any "local ledcode '\
+ E0 28 60 C3 67 4E 67 8A 06 C3 80 D2 0C 74 01 28 \
+ 60 C3 32 00 D7 87 32 01 D7 87 32 07 D7 87 32 08 \
+ D7 87 32 0F 87 32 0F 87 32 0F 87 32 0F 87 12 C2 \
+ 85 05 D2 0F 71 38 52 00 12 C1 85 05 D2 1F 71 42 \
+ 52 00 12 C0 85 05 D2 05 71 4C 52 00 3A 38 32 00 \
+ 97 75 5A 12 A0 FE C3 02 0A 50 32 01 97 75 66 12 \
+ AD FE C3 02 0A 50 12 AD FE C3 95 75 78 85 12 A0 \
+ FE C3 95 75 C0 85 77 B9 12 A0 FE C3 95 75 82 85 \
+ 77 C7 16 C0 DA 02 71 C7 77 C0 32 05 97 71 9A 32 \
+ 02 97 71 B9 06 C1 D2 01 71 B9 06 C3 67 B2 75 B9 \
+ 32 03 97 71 C0 32 04 97 75 C7 06 C2 D2 07 71 C7 \
+ 77 C0 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5690.hex
+
+if $?draco_k12 "local ledcode '\
+ 02 0B A2 01 28 A2 01 60 C3 67 32 67 6E 06 C3 90 \
+ 75 02 12 C2 85 05 D2 0F 71 1C 52 00 12 C1 85 05 \
+ D2 1F 71 26 52 00 12 C0 85 05 D2 05 71 30 52 00 \
+ 3A 30 32 00 97 75 3E 12 A0 FE C3 02 0A 50 32 01 \
+ 97 75 4A 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 \
+ 5C 85 12 A0 FE C3 95 75 A6 85 77 9F 12 A0 FE C3 \
+ 95 75 66 85 77 AD 16 C0 DA 02 71 AD 77 A6 32 05 \
+ 97 71 7E 32 02 97 71 9F 06 C1 D2 01 71 9F 06 C3 \
+ 67 96 75 9F 32 03 97 71 A6 32 04 97 75 AD 06 C2 \
+ D2 07 71 AD 77 A6 12 80 A2 01 F8 15 1A 00 57 32 \
+ 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 \
+ 32 0E 87 57'" # k12-5690.hex
+
+if $?herc && $?white_knight "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 07 \
+ D7 87 32 01 D7 87 32 00 D7 87 57'" # wk5670.hex
+
+if $?herc && $?merlin "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # merlin5670.hex
+
+if $?herc && $?lancelot "local ledcode '\
+ 2A 05 67 12 2A 06 67 12 2A 03 67 12 2A 04 67 12 \
+ 3A 10 32 08 D7 87 32 00 D7 87 32 01 D7 87 32 07 \
+ D7 87 57'" # lancelot.hex
+
+if $?xgs_fabric && $?guenevere "local ledcode '\
+ 2A 04 67 0A 2A 05 67 0A 3A 04 32 07 D7 87 32 00 \
+ 32 01 B7 D7 87 57'" # guenevere5670.hex
+
+if $?drac_any && $?white_knight "local ledcode '\
+ E0 28 60 C3 67 2f 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # wk5690.hex
+
+if $?drac_any && $?merlin "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # merlin5690.hex
+
+if $?drac_any && $?galahad "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # galahad.hex
+
+if $?drac_any && $?lm "local ledcode '\
+E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+32 0F 87 57 32 0F 87 32 0E 87 57'" # lm5690.hex
+
+if $?twolynx "local ledcode '\
+ 2A 01 67 0A 2A 00 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # twolynx.hex
+
+if $?lynx_any && $?herculynx || $?lynxalot || $?lm || $?guenevere \
+ "local ledcode '\
+12 C0 85 05 D2 03 71 0A 52 00 2A 00 67 10 3A 04 \
+32 08 D7 87 06 C0 D2 01 71 22 32 0F 87 32 0F 87 \
+77 2A 32 00 D7 87 32 01 D7 87 32 07 D7 87 57'" # herculynx.hex
+
+if $?tucana && !$?magnum "local ledcode '\
+ E0 67 23 D2 18 74 01 02 20 67 23 D2 38 74 09 02 \
+ 18 67 23 D2 1C 74 11 E9 02 80 45 80 81 DA 0D 74 \
+ 1A 3A 68 28 60 E3 67 4A 67 36 06 E4 30 87 06 E5 \
+ 30 87 06 E3 80 57 32 00 97 71 45 32 01 97 71 45 \
+ 02 0F 60 E5 57 02 0E 60 E5 57 06 E3 12 A0 F8 15 \
+ 1A 00 75 59 02 0E 60 E4 57 02 0F 60 E4 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC 67 5A 67 9C 06 FA 67 DA 06 FB 67 DA \
+ 06 FC 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0E 74 51 3A 70 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 D7 85 77 D1 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 D4 16 FF DA 02 02 FA 71 D4 77 D7 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 D1 06 FC 67 CA 02 FB 75 \
+ D1 32 02 97 71 D1 32 03 97 71 D7 32 04 97 75 D4 \
+ 06 FD D2 07 02 FB 71 D4 77 D7 12 A0 F8 15 1A 00 \
+ 57 42 00 57 42 01 57 42 02 57 D2 02 74 E3 32 0F \
+ 87 77 E6 32 0E 87 D2 01 74 EE 32 0F 87 57 32 0E \
+ 87 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 75 09 A2 01 60 FC 28 67 37 67 73 \
+ 06 FB 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 3A 70 32 00 97 75 43 12 C0 FE FC \
+ 02 0A 50 32 01 97 75 4F 12 DC FE FC 02 0A 50 12 \
+ DC FE FC 95 75 61 85 12 C0 FE FC 95 75 B0 85 77 \
+ A2 12 C0 FE FC 95 75 6B 85 77 A9 16 FF DA 02 71 \
+ A9 77 B0 32 05 97 71 7E 06 FE D2 01 71 A2 06 FC \
+ 67 9B 75 A2 32 02 97 71 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 FD D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0F 87 32 0F 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57'" # magnum_sdk.hex
+
+if $?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 71 10 60 FC 28 67 D0 67 C0 77 19 \
+ A2 01 60 FC 28 67 40 67 7C 06 FB 80 D2 1C 74 01 \
+ 12 FD 85 05 D2 0F 71 2A 52 00 12 FE 85 05 D2 1F \
+ 71 34 52 00 12 FF 85 05 D2 05 71 3E 52 00 3A 68 \
+ 32 00 97 75 4C 12 C0 FE FC 02 0A 50 32 01 97 75 \
+ 58 12 DC FE FC 02 0A 50 12 DC FE FC 95 75 6A 85 \
+ 12 C0 FE FC 95 75 B9 85 77 AB 12 C0 FE FC 95 75 \
+ 74 85 77 B2 16 FF DA 02 71 B2 77 B9 32 05 97 71 \
+ 87 06 FE D2 01 71 AB 06 FC 67 A4 75 AB 32 02 97 \
+ 71 AB 32 03 97 71 B9 32 04 97 75 B2 06 FD D2 07 \
+ 71 B2 77 B9 12 A0 F8 15 1A 00 57 32 0F 87 32 0F \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 \
+ 02 0E 32 00 97 71 CD 32 01 97 71 CD 80 30 87 57 \
+ 06 FC 12 A0 F8 15 1A 00 02 0F 75 DD 90 30 87 57'" # magnum.hex
+
+if $?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC D2 18 71 0E 67 E9 67 D9 77 1A 67 5A \
+ 67 9C 06 FA 67 D0 06 FB 67 D0 06 FC 80 D2 1C 74 \
+ 01 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0D 74 51 3A 68 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 CD 85 77 C7 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 CA 16 FF DA 02 02 FA 71 CA 77 CD 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 C7 06 FC 67 C0 02 FB 75 \
+ C7 32 02 97 71 C7 32 03 97 71 CD 32 04 97 75 CA \
+ 12 A0 F8 15 1A 00 57 42 FF 57 42 FE 57 42 EF 57 \
+ 30 87 98 98 98 98 30 87 57 02 0E 32 00 97 71 E6 \
+ 32 01 97 71 E6 80 30 87 57 06 FC 12 A0 F8 15 1A \
+ 00 02 0F 75 F6 90 30 87 57'" # tuc24_ref.hex
+
+if $?herc8_15 "local ledcode '\
+ 02 01 28 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 \
+ 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 74 22 \
+ 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 87 91 \
+ 74 2B 3A 28'" # sdk5675.hex
+
+if $?drac_any && $?lm "local ledcode '\
+ E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+ 00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+ 75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+ C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+ A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+ C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+ 71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+ 71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57 00 00 00 00 00'" # lm5690.hex
+
+if $?drac_any && $?lm48p "local ledcode '\
+ E0 28 60 C3 67 7C 06 C3 80 28 60 C3 67 7C 67 40 \
+ 06 C3 90 28 60 C3 67 40 06 C3 80 80 D2 0C 74 01 \
+ 12 C2 85 05 D2 0F 71 2A 52 00 12 C1 85 05 D2 1F \
+ 71 34 52 00 12 C0 85 05 D2 05 71 3E 52 00 3A 30 \
+ 32 00 97 75 4C 12 A0 FE C3 02 0A 50 32 01 97 75 \
+ 58 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 6A 85 \
+ 12 A0 FE C3 95 75 B9 85 77 AB 12 A0 FE C3 95 75 \
+ 74 85 77 B2 16 C0 DA 02 71 B2 77 B9 32 05 97 71 \
+ 8C 32 02 97 71 AB 06 C1 D2 01 71 AB 06 C3 67 A4 \
+ 75 AB 32 03 97 71 B9 32 04 97 75 B2 06 C2 D2 07 \
+ 71 B2 77 B9 12 80 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695.hex
+
+if $?drac_any && $?lm48p_B "local ledcode '\
+ E0 28 60 C3 67 79 06 C3 67 3D 06 C3 80 28 60 C3 \
+ 67 3D 06 C3 67 79 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 27 52 00 12 C1 85 05 D2 1F 71 31 52 \
+ 00 12 C0 85 05 D2 05 71 3B 52 00 3A 30 32 00 97 \
+ 75 49 12 A0 FE C3 02 0A 50 32 01 97 75 55 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 67 85 12 A0 FE \
+ C3 95 75 B6 85 77 A8 12 A0 FE C3 95 75 71 85 77 \
+ AF 16 C0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 C1 D2 01 71 A8 06 C3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 C2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695_10.hex
+
+if $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 55 67 91 06 E3 80 28 60 E3 67 91 \
+ 67 55 06 E3 80 D2 18 74 01 28 60 E3 67 B9 75 26 \
+ 67 CE 67 55 77 2E 32 0E 87 32 08 87 67 C0 06 E3 \
+ 80 D2 1C 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 3A 70 32 00 97 75 61 12 A0 FE E3 02 0A \
+ 50 32 01 97 75 6D 12 BC FE E3 02 0A 50 12 BC FE \
+ E3 95 75 7F 85 12 A0 FE E3 95 75 CE 85 77 C0 12 \
+ A0 FE E3 95 75 89 85 77 C7 16 E0 DA 02 71 C7 77 \
+ CE 32 05 97 71 A1 32 02 97 71 C0 06 E1 D2 01 71 \
+ C0 06 E3 67 B9 75 C0 32 03 97 71 CE 32 04 97 75 \
+ C7 06 E2 D2 07 71 C7 77 CE 12 80 F8 15 1A 00 57 \
+ 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F \
+ 87 32 0E 87 57'" # sdk56504.hex
+
+#Led program for new rev of FB SDK and Ref design
+if $?firebolt_any && !$?fb24 "local ledcode '\
+ E0 28 60 E3 67 4B 67 87 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AF 75 1C 67 C4 67 4B 77 24 32 0E 87 32 \
+ 08 87 67 B6 06 E3 80 D2 1C 74 0F 12 E2 85 05 D2 \
+ 0F 71 35 52 00 12 E1 85 05 D2 1F 71 3F 52 00 12 \
+ E0 85 05 D2 05 71 49 52 00 3A 70 32 00 97 75 57 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 63 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 75 85 12 A0 FE E3 95 \
+ 75 C4 85 77 B6 12 A0 FE E3 95 75 7F 85 77 BD 16 \
+ E0 DA 02 71 BD 77 C4 32 05 97 71 97 32 02 97 71 \
+ B6 06 E1 D2 01 71 B6 06 E3 67 AF 75 B6 32 03 97 \
+ 71 C4 32 04 97 75 BD 06 E2 D2 07 71 BD 77 C4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56504ref.hex
+
+#Override Default Firebolt LED program for Line Module
+if $?lm && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 79 06 E3 67 3D 06 E3 80 28 60 E3 \
+ 67 3D 06 E3 67 79 06 E3 80 D2 18 74 01 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 60 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B6 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AF 16 E0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 E2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p56504.hex
+
+#Override Default Firebolt LED program for Line Module -50 version
+if $?lm && $?lm48p_D && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 6D 06 E3 67 31 06 E3 80 D2 18 74 \
+ 01 12 E2 85 05 D2 0F 71 1B 52 00 12 E1 85 05 D2 \
+ 1F 71 25 52 00 12 E0 85 05 D2 05 71 2F 52 00 3A \
+ 60 32 00 97 75 3D 12 A0 FE E3 02 0A 50 32 01 97 \
+ 75 49 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 5B \
+ 85 12 A0 FE E3 95 75 AA 85 77 9C 12 A0 FE E3 95 \
+ 75 65 85 77 A3 16 E0 DA 02 71 A3 77 AA 32 05 97 \
+ 71 7D 32 02 97 71 9C 06 E1 D2 01 71 9C 06 E3 67 \
+ 95 75 9C 32 03 97 71 AA 32 04 97 75 A3 06 E2 D2 \
+ 07 71 A3 77 AA 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # lm48p56504_50.hex
+
+if $?lm && $?firebolt_10x4 "local ledcode '\
+ 02 18 28 32 07 67 1E 75 0A D7 87 32 01 D7 87 32 \
+ 00 D7 87 32 08 D7 87 80 D2 1C 74 02 3A 0C 12 80 \
+ F8 15 1A 00 57 '" # lm12pcx456501.hex
+
+if $?fbpoe && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 85 67 49 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AD 75 1A 67 C2 77 20 32 0E 87 32 08 87 \
+ 67 49 06 E3 80 D2 1A 74 0F 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 32 00 97 75 55 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 61 12 BA FE E3 02 0A \
+ 50 12 BA FE E3 95 75 73 85 12 A0 FE E3 95 75 C2 \
+ 85 77 B4 12 A0 FE E3 95 75 7D 85 77 BB 16 E0 DA \
+ 02 71 BB 77 C2 32 05 97 71 95 32 02 97 71 B4 06 \
+ E1 D2 01 71 B4 06 E3 67 AD 75 B4 32 03 97 71 C2 \
+ 32 04 97 75 BB 06 E2 D2 07 71 BB 77 C2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # poe48p56504.hex
+
+#Override Default Firebolt LED program for felix
+if $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0E 87 32 0F 87 57'" # sdk56102.hex
+
+#Override Default Felix LED program for felix48
+if $?felix48 && $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # felix48.hex
+
+if $?easyrider_any "local ledcode '\
+ E0 28 60 E3 67 59 67 95 06 E3 80 28 60 E3 67 95 \
+ 67 59 06 E3 80 D2 0C 74 01 28 60 E3 67 BD 75 26 \
+ 67 D2 67 59 77 2E 32 0E 87 32 08 87 67 C4 06 E3 \
+ 80 D2 0D 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 67 C4 67 C4 3A 38 32 00 97 75 65 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 71 12 AD FE E3 02 0A \
+ 50 12 AD FE E3 95 75 83 85 12 A0 FE E3 95 75 D2 \
+ 85 77 C4 12 A0 FE E3 95 75 8D 85 77 CB 16 E0 DA \
+ 02 71 CB 77 D2 32 05 97 71 A5 32 02 97 71 C4 06 \
+ E1 D2 01 71 C4 06 E3 67 BD 75 C4 32 03 97 71 D2 \
+ 32 04 97 75 CB 06 E2 D2 07 71 CB 77 D2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # sdk56601.hex
+
+#Override Default Easyrider LED program for 56602
+if $?easyrider_1x1 "local ledcode '\
+ E0 60 E1 67 7C 67 7C 06 E1 80 D2 0C 74 01 02 0C \
+ 28 60 E1 67 75 75 1D 67 8A 67 39 77 25 32 0E 87 \
+ 32 08 87 67 7C 06 E1 D2 00 02 00 74 10 12 E0 85 \
+ 05 D2 05 71 37 52 00 3A 38 32 00 97 75 45 12 A0 \
+ FE E1 02 0A 50 32 01 97 75 51 12 AD FE E1 02 0A \
+ 50 12 AD FE E1 95 75 63 85 12 A0 FE E1 95 75 8A \
+ 85 77 7C 12 A0 FE E1 95 75 6D 85 77 83 16 E0 DA \
+ 02 71 83 77 8A 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # sdk56602.hex
+
+#Override Default LED program for 53300
+if $?mirage24 "local ledcode '\
+ E0 28 60 E3 67 6B 67 2F 06 E3 80 D2 18 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A2 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 9E 16 E0 DA 02 71 9E 77 A2 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A2 32 04 97 75 9E 06 E2 D2 07 71 \
+ 9E 77 A2 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E \
+ 87 57 32 0E 87 57'" # sdk53300.hex
+
+#Override Default LED program for 56314
+if $?bcm56314p24ref "local ledcode '\
+ E0 28 60 E3 67 79 67 3D 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 79 67 A8 06 E3 80 D2 1C 74 0F 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 38 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B0 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AC 16 E0 DA 02 71 AC 77 B0 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B0 32 04 97 75 AC 06 E2 D2 07 71 AC 77 \
+ B0 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ 32 0E 87 57'" # bcm956314p24ref.hex
+
+if $?bradley "local ledcode '\
+ E0 28 60 F2 67 1B 06 F2 80 D2 14 74 01 86 F3 12 \
+ F0 85 05 D2 05 71 19 52 00 3A 28 32 00 97 75 27 \
+ 12 A8 FE F2 02 0A 50 32 01 97 75 33 12 BC FE F2 \
+ 02 0A 50 12 BC FE F2 95 75 45 85 12 A8 FE F2 95 \
+ 75 91 85 77 57 12 A8 FE F2 95 75 4F 85 77 8A 16 \
+ F0 DA 02 71 8A 77 91 06 F2 12 94 F8 15 02 02 C1 \
+ 74 6E 02 04 C1 74 6E 02 08 C1 74 6E 77 74 C6 F3 \
+ 74 91 77 8A 06 F2 67 7C 75 83 77 91 12 80 F8 15 \
+ 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 \
+ 57 32 0F 87 32 0E 87 57'" # sdk56800.hex
+
+if $?humv "local ledcode '\
+ E0 28 60 F2 67 21 06 F2 80 D2 08 74 0F F2 02 D2 \
+ 12 74 01 86 F3 12 F0 85 05 D2 05 71 1F 52 00 3A \
+ 20 32 00 97 75 2D 12 A8 FE F2 02 0A 50 32 01 97 \
+ 75 39 12 BA FE F2 02 0A 50 12 BA FE F2 95 75 4B \
+ 85 12 A8 FE F2 95 75 97 85 77 5D 12 A8 FE F2 95 \
+ 75 55 85 77 90 16 F0 DA 02 71 90 77 97 06 F2 12 \
+ 94 F8 15 02 02 C1 74 74 02 04 C1 74 74 02 08 C1 \
+ 74 74 77 7A C6 F3 74 97 77 90 06 F2 67 82 75 89 \
+ 77 97 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56700.hex
+
+if $?bradley_1g "local ledcode '\
+ E0 28 60 E3 67 2F 67 6B 06 E3 80 D2 14 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 50 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 B4 FE E3 02 0A 50 12 B4 FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A8 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 A1 16 E0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 E2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 '" # sdk56800c.hex
+
+if $?goldwing "local ledcode '\
+ E0 28 60 F3 D2 10 75 0E 67 3B 67 94 77 12 67 94 \
+ 67 3B 06 F3 80 D2 14 74 01 86 F4 12 F2 85 05 D2 \
+ 0F 71 25 52 00 12 F1 85 05 D2 1F 71 2F 52 00 12 \
+ F0 85 05 D2 05 71 39 52 00 3A 50 32 00 97 75 47 \
+ 12 A8 FE F3 02 0A 50 32 01 97 75 53 12 BC FE F3 \
+ 02 0A 50 12 BC FE F3 95 75 65 85 12 A8 FE F3 95 \
+ 75 C0 85 77 77 12 A8 FE F3 95 75 6F 85 77 B9 16 \
+ F0 DA 02 71 B9 77 C0 06 F3 12 94 F8 15 02 02 C1 \
+ 74 8E 02 04 C1 74 8E 02 08 C1 74 8E 77 B2 C6 F4 \
+ 74 C0 77 B9 06 F3 67 AB 75 B2 32 04 75 B2 32 03 \
+ 97 71 C0 06 F2 D2 07 71 B9 77 C0 12 80 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 '" # sdk56580.hex
+
+if $?humv && $?lm "local ledcode '\
+ 02 04 28 D2 08 74 0A F2 02 28 32 07 67 29 75 11 \
+ D7 87 60 E4 67 30 06 E4 60 E4 67 4C 06 E4 32 08 \
+ D7 87 80 D2 12 74 02 3A 30 12 80 F8 15 1A 00 57 \
+ 06 E4 12 94 F8 15 02 10 C1 70 42 12 D2 FE E4 02 \
+ 0A 50 12 D2 FE E4 95 75 6D 85 77 68 06 E4 12 94 \
+ F8 15 02 20 C1 70 5E 12 C0 FE E4 02 0A 50 12 C0 \
+ FE E4 95 75 6D 85 77 68 32 0E D7 87 57 32 0F D7 \
+ 87 57 '" # lm12p56802.hex
+
+
+if $?raptor "local ledcode '\
+ 02 06 28 60 FF 67 64 67 93 06 FF 80 D2 36 74 02 \
+ 02 04 28 60 FF 67 BB 75 1E 32 0E 87 77 21 32 0F \
+ 87 67 7D 06 FF 80 D2 06 74 12 02 01 28 60 FF 67 \
+ BB 75 38 32 0E 87 77 3B 32 0F 87 67 7D 06 FF 80 \
+ D2 03 74 2C 12 FE 85 05 D2 0F 71 4E 52 00 12 FD \
+ 85 05 D2 1F 71 58 52 00 12 FC 85 05 D2 05 71 62 \
+ 52 00 3A C8 32 01 97 75 76 32 00 97 75 C9 16 FC \
+ DA 02 71 C9 77 D0 32 00 97 75 C2 77 D0 32 00 97 \
+ 75 86 32 0E 87 57 32 01 97 75 8F 32 0E 87 57 32 \
+ 0F 87 57 32 05 97 71 A3 32 02 97 71 C2 06 FD D2 \
+ 01 71 C2 06 FF 67 BB 75 C2 32 03 97 71 D0 32 04 \
+ 97 75 C9 06 FE D2 07 71 C9 77 D0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" # sdk56018.hex
+
+if $?raptor && $?rap24_ref "local ledcode '\
+ 02 06 60 E1 67 48 67 31 06 E1 80 D2 1E 71 02 02 \
+ 05 60 E1 67 48 67 31 06 E1 90 D2 03 74 11 02 02 \
+ 60 E1 67 48 67 31 06 E1 90 D2 00 74 20 86 E0 3A \
+ 38 06 E1 67 50 75 57 28 32 00 32 01 B7 97 75 57 \
+ 16 E0 CA 05 74 5B 77 57 06 E1 67 50 75 57 77 5B \
+ 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00'" # sdk56214.hex
+
+if $?raven_eb_48p "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 71 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024p48ref.hex
+
+if $?BCM956024R50T "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 75 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024r50t.hex
+
+if $?scorpion || $?conqueror "local ledcode '\
+ 02 18 28 60 E1 67 12 06 E1 90 D2 00 74 02 86 E0 \
+ 3A 18 67 2D 75 34 28 32 00 32 01 B7 97 75 38 16 \
+ E0 CA 05 74 38 77 34 67 2D 75 34 77 38 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 \
+ 00 00 00'" #sdk56820.hex
+
+if $?scorpion && $?BCM956820R24XG "local ledcode '\
+ 02 01 28 67 D0 02 02 28 67 D6 67 D0 02 01 28 67 \
+ D6 02 04 28 67 D0 02 03 28 67 D6 67 D0 02 04 28 \
+ 67 D6 02 05 28 67 D0 02 06 28 67 D6 67 D0 02 05 \
+ 28 67 D6 02 07 28 67 D0 02 08 28 67 D6 67 D0 02 \
+ 07 28 67 D6 02 09 28 67 D0 02 0A 28 67 D6 67 D0 \
+ 02 09 28 67 D6 02 0C 28 67 D0 02 0B 28 67 D6 67 \
+ D0 02 0C 28 67 D6 02 0D 28 67 D0 02 0E 28 67 D6 \
+ 67 D0 02 0D 28 67 D6 02 0F 28 67 D0 02 10 28 67 \
+ D6 67 D0 02 0F 28 67 D6 02 11 28 67 D0 02 12 28 \
+ 67 D6 67 D0 02 11 28 67 D6 02 14 28 67 D0 02 13 \
+ 28 67 D6 67 D0 02 14 28 67 D6 02 15 28 67 D0 02 \
+ 16 28 67 D6 67 D0 02 15 28 67 D6 02 17 28 67 D0 \
+ 02 18 28 67 D6 67 D0 02 17 28 67 D6 86 E0 3A 30 \
+ 67 F1 75 F8 77 FC 67 F1 75 F8 28 32 00 32 01 B7 \
+ 97 75 F8 16 E0 CA 05 74 FC 77 F8 67 F1 75 F8 77 \
+ FC 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ '" #bcm956820r24xg.hex
+
+if $?valkyrie "local ledcode '\
+ 02 02 67 A9 67 94 02 03 67 A9 67 94 02 05 67 A9 \
+ 67 94 02 04 67 A9 67 94 02 06 67 A9 67 94 02 07 \
+ 67 A9 67 94 02 12 67 A9 67 94 02 13 67 A9 67 94 \
+ 02 0E 67 A9 67 94 02 0F 67 A9 67 94 02 11 67 A9 \
+ 67 94 02 10 67 A9 67 94 02 1A 67 A9 67 94 02 20 \
+ 67 A9 67 94 02 21 67 A9 67 94 02 22 67 A9 67 94 \
+ 02 23 67 A9 67 94 02 24 67 A9 67 94 02 2F 67 A9 \
+ 67 94 02 2E 67 A9 67 94 02 1B 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56680.hex
+
+if $?valkyrie2 "local ledcode '\
+ 02 1E 67 A9 67 94 02 1F 67 A9 67 94 02 21 67 A9 \
+ 67 94 02 20 67 A9 67 94 02 22 67 A9 67 94 02 23 \
+ 67 A9 67 94 02 24 67 A9 67 94 02 25 67 A9 67 94 \
+ 02 26 67 A9 67 94 02 27 67 A9 67 94 02 29 67 A9 \
+ 67 94 02 28 67 A9 67 94 02 2A 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 02 2E 67 A9 67 94 02 2F 67 A9 67 94 02 31 67 A9 \
+ 67 94 02 30 67 A9 67 94 02 32 67 A9 67 94 02 33 \
+ 67 A9 67 94 02 34 67 A9 67 94 02 35 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56685.hex
+
+if $?hawkeye_p24 "local ledcode '\
+ 02 01 28 60 E3 67 43 67 1C 06 E3 80 D2 19 74 02 \
+ 12 E0 85 05 D2 03 71 1A 52 00 3A 60 32 00 32 01 \
+ B7 97 75 2B 12 E4 FE E3 02 01 50 12 E4 FE E3 95 \
+ 75 3B 85 06 E3 67 55 75 6A 77 5C 16 E0 DA 01 71 \
+ 6A 77 5C 06 E3 67 55 75 6A 32 03 97 71 5C 32 04 \
+ 97 75 6A 77 63 12 A0 F8 15 1A 00 57 32 0E 87 32 \
+ 0F 87 57 32 0F 87 32 0E 87 57 32 0F 87 32 0F 87 \
+ 57'" #bcm953314p24ref.hex
+
+if $?hawkeye_k24 "local ledcode '\
+ 02 01 28 60 E1 67 3D 67 1C 06 E1 80 D2 19 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 30 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 50 16 E0 DA 02 71 4C 77 50 06 E1 67 \
+ 45 75 50 77 4C 12 A0 F8 15 1A 00 57 32 0E 87 57 \
+ 32 0F 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #bcm953314k24.hex
+
+if !"expr $pcidev + 0 == 0xb624" "local ledcode '\
+ 02 1C 28 67 18 02 1D 28 67 18 02 1E 28 67 18 02 \
+ 1F 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56624.hex
+
+if !"expr $pcidev + 0 == 0xb626" "local ledcode '\
+ 02 1A 28 67 22 02 1B 28 67 22 02 1C 28 67 22 02 \
+ 1D 28 67 22 02 1E 28 67 22 02 1F 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56626.hex
+
+if !"expr $pcidev + 0 == 0xb628" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56628.hex
+
+if !"expr $pcidev + 0 == 0xb629" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56629.hex
+
+if !"expr $pcidev + 0 == 0xb634" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb630" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb636" "local ledcode '\
+ 02 2A 28 67 22 02 32 28 67 22 02 1A 28 67 22 02 \
+ 1B 28 67 22 02 1C 28 67 22 02 1D 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56636.hex
+
+if !"expr $pcidev + 0 == 0xb638" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56638.hex
+
+if !"expr $pcidev + 0 == 0xb639" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56639.hex
+
+if !"expr $pcidev + 0 == 0xb334" "local ledcode '\
+ 02 02 28 60 E1 67 3D 67 1C 06 E1 80 D2 1E 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 38 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 4C 16 E0 DA 02 71 50 77 4C 06 E1 67 \
+ 45 75 4C 77 50 12 A0 F8 15 1A 00 57 32 0F 87 57 \
+ 32 0E 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #sdk56334.hex
+
+if $?apollo "local ledcode '\
+ 02 1E 28 60 E0 67 58 67 73 06 E0 80 28 60 E0 67 \
+ 73 67 58 06 E0 80 D2 36 74 02 02 1A 28 60 E0 67 \
+ 9B 75 29 67 B0 67 58 77 31 32 0E 87 32 08 87 67 \
+ A2 06 E0 80 D2 1E 74 1C 12 E2 85 05 D2 0F 71 42 \
+ 52 00 12 E1 85 05 D2 1F 71 4C 52 00 12 E3 85 05 \
+ D2 05 71 56 52 00 3A 70 32 00 97 75 64 32 01 97 \
+ 71 6B 77 B0 32 01 97 71 A9 77 A2 16 E3 DA 02 71 \
+ A9 77 B0 32 05 97 75 83 32 02 97 71 A2 06 E1 D2 \
+ 01 71 A2 06 E0 67 9B 75 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 E2 D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" #sdk56524.hex
+
+if $?tomahawk "local ledcode '\
+ 02 00 28 60 E1 67 25 67 14 06 E1 80 D2 40 74 02 \
+ 86 E0 3A FC 28 32 00 32 01 B7 97 75 37 16 E0 CA \
+ 05 74 3E 77 37 67 2B 75 37 77 45 12 A0 F8 15 1A \
+ 00 57 28 32 07 97 57 32 0E 87 32 0E 87 57 32 0F \
+ 87 32 0E 87 57 32 0E 87 32 0F 87 57 00 00 00 00'" #sdk56960.hex
+
+if $?trident2plus "local ledcode '\
+ 02 01 28 60 E1 67 31 67 20 06 E1 80 D2 31 74 02 \
+ 86 E0 3A C0 67 37 75 1C 67 51 77 20 67 43 77 43 \
+ 28 32 00 32 01 B7 97 75 43 16 E0 CA 05 74 4A 77 \
+ 43 67 37 75 43 77 51 12 A0 F8 15 1A 00 57 28 32 \
+ 07 97 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00'" #sdk56860.hex
+
+if $?apache "local ledcode '\
+ 02 00 67 24 67 0F 80 D2 24 74 02 86 E0 3A F8 67 \
+ 34 75 16 77 1D 57 67 3C 75 62 77 44 57 67 3C 75 \
+ 4E 77 58 57 67 2C 75 62 77 70 07 57 07 12 A0 F8 \
+ 15 1A 00 57 07 12 A0 F8 15 1A 04 57 07 12 A0 F8 \
+ 15 1A 05 57 16 E0 CA 1E 74 69 77 62 07 57 16 E0 \
+ CA 1E 74 70 77 62 07 57 16 E0 CA 1E 74 69 77 70 \
+ 07 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00 00'" #sdk56560.hex
+
+if $?generic8led "local ledcode '\
+ 06 E1 D2 40 71 11 E0 60 E1 16 E3 DA 01 71 15 60 \
+ E3 67 5D 75 2B 12 01 61 E3 67 71 28 67 32 86 E0 \
+ 16 E2 81 61 E2 DA 1E 75 2B 3A 08 E9 61 E2 86 E1 \
+ 77 00 67 5D 75 38 77 3C 67 64 77 64 67 41 67 4F \
+ 57 28 32 01 97 75 64 16 E0 CA 05 74 68 77 64 28 \
+ 32 00 97 75 64 16 E0 CA 05 74 68 77 64 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 09 75 64 77 \
+ 68 12 05 67 6C 12 04 67 6C 12 03 67 6C 12 02 67 \
+ 6C 12 01 67 6C 12 00 67 6C 57 00 00 00 00 00 00'" #generic8led.hex
+
+# Download LED code into LED processor and enable (if applicable).
+
+if $?feature_led_proc && $?ledcode && !$?simulator \
+ "led prog $ledcode; \
+ led auto on; led start"
+
+# Setup Greyhound LED processor
+if $?greyhound \
+ "rcload gh_ledup.soc"
+
+# Setup Hurricane3 LED processor
+if $?hurricane3 \
+ "rcload hr3_led.soc"
+
+# Setup Tomahawk LED processor
+if $?tomahawk && !$?simulator \
+ "led 1 prog $ledcode; \
+ led 1 auto on; led 1 start; \
+ led 2 prog $ledcode; \
+ led 2 auto on; led 2 start"
+
+# If loading multiple rc.soc, upon loading the last unit, restart
+# all LED processors so any common blinking is in sync.
+
+if !"expr $?feature_led_proc && !$?simulator && $unit == $units - 1" \
+ "*:led stop; *:led start"
+
+# Run counter DMA task 4 times per second to achieve better
+# ctr_xaui_activity.
+if $?bradley_any \
+ "ctr interval=250000"
+
+# Initialize Hercules UC modid 0 entry to point to the CPU
+if $?herc_any \
+ "w uc 0 1 1"
+
+# Additional configuration for 48-port in Stacking mode.
+# On the 48-port platform, rc.soc is run twice; once on unit 0 and
+# then once on unit 1. The turbo port on unit N is geN.
+# All turbo port traffic must be tagged; see vlan add below.
+# See $SDK/doc/48-port.txt for more information including how
+# to configure IPG values for line rate operation.
+
+if $?p48 && $?unit0 \
+ "local turbo_port 0; local my_modid 1;"
+
+if $?p48 && $?unit1 \
+ "local turbo_port 1; local my_modid 2;"
+
+if $?p48 \
+ "m config st_is_mirr=0 st_module=1 st_mcnt=1 st_simplex=0 st_link=0; \
+ m config.g$turbo_port st_link=1; \
+ m gmacc2.ge$turbo_port ipgt=8 mclkfq=1; \
+ m fe_maxf maxfr=1560; \
+ m maxfr maxfr=1568; \
+ m config2 my_modid=$my_modid; \
+ port ge$turbo_port speed=2500; \
+ vlan add 1 pbm=ge$turbo_port ubm=none"
+
+if !$?no_bcm && $?drac_any \
+ "m modport_7_0 port_for_mod1=0xc"
+if !$?no_bcm && $?lynx_any \
+ "m modport_7_0 port_for_mod1=0x1"
+if !$?no_bcm && $?tucana \
+ "stkmode modid=0;"
+if !$?no_bcm && $?tucana && !$?magnum && !$?tucana_nohg \
+ "m modport_7_0 port_for_mod2=0x38; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=0 port_for_mod2=0x38; \
+ stkmode modid=0"
+if !$?no_bcm && $?xgs_switch && !$?rcpu_only\
+ "stkmode modid=0; \
+ s CMIC_COS_CTRL_RX CH0_COS_BMP=0,CH1_COS_BMP=0xff, \
+ CH2_COS_BMP=0,CH3_COS_BMP=0"
+
+# Back-to-back Draco setup.
+
+# Draco chips must run at 127MHz. Some older versions
+# are not set to this frequency.
+
+if $?draco_stk && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+# Applies to SDK Baseboard with either internal or external Higigs,
+# as well as the Galahad reference design.
+
+if $?draco_b2b && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if !$?simulator && $?draco_b2b && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_b2b && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Merlin, White Knight, Black Knight setup.
+# Draco unit 1 is on Herc port 8
+# Draco unit 2 is on Herc port 1
+
+if $?draco_herc4 && $?unit0 \
+ "w uc.hpic7 0 1 0x0; \
+ w uc.hpic7 1 1 0x2; \
+ w uc.hpic0 0 1 0x100; \
+ w uc.hpic0 1 1 0x0"
+
+if !$?simulator && $?draco_herc4 && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_herc4 && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if $?draco_herc4 && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Lancelot setup
+# (enabled by adding the property "lancelot=1")
+# Notes:
+# Draco unit 1 is on Herc port 7
+# Draco unit 2 is on Herc port 8
+# Draco unit 3 is on Herc port 1
+# Draco unit 4 is on Herc port 2
+
+if $?lancelot && $?unit0 \
+ "w uc.hpic6 0 1 0x0; \
+ w uc.hpic6 1 1 0x100; \
+ w uc.hpic6 2 1 0x2; \
+ w uc.hpic6 3 1 0x4; \
+ w uc.hpic7 0 1 0x80; \
+ w uc.hpic7 1 1 0x0; \
+ w uc.hpic7 2 1 0x2; \
+ w uc.hpic7 3 1 0x4; \
+ w uc.hpic0 0 1 0x80; \
+ w uc.hpic0 1 1 0x100; \
+ w uc.hpic0 2 1 0x0; \
+ w uc.hpic0 3 1 0x4; \
+ w uc.hpic1 0 1 0x80; \
+ w uc.hpic1 1 1 0x100; \
+ w uc.hpic1 2 1 0x2; \
+ w uc.hpic1 3 1 0x0"
+
+if !$?simulator && $?lancelot && $?unit0 \
+ "i2c probe quiet; bb clock Draco_Core 127"
+
+if $?lancelot && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit3 \
+ "stkmode modid=2; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12"
+
+if $?lancelot && $?unit4 \
+ "stkmode modid=3; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0"
+
+# Lynx SDK (TwoLynx) setup
+# (enabled by adding the property "twolynx=1")
+
+if $?twolynx && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ "
+
+if $?twolynx && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ "
+# HercuLynx setup
+# (enabled by adding the property "herculynx=1")
+# Notes:
+# Lynx unit 1 is on Herc port 1
+# Lynx unit 2 is on Herc port 2
+# Lynx unit 3 is on Herc port 3
+# Lynx unit 4 is on Herc port 4
+# Lynx unit 5 is on Herc port 5
+# Lynx unit 6 is on Herc port 6
+# Lynx unit 7 is on Herc port 7
+# Lynx unit 8 is on Herc port 8
+
+if $?herculynx && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x008; \
+ w uc.hpic0 3 1 0x010; \
+ w uc.hpic0 4 1 0x020; \
+ w uc.hpic0 5 1 0x040; \
+ w uc.hpic0 6 1 0x080; \
+ w uc.hpic0 7 1 0x100; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x008; \
+ w uc.hpic1 3 1 0x010; \
+ w uc.hpic1 4 1 0x020; \
+ w uc.hpic1 5 1 0x040; \
+ w uc.hpic1 6 1 0x080; \
+ w uc.hpic1 7 1 0x100; \
+ ; \
+ w uc.hpic2 0 1 0x002; \
+ w uc.hpic2 1 1 0x004; \
+ w uc.hpic2 2 1 0x008; \
+ w uc.hpic2 3 1 0x010; \
+ w uc.hpic2 4 1 0x020; \
+ w uc.hpic2 5 1 0x040; \
+ w uc.hpic2 6 1 0x080; \
+ w uc.hpic2 7 1 0x100; \
+ ; \
+ w uc.hpic3 0 1 0x002; \
+ w uc.hpic3 1 1 0x004; \
+ w uc.hpic3 2 1 0x008; \
+ w uc.hpic3 3 1 0x010; \
+ w uc.hpic3 4 1 0x020; \
+ w uc.hpic3 5 1 0x040; \
+ w uc.hpic3 6 1 0x080; \
+ w uc.hpic3 7 1 0x100; \
+ ; \
+ w uc.hpic4 0 1 0x002; \
+ w uc.hpic4 1 1 0x004; \
+ w uc.hpic4 2 1 0x008; \
+ w uc.hpic4 3 1 0x010; \
+ w uc.hpic4 4 1 0x020; \
+ w uc.hpic4 5 1 0x040; \
+ w uc.hpic4 6 1 0x080; \
+ w uc.hpic4 7 1 0x100; \
+ ; \
+ w uc.hpic5 0 1 0x002; \
+ w uc.hpic5 1 1 0x004; \
+ w uc.hpic5 2 1 0x008; \
+ w uc.hpic5 3 1 0x010; \
+ w uc.hpic5 4 1 0x020; \
+ w uc.hpic5 5 1 0x040; \
+ w uc.hpic5 6 1 0x080; \
+ w uc.hpic5 7 1 0x100; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x008; \
+ w uc.hpic6 3 1 0x010; \
+ w uc.hpic6 4 1 0x020; \
+ w uc.hpic6 5 1 0x040; \
+ w uc.hpic6 6 1 0x080; \
+ w uc.hpic6 7 1 0x100; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x008; \
+ w uc.hpic7 3 1 0x010; \
+ w uc.hpic7 4 1 0x020; \
+ w uc.hpic7 5 1 0x040; \
+ w uc.hpic7 6 1 0x080; \
+ w uc.hpic7 7 1 0x100; \
+ ; \
+ "
+
+if $?herculynx && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?herculynx && $?unit1 \
+ "stkmode modid=0"
+
+if $?herculynx && $?unit2 \
+ "stkmode modid=1"
+
+if $?herculynx && $?unit3 \
+ "stkmode modid=2"
+
+if $?herculynx && $?unit4 \
+ "stkmode modid=3"
+
+if $?herculynx && $?unit5 \
+ "stkmode modid=4"
+
+if $?herculynx && $?unit6 \
+ "stkmode modid=5"
+
+if $?herculynx && $?unit7 \
+ "stkmode modid=6"
+
+if $?herculynx && $?unit8 \
+ "stkmode modid=7"
+
+# LynxaLot setup
+# (enabled by adding the property "lynxalot=1")
+# Notes:
+# Lynx unit 0 is on Herc port 3 (hg2/hpic2) (mod 0)
+# Lynx unit 1 is on Herc port 4 (hg3/hpic3) (mod 1)
+# Higig conn 0 is on Herc port 5 (hg4/hpic4)
+# Higig conn 1 is on Herc port 6 (hg5/hpic5)
+# Draco unit 3 is on Herc port 7 (hg6/hpic6) (mod 2)
+# Draco unit 4 is on Herc port 8 (hg7/hpic7) (mod 3)
+# Draco unit 5 is on Herc port 1 (hg0/hpic0) (mod 4)
+# Draco unit 6 is on Herc port 2 (hg1/hpic1) (mod 5)
+
+if $?lynxalot && $?unit2 \
+ " \
+ w uc.hpic0 0 1 0x008; \
+ w uc.hpic0 1 1 0x010; \
+ w uc.hpic0 2 1 0x080; \
+ w uc.hpic0 3 1 0x100; \
+ w uc.hpic0 4 1 0x002; \
+ w uc.hpic0 5 1 0x004; \
+ ; \
+ w uc.hpic1 0 1 0x008; \
+ w uc.hpic1 1 1 0x010; \
+ w uc.hpic1 2 1 0x080; \
+ w uc.hpic1 3 1 0x100; \
+ w uc.hpic1 4 1 0x002; \
+ w uc.hpic1 5 1 0x004; \
+ ; \
+ w uc.hpic2 0 1 0x008; \
+ w uc.hpic2 1 1 0x010; \
+ w uc.hpic2 2 1 0x080; \
+ w uc.hpic2 3 1 0x100; \
+ w uc.hpic2 4 1 0x002; \
+ w uc.hpic2 5 1 0x004; \
+ ; \
+ w uc.hpic3 0 1 0x008; \
+ w uc.hpic3 1 1 0x010; \
+ w uc.hpic3 2 1 0x080; \
+ w uc.hpic3 3 1 0x100; \
+ w uc.hpic3 4 1 0x002; \
+ w uc.hpic3 5 1 0x004; \
+ ; \
+ w uc.hpic6 0 1 0x008; \
+ w uc.hpic6 1 1 0x010; \
+ w uc.hpic6 2 1 0x080; \
+ w uc.hpic6 3 1 0x100; \
+ w uc.hpic6 4 1 0x002; \
+ w uc.hpic6 5 1 0x004; \
+ ; \
+ w uc.hpic7 0 1 0x008; \
+ w uc.hpic7 1 1 0x010; \
+ w uc.hpic7 2 1 0x080; \
+ w uc.hpic7 3 1 0x100; \
+ w uc.hpic7 4 1 0x002; \
+ w uc.hpic7 5 1 0x004; \
+ ; \
+ "
+
+if $?lynxalot && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?lynxalot && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?lynxalot && $?unit0 \
+ "stkmode modid=0"
+
+if $?lynxalot && $?unit1 \
+ "stkmode modid=1"
+
+if $?lynxalot && $?unit3 \
+ "stkmode modid=2"
+
+if $?lynxalot && $?unit4 \
+ "stkmode modid=3"
+
+if $?lynxalot && $?unit5 \
+ "stkmode modid=4"
+
+if $?lynxalot && $?unit6 \
+ "stkmode modid=5"
+
+# guenevere setup
+# (enabled by adding the property "guenevere=1")
+# Notes:
+# hgX mapping based on pbmp_valid.0=0x1b7
+# Draco unit 1 is on Herc port 1 (hg0/hpic0) (mod 0)
+# Draco unit 2 is on Herc port 2 (hg1/hpic1) (mod 1)
+# Lynx unit 3 is on Herc port 8 (hg5/hpic7) (mod 2)
+# Lynx unit 4 is on Herc port 7 (hg4/hpic6) (mod 3)
+# Higig conn 0 is on Herc port 4 (hg2/hpic3)
+# Higig conn 1 is on Herc port 5 (hg3/hpic4)
+# Herc port 3 - Unused (hpic2)
+# Herc port 6 - Unused (hpic5)
+if $?guenevere && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x100; \
+ w uc.hpic0 3 1 0x080; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x100; \
+ w uc.hpic1 3 1 0x080; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x100; \
+ w uc.hpic7 3 1 0x080; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x100; \
+ w uc.hpic6 3 1 0x080; \
+ ; \
+ "
+
+if $?guenevere && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?guenevere && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?guenevere && $?unit1 \
+ "stkmode modid=0"
+
+if $?guenevere && $?unit2 \
+ "stkmode modid=1"
+
+if $?guenevere && $?unit3 \
+ "stkmode modid=2"
+
+if $?guenevere && $?unit4 \
+ "stkmode modid=3"
+
+# felix48 setup
+# (enabled by adding the property "felix48=1")
+# Notes:
+# BCM56102 unit-0 higig port (port 26) is connected
+# to BCM56102 Unit-1 higig port (port 26)
+#
+
+if $?felix48 && $?unit0 \
+ "stkmode modid=0 ; \
+ m IEGR_PORT MY_MODID=0; \
+ m XPORT_CONFIG MY_MODID=0; \
+ w MODPORT_MAP 1 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+
+if $?felix48 && $?unit1 \
+ "stkmode modid=1 ; \
+ m IEGR_PORT MY_MODID=1; \
+ m XPORT_CONFIG MY_MODID=1; \
+ w MODPORT_MAP 0 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+# fbpoe setup
+# (enabled by adding the property "fbpoe=1")
+# Notes:
+# BCM56504 unit-0 higig port (port 27,28) is connected
+# to BCM56504 Unit-1 higig port (port 27,28)
+#
+
+if $?unit0 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+if $?unit1 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+# Dual Raptor/Raven boards
+if $?raven_eb_48p || $?rap24_ref \
+ "local rcpu_system 1"
+if $?unit0 && $?rcpu_system \
+ "stkmode modid=0"
+if $?unit1 && $?rcpu_system \
+ "stkmode modid=1"
+
+# LM fb48 platform setup
+# (enabled by adding the property "lm48p=1")
+#
+if $?unit0 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=0"
+
+if $?unit1 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=1"
+
+# Set Firebolt POE power level 170(total) - 110(switch) = 60
+if $?fbpoe \
+ "local poepower 60"
+
+# Set Draco15 POE power level 170(total) - 80(switch) = 90
+if $?drac15\
+ "local poepower 90"
+
+# Hurricane3 BCM956160R setup
+# Notes:
+# BCM56160 unit-0 higig port (port 29,30) is connected
+# to BCM56160 Unit-1 higig port (port 26,27)
+#
+
+if $?bcm956160r && $?unit0 \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x60000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+if $?bcm956160r && $?unit1 \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0xc000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+# if enable_poe is set, then enable the POE processor for
+# either Firebolt or Draco15 platform
+if $?unit0 && $?enable_poe && $?fbpoe || $?drac15 \
+ "$echo rc: Enabling POE ...; \
+ poesel reset; \
+ i2c probe quiet; \
+ xpoe verbose off; \
+ xpoe power $poepower; \
+ xpoe verbose on; \
+ poesel enable"
+
+# mark this unit so that subsequent rc runs are quiet
+setenv rc$unit 1
+
+if $?macsec '\
+ macsec sync; \
+ $echo "rc: MACSEC CLI Enabled"'
+
+# cache a copy of rc.soc in memory
+rccache addq rc.soc
+
+# setup chassis if requested
+if !"expr $?autochassis2 && $unit == $units - 1" \
+ "setenv chassis2_no_rc 1; \
+ rcload c2switch.soc; \
+ setenv chassis2_no_rc; \
+ "
+
+# start stacking if requested
+if !"expr $?autostack && $unit == $units - 1" \
+ "rcload stk.soc"
+
+if !"expr $?aedev + 0" && !"expr $unit == $units - 1" \
+ "aedev init"
+
+# hurricane 48p FE platform LED setup for 56146_A0 and 56147_A0 board
+# (enabled by adding the property "fe_hu_48p=1")
+#
+if $?fe_hu_48p && $?BCM56146 || $?BCM56147 \
+ "phy fe0 0x1f 0x008b; \
+ phy fe0 0x1a 0x3f09;\
+ phy fe8 0x1f 0x008b; \
+ phy fe8 0x1a 0x3f09; \
+ phy fe16 0x1f 0x008b; \
+ phy fe16 0x1a 0x3f09"
+
+# enable LED matrix mode for PHY54292 on BCM953411K/R
+if $?bcm953411 \
+ "rcload gh_bcm953411x.soc"
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/readme.txt b/bal_release/3rdparty/bcm-sdk/rc/arad/readme.txt
new file mode 100644
index 0000000..84e5089
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/readme.txt
@@ -0,0 +1,18 @@
+This directory contains bcm files that are needed in the Pioneer svk file system `to bring up
+the Arad BCM Diag Shell.
+User should also copy the bcm.user linux-kernel-bde.ko and linux-user-bde.ko
+from the Jenkins BAL bcm-sdk build (for PPC) or private bcm_sdk build to the same Pioneer svk file system.
+!!!
+ Do not forget to change the IP in rpc.soc to point it to the BAL_CORE
+!!!
+
+The currently supported bcm_sdk version is 6.5.4
+.
+|-- config.bcm
+|-- arad.soc
+|-- arad_dram.soc
+|-- rc.soc
+`-- rpc.soc
+
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/arad/rpc.soc b/bal_release/3rdparty/bcm-sdk/rc/arad/rpc.soc
new file mode 100644
index 0000000..07e45b4
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/arad/rpc.soc
@@ -0,0 +1,22 @@
+cpudb newdb
+
+cpudb add key=0x1
+
+cpudb add key=0x2 local=t
+
+cts atp trans sock server start
+
+cts atp cos=0 vlan=1
+
+cte reg mode=atp
+
+cts atp trans sock inst dk=0x1 dip=10.25.8.74
+
+rpc nonexthop
+
+rpc start
+
+dune "sand trap_target 10.25.8.74:50001"
+
+dune "sand trap_receive 10.25.8.74:50002"
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/bal/bal_config.ini b/bal_release/3rdparty/bcm-sdk/rc/bal/bal_config.ini
new file mode 100644
index 0000000..bc9c0c3
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/bal/bal_config.ini
@@ -0,0 +1,16 @@
+# Maple IWF mode "direct" or "per_flow"
+iwf_mode=direct
+# System NNI/PON mapping table
+# 0: KT2
+# 1: SVK3
+# 2: ARAD (experiment)
+# 3: Qumran (experiment)
+intf_maptable=3
+# UDP port that receive the switch CPU_TRAP packets
+trap_udp_port=50001
+# Switch QOS scheduler mode
+# 0: SP
+# 1: WFQ
+ds_sched_mode=1
+# UDP port on switch that receive packet_out packets
+pkt_send_svr_listen_port=50002
diff --git a/bal_release/3rdparty/bcm-sdk/rc/bal/config.bcm b/bal_release/3rdparty/bcm-sdk/rc/bal/config.bcm
new file mode 100644
index 0000000..239ee72
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/bal/config.bcm
@@ -0,0 +1,1713 @@
+#
+# $Id: config-sand.bcm,v 1.140 2013/09/22 14:29:47 tomerma Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+
+#########################################
+##cfg for BCM88640 (PetraB) and BCM88650 (Arad)
+#########################################
+
+## temporary suppressing unknown soc properties warnings - till adding them unknown to property.h/propgen
+## (need to be the first soc property in the file).
+suppress_unknown_prop_warnings=1
+
+## Multi device system (Negev): 2 devices, fabric mode is FE, mod id is slot id
+## (Top line card is 0, button is 1).
+#diag_chassis=1
+
+## Disable diag init application. Should be used if one wants to run his own
+## application instead of the diag init example
+#diag_disable=1
+
+## Skip cosq configuration in diag_init
+#diag_cosq_disable=1
+
+#########################################
+##cfg for BCM88650 - Arad
+#########################################
+
+### Device configuration ###
+
+## Activate Emulation partial init. Values: 0 - Normal, 1 - Emulation .Default: 0x0.
+diag_emulator_partial_init.BCM88650=0
+
+## General
+# Set the FAP Device mode
+# Options: PP / TM / TDM_OPTIMIZED / TDM_STANDARD
+fap_device_mode.BCM88650=PP
+
+## Credit worth size (Bytes)
+credit_size.BCM88650=1024
+
+## Clock configurations
+# Core clock speed (MHz). Default: 600 MHz
+core_clock_speed_khz.BCM88650=600000
+# System reference clock (MHz). Default: 600 MHz
+system_ref_core_clock_khz.BCM88650=600000
+
+### Network Interface configuration ###
+## Use of the ucode_port_<Local-Port-Id>=<Interface-type>[<Interface-Id>][.<Channel-Id>]
+## Local port range: 0 - 255.
+## Interface types: XAUI/RXAUI/SGMII/ILKN/10GBase-R/XLGE/CGE/CPU
+
+# Map bcm local port to CPU[.channel] interfaces
+ucode_port_180.BCM88650=CPU.0
+
+pon_application_support_enabled_0.BCM88650=TRUE
+pon_application_support_enabled_1.BCM88650=TRUE
+pon_application_support_enabled_2.BCM88650=TRUE
+pon_application_support_enabled_3.BCM88650=TRUE
+#pon_application_support_enabled_4.BCM88650=TRUE
+#pon_application_support_enabled_5.BCM88650=TRUE
+#pon_application_support_enabled_6.BCM88650=TRUE
+#pon_application_support_enabled_7.BCM88650=TRUE
+
+vlan_match_criteria_mode=PON_PCP_ETHERTYPE
+
+#Firmware mode:
+# 0=DEFAULT
+# 1=SFP_OPT_SR4 - optical short range
+# 2=SFP_DAC - direct attach copper
+# 3=XLAUI - 40G XLAUI mode
+# 4=FORCE_OSDFE - force over sample digital feedback equalization
+# 5=FORCE_BRDFE - force baud rate digital feedback equalization
+# 6=SW_CL72 - software cl72 with AN on
+# 7=CL72_WITHOUT_AN - cl72 without AN
+#For Negev2 chassis enable DFE is recommended
+
+serdes_if_type=1024
+
+#serdes_firmware_mode.BCM88650=3
+serdes_firmware_mode_il.BCM88650=4
+serdes_firmware_mode_sfi.BCM88650=0
+
+#
+# Serdes firmware mode for Channelized PON interfaces
+#
+#serdes_firmware_mode_xe0.BCM88650=0
+#serdes_firmware_mode_xe1.BCM88650=0
+#serdes_firmware_mode_xe2.BCM88650=0
+#serdes_firmware_mode_xe3.BCM88650=0
+#serdes_firmware_mode_xe4.BCM88650=0
+#serdes_firmware_mode_xe5.BCM88650=0
+#serdes_firmware_mode_xe6.BCM88650=0
+#serdes_firmware_mode_xe7.BCM88650=0
+#serdes_firmware_mode_xe8.BCM88650=0
+#serdes_firmware_mode_xe9.BCM88650=0
+#serdes_firmware_mode_xe10.BCM88650=0
+#serdes_firmware_mode_xe11.BCM88650=0
+#serdes_firmware_mode_xe12.BCM88650=0
+#serdes_firmware_mode_xe13.BCM88650=0
+#serdes_firmware_mode_xe14.BCM88650=0
+#serdes_firmware_mode_xe15.BCM88650=0
+
+#
+# Serdes firmware mode for NNI interfaces
+#
+serdes_firmware_mode_xe128.BCM88650=2
+serdes_firmware_mode_xe129.BCM88650=2
+serdes_firmware_mode_xe130.BCM88650=2
+serdes_firmware_mode_xe131.BCM88650=2
+serdes_firmware_mode_xe0.BCM88650=2
+serdes_firmware_mode_xe1.BCM88650=2
+serdes_firmware_mode_xe2.BCM88650=2
+serdes_firmware_mode_xe3.BCM88650=2
+
+#
+# Set the speed for the PON-side ports (connected to Pioneer) to 12.5G
+#
+#port_init_speed_xe0.BCM88650=12500
+#port_init_speed_xe1.BCM88650=12500
+#IL# change xe2, xe3 speed to 1G
+port_init_speed_xe2.BCM88650=1000
+port_init_speed_xe3.BCM88650=1000
+#port_init_speed_xe4.BCM88650=12500
+#port_init_speed_xe5.BCM88650=12500
+#port_init_speed_xe6.BCM88650=12500
+#port_init_speed_xe7.BCM88650=12500
+#port_init_speed_xe8.BCM88650=12500
+#port_init_speed_xe9.BCM88650=12500
+#port_init_speed_xe10.BCM88650=12500
+#port_init_speed_xe11.BCM88650=12500
+#port_init_speed_xe12.BCM88650=12500
+#port_init_speed_xe13.BCM88650=12500
+#port_init_speed_xe14.BCM88650=12500
+#port_init_speed_xe15.BCM88650=12500
+
+#
+# Set the number of priorities for the PON-side ports (connected to
+# Pioneer) to '2'.
+#
+port_priorities_xe0.BCM88650=2
+port_priorities_xe1.BCM88650=2
+port_priorities_xe2.BCM88650=2
+port_priorities_xe3.BCM88650=2
+#port_priorities_xe4.BCM88650=2
+#port_priorities_xe5.BCM88650=2
+#port_priorities_xe6.BCM88650=2
+#port_priorities_xe7.BCM88650=2
+#port_priorities_xe8.BCM88650=2
+#port_priorities_xe9.BCM88650=2
+#port_priorities_xe10.BCM88650=2
+#port_priorities_xe11.BCM88650=2
+#port_priorities_xe12.BCM88650=2
+#port_priorities_xe13.BCM88650=2
+#port_priorities_xe14.BCM88650=2
+#port_priorities_xe15.BCM88650=2
+
+#
+# Map bcm local port to Network-Interface[.channel] interfaces
+#
+# PON Interfaces
+#
+
+#
+# Non-channelized PON Interfaces
+#
+# Uncomment the following if using non-channelized PON interfaces with
+# Pioneer.
+#
+#ucode_port_0.BCM88650=10GBase-R8
+#ucode_port_1.BCM88650=10GBase-R9
+#ucode_port_2.BCM88650=10GBase-R10
+#ucode_port_3.BCM88650=10GBase-R11
+#ucode_port_4.BCM88650=10GBase-R12
+#ucode_port_5.BCM88650=10GBase-R13
+#ucode_port_6.BCM88650=10GBase-R14
+#ucode_port_7.BCM88650=10GBase-R15
+
+#
+# Channelized PON Interfaces
+#
+# Define virtual ports for the 10G Channels
+#
+#ucode_port_0.BCM88650=10GBase-R8.0
+#ucode_port_1.BCM88650=10GBase-R9.0
+#ucode_port_2.BCM88650=10GBase-R10.0
+#ucode_port_3.BCM88650=10GBase-R11.0
+#ucode_port_4.BCM88650=10GBase-R12.0
+#ucode_port_5.BCM88650=10GBase-R13.0
+#ucode_port_6.BCM88650=10GBase-R14.0
+#ucode_port_7.BCM88650=10GBase-R15.0
+
+#
+# Define virtual ports for the 1G Channels
+#
+#ucode_port_8.BCM88650=10GBase-R8.1
+#ucode_port_9.BCM88650=10GBase-R9.1
+#ucode_port_10.BCM88650=10GBase-R10.1
+#ucode_port_11.BCM88650=10GBase-R11.1
+#ucode_port_12.BCM88650=10GBase-R12.1
+#ucode_port_13.BCM88650=10GBase-R13.1
+#ucode_port_14.BCM88650=10GBase-R14.1
+#ucode_port_15.BCM88650=10GBase-R15.1
+
+#
+# NNI Interfaces
+#
+ucode_port_128.BCM88650=10GBase-R0
+ucode_port_129.BCM88650=10GBase-R1
+ucode_port_130.BCM88650=10GBase-R2
+ucode_port_131.BCM88650=10GBase-R3
+ucode_port_0.BCM88650=10GBase-R4
+ucode_port_1.BCM88650=10GBase-R5
+ucode_port_2.BCM88650=10GBase-R6
+ucode_port_3.BCM88650=10GBase-R7
+
+#ucode_port_200.BCM88650=CPU.1
+#ucode_port_201.BCM88650=CPU.2
+#ucode_port_202.BCM88650=CPU.3
+#ucode_port_203.BCM88650=CPU.4
+
+#40G
+#ucode_port_1.BCM88650=XLGE0
+#ucode_port_2.BCM88650=XLGE1
+#ucode_port_3.BCM88650=XLGE2
+#ucode_port_4.BCM88650=XLGE3
+#ucode_port_5.BCM88650=XLGE4
+#ucode_port_6.BCM88650=XLGE5
+#ucode_port_7.BCM88650=XLGE6
+
+#ILKN configuration - basic config
+#ucode_port_31.BCM88650=ILKN0
+#ucode_port_32.BCM88650=ILKN1
+#ilkn_num_lanes_0.BCM88650=12
+#ilkn_num_lanes_1.BCM88650=12
+#port_init_speed_il.BCM88650=10312
+
+
+#ILKN per port channel stat
+#ilkn_counters_mode.BCM88650=PACKET_PER_CHANNEL
+
+#ILKN configuration - advanced
+#ilkn_metaframe_sync_period=2048
+# Enable\Disable ILKN status message sent through an out-of-band interface.
+# ilkn_interface_status_oob_ignore.BCM88650=1
+
+##ILKN retransmit
+#ilkn_retransmit_enable_rx.BCM88650=1
+#ilkn_retransmit_enable_tx.BCM88650=1
+#ilkn_retransmit_buffer_size.BCM88650=250
+#ilkn_retransmit_num_requests_resent.BCM88650=15
+#ilkn_retransmit_num_sn_repetitions_tx.BCM88650=1
+#ilkn_retransmit_num_sn_repetitions_rx.BCM88650=1
+#ilkn_retransmit_rx_timeout_words.BCM88650=3800
+#ilkn_retransmit_rx_timeout_sn.BCM88650=250
+#ilkn_retransmit_rx_ignore.BCM88650=80
+#ilkn_retransmit_rx_reset_when_error_enable.BCM88650=1
+#ilkn_retransmit_rx_watchdog.BCM88650=0
+#ilkn_retransmit_rx_reset_when_alligned_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_retry_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_after_disc_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_before_disc_error_enable.BCM88650=0
+#ilkn_retransmit_rx_reset_when_timout_error_enable.BCM88650=0
+#ilkn_retransmit_tx_wait_for_seq_num_change_enable.BCM88650=1
+#ilkn_retransmit_tx_ignore_requests_when_fifo_almost_empty.BCM88650=1
+
+#ucode_port_40.BCM88650=RCY.0
+#ucode_port_41.BCM88650=RCY.1
+#ucode_port_42.BCM88650=RCY.2
+
+## CAUI Configuration
+#ucode_port_41.BCM88650=CGE0
+#ucode_port_42.BCM88650=CGE1
+caui_num_lanes_0.BCM88650=10
+caui_num_lanes_1.BCM88650=10
+#Required for working IXIA 100G port:
+mld_lane_swap_lane20_ce.BCM88650=0
+mld_lane_swap_lane21_ce.BCM88650=1
+mld_lane_swap_lane0_ce.BCM88650=20
+mld_lane_swap_lane1_ce.BCM88650=21
+
+# This configures the lane polarity
+pb_serdes_lane_swap_polarity_tx_phy1.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy3.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy5.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy13.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy14.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy23.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy24.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy27.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy28.BCM88650=0
+
+pb_serdes_lane_swap_polarity_rx_phy1.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy3.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy5.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy13.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy14.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy23.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy24.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy27.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy28.BCM88650=0
+
+xgxs_tx_lane_map_quad0.BCM88650=0x3210
+xgxs_tx_lane_map_quad1.BCM88650=0x3210
+xgxs_tx_lane_map_quad2.BCM88650=0x3210
+xgxs_tx_lane_map_quad3.BCM88650=0x3210
+xgxs_tx_lane_map_quad4.BCM88650=0x3210
+xgxs_tx_lane_map_quad5.BCM88650=0x3210
+xgxs_tx_lane_map_quad6.BCM88650=0x3210
+
+xgxs_rx_lane_map_quad0.BCM88650=0x3210
+xgxs_rx_lane_map_quad1.BCM88650=0x3210
+xgxs_rx_lane_map_quad2.BCM88650=0x3210
+xgxs_rx_lane_map_quad3.BCM88650=0x3210
+xgxs_rx_lane_map_quad4.BCM88650=0x3210
+xgxs_rx_lane_map_quad5.BCM88650=0x3210
+xgxs_rx_lane_map_quad6.BCM88650=0x3210
+
+
+
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88650=1
+
+#Port init mode
+#port_init_duplex=0
+#port_init_adv=0
+#port_init_autoneg=0
+
+
+# This disables serdes initialization
+# phy_null.BCM88650=1
+
+## Number of Internal ports
+# Enable the ERP port. Values: 0 / 1.
+num_erp_tm_ports.BCM88650=1
+# Enable the OLP port. Values: 0 / 1.
+num_olp_tm_ports.BCM88650=1
+# Enable OAMP
+num_oamp_ports.BCM88650=0
+
+## Firmware Load Method
+load_firmware.BCM88650=0x102
+
+### Headers configuration ###
+
+## Use of the tm_port_header_type_<Local-Port-Id>=<Header-type>
+## Default header type is derived from fap_device_mode: If fap_device_mode is
+## PP, default header type is ETH. Otherwise, defualt header type is TM.
+## Header type per port can be overriden.
+## All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/UDH_ETH
+## Injected header types: if PTCH, INJECTED (local Port of type TM) or INJECTED_PP (PP)
+## if PTCH-2, INJECTED_2 (local Port of type TM) or INJECTED_2_PP (PP)
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88650=TM
+
+tm_port_header_type_in_180.BCM88650=INJECTED_2
+tm_port_header_type_out_180.BCM88650=CPU
+
+tm_port_header_type_in_200.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_200.BCM88650=ETH
+tm_port_header_type_in_201.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_201.BCM88650=ETH
+tm_port_header_type_in_202.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_202.BCM88650=ETH
+tm_port_header_type_in_203.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_203.BCM88650=ETH
+
+### Parser Configuration ###
+# Parser has 4 custom macros that are allocated dynamically and
+# configured according to the following features and soc properties:
+# Trill (1 macro) - trill_mode
+# FCoE (2 macros) - bcm886xx_fcoe_switch_mode
+# VxLAN (1 macro) - bcm886xx_vxlan_enable
+# IPv6-Extension-header (2 macros) - bcm886xx_ipv6_ext_hdr_enable
+# UDP (1 macro) - UDP parsing is enabled by default, and can be
+# disabled with soc property custom_feature_udp_parse_disable
+# When disabling UDP parsing VxLAN and 1588oUDP are affected
+
+# Enable IPv6 Extension Header, 0 - disable (default), 1 - enable
+#bcm886xx_ipv6_ext_hdr_enable=1
+
+# Disable UDP parsing, 0 - enable (default), 1 - disable
+#custom_feature_udp_parse_disable=1
+
+#OAMP port
+#tm_port_header_type_out_232.BCM88650=CPU
+
+#MPLS-TP channel types for OAM/BFD - If MPLS-TP used, channel should be specified
+#Available types: mplstp_bfd_control_channel_type
+# mplstp_pw_ach_channel_type
+# mplstp_dlm_channel_type
+# mplstp_ilm_channel_type
+# mplstp_dm_channel_type
+# mplstp_ipv4_channel_type
+# mplstp_cc_channel_type
+# mplstp_cv_channel_type
+# mplstp_on_demand_cv_channel_type
+# mplstp_pwe_oam_channel_type
+# mplstp_ipv6_channel_type
+# mplstp_fault_oam_channel_type
+# mplstp_g8113_channel_type
+#mplstp_g8113_channel_type=0x8902
+
+
+
+# Set the recycling port processing to be raw (static forwarding)
+tm_port_header_type_rcy.BCM88650=RAW
+
+### RCPU
+# Valid CPU local ports on which RCPU packets can be received by slave device.
+#rcpu_rx_pbmp=0xf00000000000000000000000000000000000000000000000001
+
+#tm_port_header_type_514.BCM88650=RAW
+
+## Header extensions
+# Set if an FTMH Out-LIF extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS
+fabric_ftmh_outlif_extension.BCM88650=IF_MC
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88660: ENABLED, FULL_HASH
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY / STANDBY_MC_LB
+# (available only for AradPlus)
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88650=DISABLED
+
+# Set if an OTMH Out-LIF (CUD) Extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS / DOUBLE_TAG (two hop scheduling)
+# Default: NEVER
+# tm_port_otmh_outlif_ext_mode_13.BCM88650=NEVER
+
+# Set if an OTMH Source-System-Port Extension is present.
+# Option: 0/1
+# Default: 0
+# tm_port_otmh_src_ext_enable_13.BCM88650=0
+
+#Trunk hash format, relevant only for AradPlus. Possible values: NORMAL (default) / INVERTED / DUPLICATED.
+#trunk_hash_format=NORMAL
+
+## Stacking Application
+#stacking_enable.BCM88650=1
+#custom_feature_stamp_uc_destination.BCM88650=1
+
+## System RED
+# Set System-Red functionality.
+#system_red_enable.BCM88650=1
+
+# Indicate the size (Bytes) of a first header to skip
+# before the major header at ingress (e.g. Ethernet, ITMH)
+# It can be set per port also
+first_header_size.BCM88650=0
+
+# Indicate the size (Bytes) of the PMF Extension Headers
+# to remove for TM header type ports (expecting ITMH)
+# Set per port
+#post_headers_size_0.BCM88650=4
+
+# Indicate the size (Bytes) of the User-Headers: configurable
+# headers located in the fabric between internal headers and
+# Ethernet. Their values are set by Ingress FP, and can be used
+# by Egress FP or Egress Editor.
+# units: bits. 4 values can be set:
+# 0 - size of the 1st User-Header, for the Egress PMF. 0b / 8b / 16b
+# 1 - size of the 2nd User-Header, for the Egress PMF. 0b / 8b / 16b
+# The sum of these 2 values should be under 16b
+# 2, 3 - size of the 1st/2nd User-Header, for the Egress Editor.
+# 0b / 8b / 16b / 24b / 32b
+# Each of the global User-Header size must be under 32 bits, but not 24 bits.
+# The Egress FP field is always at the MSB of the User-Header
+# Not available for 88650-A0.
+#field_class_id_size_0.BCM88650=8
+#field_class_id_size_1.BCM88650=0
+#field_class_id_size_2.BCM88650=24
+#field_class_id_size_3.BCM88650=0
+
+
+### Trunk - LAG configuration ###
+# Set Set the number of LAGs: 1024, 512, 256, 128 or 64
+number_of_trunks.BCM88650=256
+
+### SYNCE configuration ###
+## Synchronous Ethernet Signal Mode.
+## Options: TWO_DIFF_CLK, TWO_CLK_AND_VALID. Default: TWO_CLK_AND_VALID
+#sync_eth_mode.BCM88650=TWO_CLK_AND_VALID
+
+## Clock Source (single SerDes) lane in the specified NIF port.
+## Usage: sync_eth_clk_to_nif_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_nif_id_clk_0.BCM88650=1
+#sync_eth_clk_to_nif_id_clk_1.BCM88650=1
+
+## Clock Divider for the selected recovered clock. Valid values: 1/2/4. Default: 1.
+## Usage: sync_eth_clk_divider_clk_<clk_number>=<1/2/4>
+#sync_eth_clk_divider_clk_0.BCM88650=1
+#sync_eth_clk_divider_clk_1.BCM88650=1
+
+## Enable the automatic squelch function for the recovered clock. Valid values: 0/1. Default: 0.
+## Usage: sync_eth_clk_squelch_enable_clk_<clk_number>=<0/1>
+#sync_eth_clk_squelch_enable_clk_0.BCM88650=0
+#sync_eth_clk_squelch_enable_clk_1.BCM88650=0
+
+### ELK configuration ###
+## External lookup (TCAM) Device type select, Indicate the External lookup Device type.
+# Value Options: NONE/NL88650. Default: NONE.
+#ext_tcam_dev_type=NL88650
+
+## Set ELK FWD table Size.
+# format: ext_xxx_fwd_table_size.
+# where xxx replaced by FWD options: ip4_uc_rpf/ip4_mc/ip6_uc_rpf/ip6/ip6_mc/trill_uc/trill_mc/mpls/coup_mpls
+# Value Options: (0) - External table disabled, >0: number of entries. Default: 0.
+#ext_ip4_uc_rpf_fwd_table_size=8192
+#ext_ip4_mc_fwd_table_size=8192
+
+## Set ELK IP FWD use NetRoute ALG.
+# Value Options: ALG_LPM_LPM/ALG_LPM_NETROUTE/ALG_LPM_TCAM. Default: ALG_LPM_TCAM.
+#ext_fwd_algorithm_lpm=ALG_LPM_TCAM
+
+## Set ELK interface mode.
+# Change ELK interface configuration to support CAUI port.
+# Value Options: 0/1. 0 - Normal mode, 1 2 CAUI port + ELK mode. Default: 0.
+#ext_interface_mode=0
+
+### Configure MDIO interface
+# External MDIO clock rate divisor . Default: 0x24.
+#rate_ext_mdio_divisor=0x36
+# External MDIO clock rate divisor. Default: 0x1.
+#rate_ext_mdio_dividend=1
+
+### TDM - OTN configuration ###
+#fap_tdm_bypass.BCM88650=0
+
+# Indicate if a Petra-B device is connected to the actual device
+# For TDM/OTN applications,
+# system_is_petra_b_in_system.BCM88650=0
+##Indicate if TDM can arrive throgh primary pipe.
+#Should be 1 for a System with PetraB that connected to fabric over primary pipe.
+fabric_tdm_over_primary_pipe.BCM88650=0
+
+### Fabric configuration ###
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88650=2
+#SFI speed rate
+port_init_speed_sfi.BCM88650=10312
+#CL72
+#port_init_cl72_sfi=0
+fabric_segmentation_enable.BCM88650=1
+
+## Fabric transmission mode
+# Set the Connect mode to the Fabric
+# Options: FE - presence of a Fabric device (single stage) / MULT_STAGE_FE - Multi-stage /
+# SINGLE_FAP - stand-alone device / MESH - mesh / BACK2BACK - 2 devices in Mesh
+#fabric_connect_mode.BCM88650=SINGLE_FAP
+fabric_connect_mode.BCM88650=FE
+
+## Cell format configuration
+# Indicate if the traffic can be sent in dual pipe
+is_dual_mode.BCM88650=0
+# Indicate the format of the cell:
+# A VCS128 cell is used if system_is_vcs_128_in_system or system_is_fe600_in_system is TRUE
+system_is_vcs_128_in_system.BCM88650=0
+system_is_fe600_in_system.BCM88650=0
+
+### WRED ###
+
+# Set the maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88650=0
+
+### OCB (On-Chip Buffer) configuration ###
+# Enable the OCB
+# Enable MODES:
+# 0/FALSE --> OCB_DISABLED --> No OCB use
+# 1/TRUE --> OCB_ENABLED --> Like in Arad-A0/B0. Some packets may use both DRAM and OCB resources
+# ONE_WAY_BYPASS --> Depends on number of present drams (available only for AradPlus):
+# 0 drams: - OCB_ONLY
+# 1 drams: - OCB_ONLY_1_DRAM --> : OCB-only with 1 DRAM for the free pointers
+# 2-8 drams: - OCB_DRAM_SEPARATE --> : OCB and DRAM coexist separately
+# Default: TRUE.
+bcm886xx_ocb_enable.BCM88650=1
+
+# OCB Data Buffer size. Possible values: 128/256/512/1024. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88650=256
+# Repartition between Unicast and Full Multicast buffers.
+# 0: 80% Unicast and 20% Multicast, 1: Unicast-Only
+bcm886xx_ocb_repartition.BCM88650=0
+
+### PDM configuration ###
+# Set the PDM Mode.
+# 0: simple (default), 1: reduced (mandatory for LLFC-VSQ, PFC-VSQ, or ST-VSQ)
+bcm886xx_pdm_mode.BCM88650=0
+
+### Multicast Number of DBuff mode ###
+# Set IQM FMC buffers-replication sizes
+# Options for 88650: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE/ARAD_INIT_FMC_64_REP_128K_DBUFF_MODE
+# Default: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88650=ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+
+### Multicast configuration ###
+# Multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_min.BCM88650=0
+egress_multicast_direct_bitmap_max.BCM88650=4095
+
+### VOQ - Flow configuration ###
+
+# Set the VOQ mapping mode:
+# DIRECT: More than 4K System Ports are supported. System-level WRED is not supported.
+# INDIRECT: similar to Petra-B. Up to 4K System Ports.
+voq_mapping_mode.BCM88650=INDIRECT
+
+# Set the Base Queue to be added to the packet flow-id
+# when the Flow-Id is set explicitely either by the ITMH
+# or by the Destination resolution in the Packet processing
+flow_mapping_queue_base.BCM88650=0
+
+# Set the number of priorities supported at egress per Port
+# Options: 1 / 2 / 8
+port_priorities.BCM88650=8
+
+# Set the shared multicast resource mode: Strict / Discrete
+egress_shared_resources_mode.BCM88650=Strict
+
+# Define outgoing port rate mode in data rate or packet rate.
+# Options: DATA / PACKET
+otm_port_packet_rate.BCM88650=DATA
+
+# Set Port egress recycling scheduler configuration.
+# 0: Strict Priority Scheduler, 1: Round Robin Scheduler
+port_egress_recycling_scheduler_configuration.BCM88650=0
+
+# Set statically the region mode per region id
+# 0: queue connectors only (InterDigitated = FALSE, OddEven = TRUE)
+# 1: queue connectors, SE (InterDigitated =TRUE, OddEven = TRUE)
+# 2: queue connectors, SE (InterDigitated =TRUE, OddEven = FALSE)
+dtm_flow_mapping_mode_region_65.BCM88650=0
+dtm_flow_mapping_mode_region_66.BCM88650=0
+dtm_flow_mapping_mode_region_67.BCM88650=0
+dtm_flow_mapping_mode_region_68.BCM88650=0
+dtm_flow_mapping_mode_region_69.BCM88650=0
+dtm_flow_mapping_mode_region_70.BCM88650=0
+dtm_flow_mapping_mode_region_71.BCM88650=0
+dtm_flow_mapping_mode_region_72.BCM88650=0
+dtm_flow_mapping_mode_region_73.BCM88650=0
+dtm_flow_mapping_mode_region_74.BCM88650=0
+dtm_flow_mapping_mode_region_75.BCM88650=0
+dtm_flow_mapping_mode_region_76.BCM88650=0
+dtm_flow_mapping_mode_region_77.BCM88650=0
+dtm_flow_mapping_mode_region_78.BCM88650=0
+dtm_flow_mapping_mode_region_79.BCM88650=0
+dtm_flow_mapping_mode_region_80.BCM88650=0
+dtm_flow_mapping_mode_region_81.BCM88650=1
+dtm_flow_mapping_mode_region_82.BCM88650=1
+dtm_flow_mapping_mode_region_83.BCM88650=1
+dtm_flow_mapping_mode_region_84.BCM88650=1
+dtm_flow_mapping_mode_region_85.BCM88650=1
+dtm_flow_mapping_mode_region_86.BCM88650=1
+dtm_flow_mapping_mode_region_87.BCM88650=1
+dtm_flow_mapping_mode_region_88.BCM88650=1
+dtm_flow_mapping_mode_region_89.BCM88650=1
+dtm_flow_mapping_mode_region_90.BCM88650=1
+dtm_flow_mapping_mode_region_91.BCM88650=1
+dtm_flow_mapping_mode_region_92.BCM88650=1
+dtm_flow_mapping_mode_region_93.BCM88650=1
+dtm_flow_mapping_mode_region_94.BCM88650=1
+dtm_flow_mapping_mode_region_95.BCM88650=1
+dtm_flow_mapping_mode_region_96.BCM88650=1
+dtm_flow_mapping_mode_region_97.BCM88650=1
+dtm_flow_mapping_mode_region_98.BCM88650=1
+dtm_flow_mapping_mode_region_99.BCM88650=2
+dtm_flow_mapping_mode_region_100.BCM88650=2
+dtm_flow_mapping_mode_region_101.BCM88650=2
+dtm_flow_mapping_mode_region_102.BCM88650=2
+dtm_flow_mapping_mode_region_103.BCM88650=2
+dtm_flow_mapping_mode_region_104.BCM88650=2
+dtm_flow_mapping_mode_region_105.BCM88650=2
+dtm_flow_mapping_mode_region_106.BCM88650=2
+dtm_flow_mapping_mode_region_107.BCM88650=2
+dtm_flow_mapping_mode_region_108.BCM88650=2
+dtm_flow_mapping_mode_region_109.BCM88650=2
+dtm_flow_mapping_mode_region_110.BCM88650=2
+dtm_flow_mapping_mode_region_111.BCM88650=2
+dtm_flow_mapping_mode_region_112.BCM88650=2
+dtm_flow_mapping_mode_region_113.BCM88650=2
+dtm_flow_mapping_mode_region_114.BCM88650=2
+dtm_flow_mapping_mode_region_115.BCM88650=2
+dtm_flow_mapping_mode_region_116.BCM88650=2
+dtm_flow_mapping_mode_region_117.BCM88650=2
+dtm_flow_mapping_mode_region_118.BCM88650=2
+dtm_flow_mapping_mode_region_119.BCM88650=2
+dtm_flow_mapping_mode_region_120.BCM88650=2
+dtm_flow_mapping_mode_region_121.BCM88650=2
+dtm_flow_mapping_mode_region_122.BCM88650=2
+dtm_flow_mapping_mode_region_123.BCM88650=2
+dtm_flow_mapping_mode_region_124.BCM88650=2
+dtm_flow_mapping_mode_region_125.BCM88650=2
+dtm_flow_mapping_mode_region_126.BCM88650=2
+dtm_flow_mapping_mode_region_127.BCM88650=2
+dtm_flow_mapping_mode_region_128.BCM88650=2
+
+#IL# Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88650=2
+dtm_flow_nof_remote_cores_region_2.BCM88650=2
+dtm_flow_nof_remote_cores_region_3.BCM88650=2
+dtm_flow_nof_remote_cores_region_4.BCM88650=2
+dtm_flow_nof_remote_cores_region_5.BCM88650=2
+dtm_flow_nof_remote_cores_region_6.BCM88650=2
+dtm_flow_nof_remote_cores_region_7.BCM88650=2
+dtm_flow_nof_remote_cores_region_8.BCM88650=2
+dtm_flow_nof_remote_cores_region_9.BCM88650=2
+dtm_flow_nof_remote_cores_region_10.BCM88650=2
+dtm_flow_nof_remote_cores_region_11.BCM88650=2
+dtm_flow_nof_remote_cores_region_12.BCM88650=2
+dtm_flow_nof_remote_cores_region_13.BCM88650=2
+dtm_flow_nof_remote_cores_region_14.BCM88650=2
+dtm_flow_nof_remote_cores_region_15.BCM88650=2
+dtm_flow_nof_remote_cores_region_16.BCM88650=2
+dtm_flow_nof_remote_cores_region_17.BCM88650=2
+dtm_flow_nof_remote_cores_region_18.BCM88650=2
+dtm_flow_nof_remote_cores_region_19.BCM88650=2
+dtm_flow_nof_remote_cores_region_20.BCM88650=2
+dtm_flow_nof_remote_cores_region_21.BCM88650=2
+dtm_flow_nof_remote_cores_region_22.BCM88650=2
+dtm_flow_nof_remote_cores_region_23.BCM88650=2
+dtm_flow_nof_remote_cores_region_24.BCM88650=2
+dtm_flow_nof_remote_cores_region_25.BCM88650=2
+dtm_flow_nof_remote_cores_region_26.BCM88650=2
+dtm_flow_nof_remote_cores_region_27.BCM88650=2
+dtm_flow_nof_remote_cores_region_28.BCM88650=2
+dtm_flow_nof_remote_cores_region_29.BCM88650=2
+dtm_flow_nof_remote_cores_region_30.BCM88650=2
+dtm_flow_nof_remote_cores_region_31.BCM88650=2
+dtm_flow_nof_remote_cores_region_32.BCM88650=2
+dtm_flow_nof_remote_cores_region_33.BCM88650=2
+dtm_flow_nof_remote_cores_region_34.BCM88650=2
+dtm_flow_nof_remote_cores_region_35.BCM88650=2
+dtm_flow_nof_remote_cores_region_36.BCM88650=2
+dtm_flow_nof_remote_cores_region_37.BCM88650=2
+dtm_flow_nof_remote_cores_region_38.BCM88650=2
+dtm_flow_nof_remote_cores_region_39.BCM88650=2
+dtm_flow_nof_remote_cores_region_40.BCM88650=2
+dtm_flow_nof_remote_cores_region_41.BCM88650=2
+dtm_flow_nof_remote_cores_region_42.BCM88650=2
+dtm_flow_nof_remote_cores_region_43.BCM88650=2
+dtm_flow_nof_remote_cores_region_44.BCM88650=2
+dtm_flow_nof_remote_cores_region_45.BCM88650=2
+dtm_flow_nof_remote_cores_region_46.BCM88650=2
+dtm_flow_nof_remote_cores_region_47.BCM88650=2
+dtm_flow_nof_remote_cores_region_48.BCM88650=2
+dtm_flow_nof_remote_cores_region_49.BCM88650=2
+dtm_flow_nof_remote_cores_region_50.BCM88650=2
+dtm_flow_nof_remote_cores_region_51.BCM88650=2
+dtm_flow_nof_remote_cores_region_52.BCM88650=2
+dtm_flow_nof_remote_cores_region_53.BCM88650=2
+dtm_flow_nof_remote_cores_region_54.BCM88650=2
+dtm_flow_nof_remote_cores_region_55.BCM88650=2
+dtm_flow_nof_remote_cores_region_56.BCM88650=2
+dtm_flow_nof_remote_cores_region_57.BCM88650=2
+dtm_flow_nof_remote_cores_region_58.BCM88650=2
+dtm_flow_nof_remote_cores_region_59.BCM88650=2
+dtm_flow_nof_remote_cores_region_60.BCM88650=2
+#dtm_flow_nof_remote_cores_region_core0_2.BCM88675=2
+
+### Flow Control configuration ###
+# Set the Flow control type per Port.
+# Options: LL (Link-level) / CB2 (Class-Based - 2 classes) /
+# CB8 (Class-Based - 8 classes)
+# flow_control_type.BCM88650=LL
+
+## Out-Of-Band Flow control configuration
+#spn_FC_OOB_TYPE, spn_FC_OOB_MODE, spn_FC_OOB_CALENDER_LENGTH, spn_FC_OOB_CALENDER_REP_COUNT,
+
+## Set voltage mode for oob interfaces
+#HSTL_1.5V
+#3.3V
+#HSTL_1.5V_VDDO_DIV_2
+ext_voltage_mode_oob=3.3V
+
+## Inband Interlaken configuration
+# spn_FC_INBAND_INTLKN_MODE, spn_FC_INBAND_INTLKN_CALENDER_LENGTH, spn_FC_INBAND_INTLKN_CALENDER_REP_COUNT
+# spn_FC_INBAND_INTLKN_CALENDER_LLFC_MODE, spn_FC_INBAND_INTLKN_LLFC_MUB_ENABLE_MASK
+
+### Meter engine configuration ###
+
+# Specify meter operation mode
+# 32 - Two meters per packet (32k total)
+# 64 - One meter per packet (64k total)
+# Options: 0, 32, 64
+policer_ingress_count.BCM88650=32
+
+# For meters in double 32k mode, determine the sharing mode
+# Options:
+# 0 - NONE (only for 64k mode)
+# 1 - SERIAL (only for 32k mode)
+# 2 - PARALLEL (only for 32k mode)
+policer_ingress_sharing_mode.BCM88650=1
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine the mapping
+# Options: BEST, WORST
+# policer_result_parallel_color_map.BCM88650=WORST
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine how the buckets are changed
+# Options: CONSTANT, TRANSPARENT, DEFERRED
+# policer_result_parallel_bucket_update.BCM88650=CONSTANT
+
+# Applies only to Arad+ (88660)
+# Set the Ethernet policer to work in color blind mode
+# rate_color_blind.BCM88650=1
+
+# L2 learn limit mode
+# Options: VLAN, VLAN_PORT, TUNNEL or the numeric equivalent 0-2.
+# Default: VLAN
+# l2_learn_limit_mode = VLAN_PORT
+
+# Applies only to Arad+ (88660)
+# Determines the L2 learn limit ranges when l2_learn_limit_mode is set to VLAN_PORT
+# Two range bases can be selected, each of 16K size.
+# Options: 0, 16K, 32K, 48K.
+# Default: 0 & 16K
+# l2_learn_lif_range_base_0 = 0
+# l2_learn_lif_range_base_1 = 16K
+
+### Counter engine configuration ###
+
+# Set the Counter source
+# Options: INGRESS_FIELD / INGRESS_VOQ / INGRESS_VSQ
+# INGRESS_CNM / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM (per queue) / EGRESS_TM_PORT (per port)
+# EGRESS_RECEIVE_VSI / EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM (per queue) / EGRESS_RECEIVE_TM_PORT (per port)
+# INGRESS_OAM / EGRESS_OAM
+# 2 Counter-Pointers can be set (with _0 and _1) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT
+# Range extension can be set (with _LSB and _MSB) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT /EGRESS_RECEIVE_VSI /
+# EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM / EGRESS_RECEIVE_TM_PORT
+counter_engine_source_0.BCM88650=INGRESS_FIELD
+counter_engine_source_1.BCM88650=INGRESS_FIELD_1
+counter_engine_source_2.BCM88650=INGRESS_VOQ
+###
+### DML
+###
+### For DML applications, counter engine 3 is used for VOQ
+### counters. This in combination with configuring the engines used for
+### VOQs for FWD_DROP allows for counters for 32K VOQs.
+###
+#counter_engine_source_3.BCM88650=EGRESS_FIELD
+counter_engine_source_3.BCM88650=INGRESS_VOQ
+
+# Configure the statistic interface egress source
+# Options: EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT (the default is TM)
+# valid just when there is no conflict with the other counter engines
+#counter_engine_source_stat0.BCM88650=EGRESS_TM
+#counter_engine_source_stat1.BCM88650=EGRESS_TM
+
+
+# Set the Counter engine resolution
+# SIMPLE_COLOR = green, not green
+# SIMPLE_COLOR_FWD = fwd green, fwd not green (BCM88660_A0 only)
+# SIMPLE_COLOR_DROP = drop green, drop not green (BCM88660_A0 only)
+# FWD_DROP = forwarded, dropped
+# GREEN_NOT_GREEN = fwd grn, drop grn, fwd not grn, drop not grn
+# FULL_COLOR = fwd grn, drop grn, fwd not grn, drop yel, drop red
+# ALL = received
+# FWD = forwarded, DROP = droped (not supported by ARAD_A0)
+# CONFIGURABLE = defined by counter_engine_map_ SOC properties (BCM88660_A0 only)
+counter_engine_statistics_0.BCM88650=FULL_COLOR
+counter_engine_statistics_1.BCM88650=FULL_COLOR
+###
+### DML
+###
+### For DML applications, counter engine 3 is used for VOQ
+### counters. This in combination with configuring the engines used for
+### VOQs for FWD_DROP allows for counters for 32K VOQs.
+###
+#counter_engine_statistics_2.BCM88650=FULL_COLOR
+#counter_engine_statistics_3.BCM88650=FULL_COLOR
+counter_engine_statistics_2.BCM88650=FWD_DROP
+counter_engine_statistics_3.BCM88650=FWD_DROP
+
+# Set the Counter format
+# Options: PACKETS_AND_BYTES / PACKETS / BYTES
+# / MAX_QUEUE_SIZE / PACKETS_AND_PACKETS(supported just in FWD_DROP statistic in BCM88660_A0)
+# If not PACKETS_AND_BYTES or PACKETS_AND_PACKETS, the HW Counter width is 59 bits, thus
+# no background SW operation is performed
+counter_engine_format_0.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_1.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_2.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_3.BCM88650=PACKETS_AND_BYTES
+
+# #enable/disable counter processor background thread (default:1-enable)
+# counter_engine_sampling_interval=1
+
+### Configurable mode configuration (BCM88660_A0 only)###
+# counter_engine_statistics_0.BCM88660_A0=CONFIGURABLE
+# counter_engine_map_enable_0.BCM88660_A0=1
+# counter_engine_map_size_0.BCM88660_A0=4
+# counter_engine_map_fwd_green_offset_0.BCM88660_A0=0
+# counter_engine_map_fwd_yellow_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_red_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_black_offset_0.BCM88660_A0=2
+# counter_engine_map_drop_green_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_yellow_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_red_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_black_offset_0.BCM88660_A0=3
+
+### Statistic-Report configuration ###
+# Enable the Statistic-Interface configuration
+# stat_if_enable_<port> - not supported by ARAD_A0
+# stat_if_enable.BCM88650=1
+
+# ## Statistic-Report Properties
+# # Set the Statistic-Report mode
+# # Options: BILLING / BILLING_QUEUE_NUMBER (not supported by ARAD_A0)/ QSIZE
+# stat_if_report_mode.BCM88650=QSIZE
+# #Indicate if idle reports must be sent
+# #when the Statistic-report rate is too low
+# stat_if_idle_reports_present.BCM88650=0
+# # Indicate if the reported packet size is the original packet size
+# stat_if_report_original_pkt_size.BCM88650=1
+# #If set then a single ingress-billing report will be generated
+# #for the whole set of the multicast copies
+# stat_if_report_multicast_single_copy=1
+# ## Statistic Packet configurations
+# # Set the Statistic Packet size (Bytes)
+# # Valid valued: 65B/126B/248B/492B (Queue-Size), 64B/128B/256B/512B/1024B (Billing)
+# stat_if_pkt_size=64B
+#
+# ## Scrubber configuration
+# # Set the range of VOQs to scrub. Range: 0 - 96K-1.
+# stat_if_scrubber_queue_min.BCM88650=0
+# stat_if_scrubber_queue_max.BCM88650=0
+#
+# # Set the scrubber rate range
+# # If set to 0 (default), the scrubber is disabled. Units: nanoseconds
+# stat_if_scrubber_rate_min.BCM88650=0
+# stat_if_scrubber_rate_max.BCM88650=0
+#
+# # Set the thresholds (thresh_id 0 - 15) defining
+# # occupancy range per resource type:
+# # DRAM Buffers, Buffer descriptors, Buffer descriptors buffers
+# stat_if_scrubber_bdb_th.BCM88650=0
+# stat_if_scrubber_buffer_descr_th.BCM88650=0
+# stat_if_uc_dram_buffer_descr_th.BCM88650=0
+#
+# #Relective report for queue size mode - not supported by ARAD_A0
+# #Reports will be created for queue num range (stat_if_selective_report_queue_min -stat_if_selective_report_queue_max)
+# #Default - all range
+# stat_if_selective_report_queue_min.BCM88650_B0=0
+# stat_if_selective_report_queue_max.BCM88650_B0=98303
+
+### Transaction - DMA configuration ###
+# Time to wait for SCHAN channel response (from CMIC). Units: microseconds.
+
+# TODO
+### Counter threads ###
+# spn_BCM_STAT_PBMP, spn_BCM_STAT_INTERVAL, spn_BCM_STAT_FLAGS
+
+### Interrupts ###
+## Set interrupts global parameters.
+# Options: 1 - Polling interrupt mode, 0 - Line/MSI interrupt mode. Default: 1.
+polled_irq_mode.BCM88650=0
+# Set the delay in microsecond between the polling, relevant only to Polling mode. Default: 0x0.
+polled_irq_delay.BCM88650=50000
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling, relevant only to Polling completion mode.
+# SCHAN:
+#schan_intr_enable.0=1
+schan_timeout_usec.BCM88650=300000
+# TDMA
+tdma_intr_enable.BCM88650=1
+tdma_timeout_usec.BCM88650=80000000
+# TSLAM
+tslam_intr_enable.BCM88650=1
+tslam_timeout_usec.BCM88650=80000000
+# MIIM
+#miim_intr_enable.0=1
+miim_timeout_usec.0=300000
+
+### DRAM configuration ###
+
+# DRAM buffer (Dbuff) size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88650=1024
+
+# Number of external DRAMs.
+# Allowed values for 88650: 0/2/3/4/6/8. A value of 0 disables the DRAM.
+# Allowed values for 88660: 0/1/2/3/4/6/8. A value of 0 disables the DRAM.
+# A value of 1 is permitted only in ONE WAY BYPASS ocb mode.
+ext_ram_present.BCM88650=8
+
+### Dram Tuning (Shmoo)
+# 2 = Use Dram saved config Parameters, if no Parameters Perform Shmoo on init. Default option.
+# 1 = Perform Shmoo on init.
+# 0 = Use Dram saved config Parameters, if no Parameters do nothing.
+ddr3_auto_tune.BCM88650=2
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Defult: 1.
+# bist_enable_dram.BCM88650=1
+
+### Example for Dram Saved config Parameters.
+## This example is for ci=14 (Dram=7).
+#ddr3_tune_addrc_ci14=0x000000ae
+#ddr3_tune_wr_dq_wl1_ci14=0x92929292,0x92929292,0x92929292,0x92929292
+#ddr3_tune_wr_dq_wl0_ci14=0x93939393,0x93939393,0x92929292,0x92929292
+#ddr3_tune_wr_dq_ci14=0x80808080
+#ddr3_tune_vref_ci14=0x000007df
+#ddr3_tune_rd_dqs_ci14=0x96969191,0x90909191
+#ddr3_tune_rd_dq_wl1_rn_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rn_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_dq_wl1_rp_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rp_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_en_ci14=0x009d9e9d,0x00a2a3a1
+#ddr3_tune_rd_data_dly_ci14=0x00000505
+
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram related parameteres per type.
+# Dram Type for Arad:
+dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800=1
+#dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_933=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_800=1
+#dram_type_DDR3_MICRON_MT42J64M16LA_15E_667=1
+#dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_933=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_800=1
+
+### Setting dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 Parameters as Default:
+## All other dram types parameter resides in arad.soc. choosing another Dram Type will override the following parameters.
+ext_ram_t_rrd=6000
+ext_ram_columns=1024
+ext_ram_banks=8
+ext_ram_ap_bit_pos=10
+ext_ram_burst_size=32
+ext_ram_t_ref=3900000
+ext_ram_t_wr=15000
+ext_ram_t_wtr=7500
+ext_ram_t_rtp=7500
+ext_ram_freq=1066
+ext_ram_rows=16384
+ext_ram_jedec=29
+ext_ram_t_rc=46090
+ext_ram_t_rcd_rd=13090
+ext_ram_t_rcd_wr=13090
+ext_ram_t_rp=13090
+ext_ram_t_rfc=160000
+ext_ram_t_ras=33000
+ext_ram_c_wr_latency=10
+ext_ram_t_faw=35000
+ext_ram_c_cas_latency=14
+ddr3_mem_grade=0x141414
+
+# DRAM pre-configurations according to config variables which defines
+# Dram Type. supports only DDR3:
+ext_ram_type.BCM88650=DDR3
+
+# Total Dram Size (MBytes)
+# For 8 drams interfaces, 2 channel each, Each channel 2Gbit Dram. the total DRAM size is 32GBits=4000MBytes.
+ext_ram_total_size.BCM88650=4000
+
+# Total buffer size allocated for User buffer. Units: Mbytes. Default: '0x0'.
+# Supported suffix:
+# dram - the buffer size will be subtracted from the DRAM size available for packet memory.
+#user_buffer_size=0
+#user_buffer_size_dram=50
+
+# DRAM ClamShell (interface swap its HW PIN pairs during init. Note: Only one of DRAMs can have its PIN swapped)
+# Valid values: 0/1
+#dram0_clamshell_enable.BCM88650=1
+#dram1_clamshell_enable.BCM88650=1
+
+# DRAM maximum number of crc error per buffer, buffer deleted by interrupt application.
+#dram_crc_del_buffer_max_reclaims=0
+
+### Warmboot ###
+## Scache initialization for warmboot persistent storage.
+#Save the warm boot data in a file. Allowed values: 3.
+#stable_location.BCM88650=3
+#Set the warm boot data filename.
+#stable_filename.BCM88650=./warmboot_data
+#Set the warm boot data file size (At least 10MB for PETRA-B, 4MB for ARAD)
+#stable_size.BCM88650=1000000000
+
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+## If set, always configures synthesizers, even if the configured rate is equal to
+## their nominal rate. Can be disabled to speedup bringup time (keep in mind that if
+## disabled, changing a synt to a non-nominal freq and than back to nominal will not
+## work
+#synt_over.BCM88650=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88650=100000000
+synt_ddr.BCM88650=125000000
+synt_phy.BCM88650=156250000
+synth_dram_freq.BCM88650=25
+
+#Configure the reference clock frequencies for NIF and Fabric SerDes
+# Options: 0 - 125MHZ, 1 - 156.25MHz
+serdes_nif_clk_freq.BCM88650=1
+serdes_fabric_clk_freq.BCM88650=1
+# IEEE 1588 -
+# configure clock (for 1588 debug, when Broadsync is disabled):
+# DPLL mode/lock: 0 - eci ts pll clk disabled, 1 - configure eci ts pll clk
+# DPLL phase/freq. Default initial: lo = 0x40000000, hi = 0x10000000.
+#phy_1588_dpll_frequency_lock.BCM88650=1
+#phy_1588_dpll_phase_initial_lo.BCM88650=0x40000000
+#phy_1588_dpll_phase_initial_hi.BCM88650=0x10000000
+# port external MAC
+# indication whether external MAC exists or not.
+# 0: 1588 external MAC does not exist
+# 1: 1588 external MAC exists
+# the external MAC substracts the RX time from the correction field
+# and adds the TX time to the correction field.
+#ext_1588_mac_enable_14.BCM88650=1
+
+## Trill configurations
+# Trill mode: 0 (disabled) / 1 (coarse-grained) / 2 (fine-grained)
+#trill_mode.BCM88650=1
+
+# Trill multicast prunning mode:
+# 0: no prunning - vsi is not part of the key
+# 1: VSI prunning: Key is dist-tree,esadit-bit,VSI.
+trill_mc_prune_mode.BCM88650=0
+
+# Enable SA authentication
+#sa_auth_enabled=1
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88650=0
+logical_port_drop.BCM88650=1
+
+#logical_port_mim_in.BCM88650=2
+#logical_port_mim_out.BCM88650=4096
+
+# Enable EVB application
+#evb_enable=1
+
+# Enable Flexible QinQ application
+#vlan_translation_match_ipv4=1
+
+
+# Prepend tag to be 4 bytes or 8 bytes. Default: 4B.
+# Applicable only from ARAD+
+#prepend_tag_bytes=4B
+
+# The Prepend Tag is located at (12 + 2*offset) bytes from the start of the packet.
+# Range: 0-7. Default: 0
+#prepend_tag_offset=0
+
+# Enable ARP (next hop mac extension) feature
+bcm886xx_next_hop_mac_extension_enable.BCM88650=0
+
+# Set VLAN translate mode.
+# 0: normal
+# 1: advanced mode. Enable vlan edit settings with enhanced user control
+#bcm886xx_vlan_translate_mode=0
+
+# Set MPLS termination database mode
+# Set MPLS databases location for each MPLS namespace (L1,L2,L3)
+#bcm886xx_mpls_termination_database_mode=0
+
+# Enable , Disable MPLS indexed.
+# MPLS termination with known label stack location.
+# Must be enabled in case device supports more than 2 MPLS label terminations (L1,L2,L3)
+#mpls_termination_label_index_enable=1
+
+# Enable FastReRoute labels in device.
+#fast_reroute_labels_enable=0
+
+# Enable MPLS Context specific. Upstream label assignment in device.
+#mpls_context_specific_label_enable=0
+
+# MPLS context.
+# Can be global, per port , per interface or per port,interface.
+#mpls_context=global
+
+# MPLS TP MC reserved mac address (01-00-5E-90-00-00).
+# If set device will support My-MAC termination of reserved MC Ethernet
+#mpls_tp_mymac_reserved_address=0
+
+# MPLS ELI enable disable
+mpls_entropy_label_indicator_enable=0
+
+
+#########################################
+##cfg for BCM88640_A0 - Petra
+#########################################
+
+force_clk_m_n_divisors_zero_nif0.BCM88640_A0=0
+force_clk_m_n_divisors_zero_fabric0.BCM88640_A0=1
+force_clk_m_n_divisors_zero_comb0.BCM88640_A0=0
+
+combo_ref_clock.BCM88640=312500
+
+nif_ref_clock.BCM88640_A0=312500
+
+# Use variable cell size
+system_cell_format.BCM88640_A0=VCS128
+
+# Core clock speed (MHz)
+core_clock_speed.BCM88640_A0=300
+
+# Map bcm local port to CPU/NIF interfaces
+ucode_port_0.BCM88640_A0=CPU.0
+ucode_port_73.BCM88640_A0=CPU.1
+ucode_port_74.BCM88640_A0=CPU.2
+ucode_port_75.BCM88640_A0=CPU.3
+ucode_port_76.BCM88640_A0=CPU.4
+ucode_port_77.BCM88640_A0=CPU.5
+ucode_port_78.BCM88640_A0=CPU.6
+
+# Interlaken ports basic configuration (temporary).
+# This configuration replaces the above XAUI/RXAUI ports config
+# The following PB design constraint is not enforced in SW, so must be taken
+# care of here, when mapping ports to interfaces:
+# If using ilkn0, port 1 (if used) must be mapped to ilkn0
+# If using ilkn1, port 2 (if used) must be mapped to ilkn1
+# Note that in our default mapping, port 2 is mapped to RXAUI 6, thus won't
+# work. If one wants to use front panel port 2 with ilkn1, he should be map
+# RAXUI6 to a port != 2.
+#ilkn_num_lanes_0.BCM88640_A0=12
+#ucode_port_1.BCM88640_A0=ILKN0.0
+#ucode_port_2.BCM88640_A0=ILKN0.1
+#ucode_port_3.BCM88640_A0=ILKN0.2
+#ilkn_num_lanes_1.BCM88640_A0=12
+#ucode_port_4.BCM88640_A0=RXAUI6
+#ucode_port_5.BCM88640_A0=ILKN1.0
+#ucode_port_6.BCM88640_A0=ILKN1.1
+#ucode_port_7.BCM88640_A0=ILKN1.2
+
+# Default header type is derived from fap_device_mode: If fap_device_mode is
+# PP, default header type is ETH. Otherwise, defualt header type is TM.
+# Header type per port can be overriden.
+# All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/INJECTED
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88640_A0=TM
+tm_port_header_type_in_0.BCM88640_A0=TM
+tm_port_header_type_out_0.BCM88640_A0=CPU
+tm_port_header_type_73.BCM88640_A0=TM
+tm_port_header_type_74.BCM88640_A0=TM
+tm_port_header_type_75.BCM88640_A0=TM
+tm_port_header_type_76.BCM88640_A0=TM
+tm_port_header_type_77.BCM88640_A0=TM
+tm_port_header_type_78.BCM88640_A0=TM
+# recycling port
+tm_port_header_type_40.BCM88640_A0=RAW
+ucode_port_40.BCM88640_A0=RCY.0
+
+# Enable ERP and OLP ports
+num_erp_tm_ports.BCM88640_A0=1
+num_olp_tm_ports.BCM88640_A0=1
+num_recycle_tm_ports.BCM88640_A0=1
+
+# Dram configuration
+# 600 Mhz
+ext_ram_pll_r.BCM88640_A0=4
+ext_ram_pll_f.BCM88640_A0=47
+ext_ram_pll_q.BCM88640_A0=1
+ext_ram_freq.BCM88640_A0=600
+
+# Dbuff size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88640_A0=1024
+
+# Number of external DRAMs.
+# Allowed values for 88x4x: 0/2/3/4/6.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# ext_ram_total_size below assumed this value is 6 for 88x4x and 8 for
+ext_ram_present.BCM88640_A0=6
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram
+# related parameteres per type.
+# Dram Type for Pb:
+dram_type_DDR3_MICRON_MT41J64M16_15E.BCM88640_A0=1
+#dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600.BCM88640_A0=1
+#dram_type_GDDR3_SAMSUNG_K4J52324QE.BCM88640_A0=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G.BCM88640_A0=1
+
+# QDR configuration
+# Parity. Allowed values: PARITY/ECC.
+ext_qdr_protection_type.BCM88640_A0=PARITY
+ext_qdr_size_mbit.BCM88640_A0=72
+#QDR type: QDR/QDR2P/QDR3/NONE.
+ext_qdr_type.BCM88640_A0=QDR
+
+# QDR can use the core clock, or using it's own pll. Current example is for 250MHz pll (if used).
+# QDR using own pll configuration
+#ext_qdr_use_core_clock_freq.BCM88640_A0=0
+#ext_qdr_pll_m.BCM88640_A0=4
+#ext_qdr_pll_n.BCM88640_A0=4
+#ext_qdr_pll_p.BCM88640_A0=0
+
+# QDR using core clock
+ext_qdr_use_core_clock_freq.BCM88640_A0=1
+
+#Configure MDIO. If parameter is not defined, MDIO is disabled.
+mdio_clock_freq_khz.BCM88640_A0=1000
+
+# Streaming interface configuration
+streaming_if_enable_timeoutcnt.BCM88640_A0=1
+streaming_if_timeout_prd.BCM88640_A0=70
+streaming_if_quiet_mode.BCM88640_A0=0
+streaming_if_discard_bad_parity.BCM88640_A0=0
+
+# maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88640_A0=0
+
+# multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_min.BCM88640_A0=0
+egress_multicast_direct_bitmap_max.BCM88640_A0=4095
+
+# configure flow mapping base to 0
+flow_mapping_queue_base.BCM88640_A0=0
+
+dtm_flow_mapping_mode_region_25.BCM88640_A0=0
+dtm_flow_mapping_mode_region_26.BCM88640_A0=0
+dtm_flow_mapping_mode_region_27.BCM88640_A0=0
+dtm_flow_mapping_mode_region_28.BCM88640_A0=0
+dtm_flow_mapping_mode_region_29.BCM88640_A0=0
+dtm_flow_mapping_mode_region_30.BCM88640_A0=0
+dtm_flow_mapping_mode_region_31.BCM88640_A0=0
+dtm_flow_mapping_mode_region_32.BCM88640_A0=0
+dtm_flow_mapping_mode_region_33.BCM88640_A0=1
+dtm_flow_mapping_mode_region_34.BCM88640_A0=1
+dtm_flow_mapping_mode_region_35.BCM88640_A0=1
+dtm_flow_mapping_mode_region_36.BCM88640_A0=1
+dtm_flow_mapping_mode_region_37.BCM88640_A0=1
+dtm_flow_mapping_mode_region_38.BCM88640_A0=1
+dtm_flow_mapping_mode_region_39.BCM88640_A0=1
+dtm_flow_mapping_mode_region_40.BCM88640_A0=1
+dtm_flow_mapping_mode_region_41.BCM88640_A0=1
+dtm_flow_mapping_mode_region_42.BCM88640_A0=2
+dtm_flow_mapping_mode_region_43.BCM88640_A0=2
+dtm_flow_mapping_mode_region_44.BCM88640_A0=2
+dtm_flow_mapping_mode_region_45.BCM88640_A0=2
+dtm_flow_mapping_mode_region_46.BCM88640_A0=2
+dtm_flow_mapping_mode_region_47.BCM88640_A0=2
+dtm_flow_mapping_mode_region_48.BCM88640_A0=2
+dtm_flow_mapping_mode_region_49.BCM88640_A0=2
+dtm_flow_mapping_mode_region_50.BCM88640_A0=2
+dtm_flow_mapping_mode_region_51.BCM88640_A0=2
+dtm_flow_mapping_mode_region_52.BCM88640_A0=2
+dtm_flow_mapping_mode_region_53.BCM88640_A0=2
+dtm_flow_mapping_mode_region_54.BCM88640_A0=2
+dtm_flow_mapping_mode_region_55.BCM88640_A0=2
+
+# Power up state (DOWN/UP/UP_AND_RELOCK). Can be configured per lane.
+pb_serdes_lane_power_state.BCM88640_A0=UP_AND_RELOCK
+
+# SeDes media type: Pre-configuration for tx params, according to
+# media type.
+# Allowed values: SHORT_BACKPLANE/LONG_BACKPLANE/CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type.BCM88640_A0=SHORT_BACKPLANE
+pb_serdes_lane_tx_phys_media_type_28.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_29.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_30.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_31.BCM88640_A0=CHIP2CHIP
+
+system_is_fe1600_in_system.BCM88640_A0=0
+
+# Counter engine configuration
+counter_engine_source_1.BCM88640_A0=0
+counter_engine_statistics_1.BCM88640_A0=4
+counter_engine_source_2.BCM88640_A0=1
+counter_engine_statistics_2.BCM88640_A0=4
+
+# Statistic Reporting
+stat_if_enable=0
+
+# Clock Phases: 0/90/180/270
+stat_if_phase=0
+
+# Rate in nm
+stat_if_sync_rate=0
+
+# TRUE/FALSE
+stat_if_parity_enable=FALSE
+
+# BILLING/FAP20V
+stat_if_report_mode=BILLING
+
+# Billing Mode
+# EGR_Q_NB/CUD/VSI_VLAN/BOTH_LIFS
+stat_if_report_billing_mode=VSI_VLAN
+
+# Fap20V Mode
+# QUEUE/PACKET
+stat_if_report_fap20v_mode=QUEUE
+
+# QUEUE_NUM/MC_ID (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_fabric_mc=QUEUE_NUM
+stat_if_report_fap20v_ing_mc=QUEUE_NUM
+
+# TRUE/FALSE (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_cnm_report=FALSE
+
+# TRUE/FALSE
+stat_if_report_fap20v_count_snoop=FALSE
+stat_if_report_original_pkt_size=FALSE
+stat_if_report_fap20v_single_copy_reported=FALSE
+
+schan_timeout_usec.BCM88640_A0=300000
+
+
+polled_irq_mode.BCM88640_A0=0
+polled_irq_delay.BCM88640_A0=1000
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88640=DISABLED
+
+#########################################
+##cfg for BCM88750
+#########################################
+
+fabric_device_mode.BCM88750=SINGLE_STAGE_FE2
+
+is_dual_mode.BCM88750=0
+system_is_vcs_128_in_system.BCM88750=0
+
+system_is_dual_mode_in_system.BCM88750=0
+system_is_single_mode_in_system.BCM88750=1
+
+system_is_fe600_in_system.BCM88750=0
+
+system_ref_core_clock_khz.BCM88750=600000
+
+fabric_merge_cells.BCM88750=0
+fabric_multicast_mode.BCM88750=DIRECT
+fabric_load_balancing_mode.BCM88750=NORMAL_LOAD_BALANCE
+fabric_tdm_fragment.BCM88750=0x180
+##Allows single pipe device to send TDM traffic over the fabric primary pipe - available for Fe1600_B0 only
+#change vcs128_unicast_priority to be lower than 2 - when enabling
+fabric_tdm_over_primary_pipe.BCM88750=0
+fabric_optimize_partial_links.BCM88750=0
+vcs128_unicast_priority.BCM88750=2
+
+polled_irq_mode.BCM88750=0
+polled_irq_delay.BCM88750=1000
+
+#Selects if to run MBIST (Memory Built In Self Test) of internal memory (tables) during startup.
+#Supported values: 0=don't run, 1=run, 2=run with extra logs
+#bist_enable.BCM88650=1
+bist_enable.BCM88750=1
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88750=0
+load_firmware.BCM88750=2
+
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88750=2
+
+#enable\disable CL72
+port_init_cl72.BCM88750=0
+#Avaliable speeds for BCM88750: 5750, 6250, 10312, 11500, 12500
+port_init_speed.BCM88750=10312
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88750=1
+serdes_fabric_clk_freq_out.BCM88750=1
+serdes_mixed_rate_enable.BCM88750_B0=0
+
+# VSC128 or VSC256
+fabric_cell_format.BCM88750=VSC256
+
+# Core clock speed (MHz)
+core_clock_speed_khz.BCM88750=533333
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88750=0
+schan_timeout_usec.BCM88750=300000
+# TDMA
+tdma_intr_enable.BCM88750=0
+tdma_timeout_usec.BCM88750=80000000
+# TSLAM
+tslam_intr_enable.BCM88750=0
+tslam_timeout_usec.BCM88750=80000000
+# MIIM
+miim_intr_enable.BCM88750=0
+miim_timeout_usec.BCM88750=300000
+
+
+##initialization for warmboot
+stable_location.BCM88750=3
+stable_size.BCM88750=200000
+scache_filename.BCM88750=fe1600_warmboot.mem
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+# Support (and configure on init) packet processing features.
+# If not defined - only traffic management capabilities are enabled.
+packet_processing=1
+
+## PCP (Petra Co-Processor) features
+#pcp_elk.BCM88640_A0=1
+#pcp_oam.BCM88640_A0=1
+#pcp_dma.BCM88640_A0=1
+
+## Set/Override TDM related config variables
+#tdm.BCM88640_A0=1
+
+# If set, always configures synthesizers, even if the configured rate is
+# equal to
+# their nominal rate. Can be disabled to speedup bringup time
+# (keep in mind that if disabled, changing a synt to a non-nominal freq and
+# than back to nominal will not work
+#synt_over.BCM88640_A0=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88640_A0=100000000
+synt_ddr.BCM88640_A0=125000000
+synt_phy.BCM88640_A0=156250000
+
+## Scache initialization for warmboot persistent storage.
+## Valid values: 2: Store in dram. 3: Store in a file.
+stable_location=3
+stable_filename=./warmboot_data
+stable_flags=0
+stable_size=1000000000
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88640=1
+logical_port_drop.BCM88640=-1
+
+#logical_port_mim_in.BCM88640=2
+#logical_port_mim_out.BCM88640=3
+
+## IPV6 tunnel
+bcm886xx_ipv6_tunnel_enable=1
+
+## Inlif Profile Management Mode - QoS L3 L2 marking mode
+#
+# BCM88660 ONLY
+#
+# QoS L3 L2 marking allows changing the DSCP and/or EXP values
+# of IP and/or MPLS packets according to the incoming port
+# (or inlif), and the Traffic Class/Drop Precedence.
+#
+# The inlif profile is used to control the DSCP/EXP marking.
+# This SOC property controls which mode is used for the inlif profile:
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the DSCP/EXP marking).
+# 0: Advanced mode (the user controls which inlif profile values perform DSCP/EXP marking directly).
+#bcm886xx_qos_l3_l2_marking=1
+
+## Unicast RPF mode per RIF
+#
+# This SOC property allows the user to set the unicast RPF mode - loose, strict or disabled - per RIF.
+# If disabled, the unicast RPF mode of a RIF is set globally.
+# Options: 0 / 1
+
+# bcm886xx_l3_ingress_urpf_enable=1
+
+## BOS handling mode
+# BCM8866X ONLY
+#
+# There are two ways to handle BOS, controlled by bcm886xx_mpls_termination_mode:
+# 0 - Use BOS as key in lookup.
+# 1 - Don't use it (except for reserved labels).
+#
+#bcm886xx_mpls_termination_key_mode=0
+
+# Color resolution mode allows the user to have more detailed metering color information.
+# BCM88660 ONLY
+#
+# Options: 0/1
+# 0: A red result from both Ethernet policer and policer implies DP=3.
+# 1: A red result from the policer implies that DP=2, while a red result from rate (Ethernet policer) implies DP=3.
+#policer_color_resolution_mode=1
+
+## Inlif Profile Management Mode - Disable Same Interface Filter
+# BCM8866X ONLY
+#
+# Controls which mode is used for the inlif profile management.
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the same-interface filter).
+# 0: Advanced mode (the user controls which inlif profile values have the same-interface filter disabled for them).
+#bcm886xx_logical_interface_bridge_filter_enable=1
+
+## Default Block Forwarding Strength
+#
+# Configure the default forwarding strength of blocks.
+#
+# SOC Properties:
+#block_trap_strength_vtt - VTT block forwarding strength
+#block_trap_strength_flp - FLP block forwarding strength
+#block_trap_strength_hash - SLB block forwarding strength (BCM8866X ONLY)
+#block_trap_strength_pmf_0 - PMF 1st lookup forwarding strength
+#block_trap_strength_pmf_1 - PMF 2nd lookup forwarding strength
+#
+# Options: 0-7
+
+## Stateful Load Balancing
+# BCM8866X ONLY
+#
+# Stateful Load Balancing (SLB) allows the load balancing of ECMP and LAG
+# groups to become stateful.
+# In standard load balancing, removing a member from the ECMP/LAG
+# group may affect the selected member, since the formula
+# depends on group size.
+# In stateful load balancing the member is selected once and saved.
+# Later, the member is always retrieved, and does not depend on
+# the size of the LAG/ECMP group.
+#
+# resilient_hash_enable - Enable/disable SLB. Values:
+# 1 - Enable SLB.
+# 0 - Disable SLB.
+#resilient_hash_enable=1
+
+
+#Make Arad SOC properties work for Arad+, by mapping the BCM88660 suffix to BCM88650
+soc_family.BCM88660=BCM88650
+#Make Arad SOC properties work for Ardon, by mapping the BCM88202 suffix to BCM88650
+soc_family.BCM88202=BCM88650
+
+# Use different mymac addresses for ipv4 and ipv6 when using vrrp for mymac termination.
+#l3_vrrp_ipv6_distinct=1
+
+# Enable multiple mymac termination mode. In order to enable it, also set l3_vrrp_ipv6_distinct=0 and
+# l3_vrrp_max_vid=0 since vrrp and multiple mymac mode can't co exist.
+#l3_multiple_mymac_termination_enable=1
+
+# Distinguish between ipv4 and all other l3 protocols when multiple mymac terminating
+#l3_multiple_mymac_termination_mode=1
+
+# Usually the final DP given by the meter (or the In-DP) is unchanged, and can be from 0-3.
+# When this SOC property is set to 1, when the final INGRESS DP is 2, it is mapped to 1 instead,
+# and thus only the values 0-1 and 3 can be output.
+# This has no effect when policer_color_resolution_mode=1.
+#custom_feature_always_map_result_dp_2_to_1=1
+
+#
+# Enable L3 Source Binds for DPoE SAV
+#
+l3_source_bind_mode=IP
+l3_source_bind_subnet_mode=IP
+ipv4_num_vrfs = 4096
+
+#
+# Enable ARP checking for L3 Source Binds
+#
+# This feature is not currently used.
+#
+# Valid values for custom_feature_l3_source_bind_arp_relay:
+# 0 - disabled
+# 1 - downstream ARP checking
+# 2 - upstream ARP checking
+# 3 - both downstream and upstream ARP checking
+#
+#custom_feature_l3_source_bind_arp_relay=2
diff --git a/bal_release/3rdparty/bcm-sdk/rc/bal/readme.txt b/bal_release/3rdparty/bcm-sdk/rc/bal/readme.txt
new file mode 100644
index 0000000..65ea330
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/bal/readme.txt
@@ -0,0 +1,12 @@
+This directory contains bcm files that are needed in the BAL file system to bring up
+the bal_core or bal_op_agent.
+For bal_op_agent,
+User should also copy the bal_autostart.ini from P4 BAL branch ~cur/scripts/ to the same BAL file system.
+
+The currently supported bcm_sdk version is 6.5.3
+.
+|-- bal_config.ini
+|-- config.bcm
+`-- rpc.soc.template
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/bal/rpc.soc.template b/bal_release/3rdparty/bcm-sdk/rc/bal/rpc.soc.template
new file mode 100755
index 0000000..f119730
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/bal/rpc.soc.template
@@ -0,0 +1,25 @@
+cpudb newdb
+
+cpudb add key=0x1 local=t
+
+cpudb add key=0x2
+
+cts atp trans sock server start
+
+cts atp cos=0 vlan=1
+
+cte reg mode=atp
+
+# DIP token is to be replaced by an IP address supplied by application's command line option. Please do not remove or change this line - it is mandatory.
+cts atp trans sock inst dk=0x2 dip=$DIP$
+
+rpc nonexthop
+
+rpc start
+
+dispatch attach 2 client 0 0x2
+
+sleep 1
+
+cte echo string="!> tr 141" mode=atp dk=0x2
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/bal.soc b/bal_release/3rdparty/bcm-sdk/rc/kt2/bal.soc
new file mode 100755
index 0000000..d209d10
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/bal.soc
@@ -0,0 +1,20 @@
+port xe0,xe1,xe2,xe3,xe4,xe5 lanes 4
+
+cpudb newdb
+
+cpudb add key=0x1
+
+cpudb add key=0x2 local=t
+
+cts atp trans sock server start
+
+cts atp cos=0 vlan=1
+
+cte reg mode=atp
+
+cts atp trans sock inst dk=0x1 dip=10.25.8.25
+
+rpc nonexthop
+
+rpc start
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/bcm.user b/bal_release/3rdparty/bcm-sdk/rc/kt2/bcm.user
new file mode 100755
index 0000000..0e3d484
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/bcm.user
Binary files differ
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-kernel-bde.ko b/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-kernel-bde.ko
new file mode 100755
index 0000000..5031d17
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-kernel-bde.ko
Binary files differ
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-user-bde.ko b/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-user-bde.ko
new file mode 100755
index 0000000..0f54e9b
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/linux-user-bde.ko
Binary files differ
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/rc.soc b/bal_release/3rdparty/bcm-sdk/rc/kt2/rc.soc
new file mode 100755
index 0000000..7bf9ce4
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/rc.soc
@@ -0,0 +1,1686 @@
+# $Id: rc.soc 1.192 Broadcom SDK $
+# $Copyright: Copyright 2012 Broadcom Corporation.
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified
+# or distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom
+# (an "Authorized License"). Except as set forth in an Authorized
+# License, Broadcom grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and
+# Broadcom expressly reserves all rights in and to the Software
+# and all intellectual property rights therein. IF YOU HAVE
+# NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
+# IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
+# PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+# OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+# BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
+# INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
+# ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
+# TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
+# THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
+# WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+# ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
+#
+# Initialization RC (run commands) file
+#
+# These are default commands that are read and executed by default
+# when BCM boots up. Typically this file is called rc.soc and resides
+# in the flash filesystem, NVRAM, or disk.
+#
+# Board Configuration Setting
+#
+# This file uses configuration properties to know on which board
+# it is running. Currently one of following settings must be made:
+#
+# BCM95670K8 config add herc8=1
+# BCM95690K24 config add draco_b2b=1
+# BCM95690K24S config add draco_stk=1
+# BCM95690R24 config add galahad=1
+# BCM95690R24S config add merlin=1
+# BCM95690R48S config add lancelot=1
+# BCM95691K12 config add draco_k12=1
+# White Knight config add white_knight=1 (not shipping)
+# Black Knight config add black_knight=1 (not shipping)
+# BCM95673K2S config add twolynx=1
+# BCM95673R8 config add herculynx=1
+# BCM95673R24S config add lynxalittle=1
+# BCM95673R48S config add lynxalot=1
+# BCM95695P24SX_10 config add guenevere=1
+# BCM95650K24 config add magnum=1 (automatic for 5650L)
+# BCM95675 config add herc8_15=1
+# BCM95650R24 config add tuc24_ref=1
+# BCM95695P48LM config add lm48p=1
+# BCM95695P48LM-10 config add lm48p_B=1
+# BCM956504P48LM-10 config add lm48p_C=1
+# BCM956504P48LM-20 config add lm48p_C=1
+# BCM956504P48LM-50 config add lm48p_D=1
+# BCM956504P48POEREF config add fbpoe=1
+# BCM956504P24REF P0 config add fb24=1
+# BCM956504P24 P0 config add fb24=1
+# BCM956102P48 config add felix48=1
+# BCM953300P24REF config add mirage24=1
+# BCM956800K20C config add bradley_1g=1
+# BCM956700K16 config add humv=1
+# BCM956800K20 config add bradley=1
+# BCM956580K16 config add goldwing=1
+# BCM956314P24REF config add bcm56314p24ref=1
+# BCM956024P48REF config add BCM956024P48REF=1
+# BCM956224P48REF config add BCM956224P48REF=1
+# BCM956224R50T config add BCM956224R50T=1
+# BCM956024R50T config add BCM956024R50T=1
+# BCM56820K24XG config add BCM56820K24XG=1
+# BCM953314R24GS config add BCM953314R24GS=1
+# BCM953314K24 config add BCM953314K24=1
+# BCM956820R24XG config add BCM956820R24XG=1
+
+if $?BCM56146_A0 \
+ 'local BCM56146 1'
+
+if $?BCM56147_A0 \
+ 'local BCM56147 1'
+
+
+if $?1 "echo rc: arguments not supported; exit"
+if !$?unit "echo rc: no current unit; exit"
+
+echo "rc: unit $unit device $devname"
+local quiet no
+local echo echo
+local rcdone \$rc$unit
+if !"expr $rcdone + 0" "local echo noecho; local quiet yes"
+
+# Set convenience local variables
+
+# simulation related
+#if $?plisim \
+# "local no_bcm 1"
+if $?quickturn || $?plisim \
+ "local simulator 1"
+
+# board related
+if $?galahad \
+ "local draco_b2b 1"
+if $?black_knight || $?white_knight || $?merlin \
+ "local draco_herc4 1"
+
+# chip related
+if $?PETRAB_A0 \
+ 'rcload dune.soc ; exit'
+
+
+if $?BCM88750_A0 || $?BCM88750_B0 || $?BCM88755_B0 || $?BCM88754_A0\
+ 'rcload dfe.soc ; exit'
+
+if $?ARAD_A0 || $?ARAD_B0 || $?ARAD_B1 || $?BCM88650_A0 || $?BCM88650_B0 || $?BCM88650_B1 || $?BCM88350_B1 || $?BCM88351_B1 || \
+ $?BCM88450_B1 || $?BCM88451_B1 || $?BCM88550_B1 || $?BCM88551_B1 || $?BCM88552_B1 || $?BCM88651_B1 || $?BCM88654_B1 || $?ARADPLUS_A0 || $?BCM88360_A0 || $?BCM88361_A0 || \
+ $?BCM88460_A0 || $?BCM88461_A0 || $?BCM88560_A0 || $?BCM88561_A0 || $?BCM88562_A0 || $?BCM88661_A0 || $?BCM88664_A0 \
+ 'rcload arad.soc ; exit'
+
+if $?BCM88850_P3 \
+ 'exit'
+
+
+
+
+
+
+if $?ACP \
+ 'exit'
+
+if !"expr $pcidev + 0 == 0x5650" \
+ "local magnum 1"
+if $?drac || $?drac15 \
+ "local drac_any 1"
+if $?lynx || $?lynx15 \
+ "local lynx_any 1"
+if $?tucana || $?magnum \
+ "local tucana_any 1"
+if $?herc || $?herc15 \
+ "local herc_any 1"
+if $?firebolt || $?firebolt2 || $?helix || \
+ $?felix || $?helix15 || $?felix15 || $?raptor || $?raven || $?hawkeye\
+ "local firebolt_any 1"
+if !"expr $pcidev + 0 == 0xb501" \
+ "local firebolt_10x4 1"
+if $?easyrider \
+ "local easyrider_any 1"
+if !"expr $pcidev + 0 == 0xb602" \
+ "local easyrider_1x1 1"
+if $?bradley || $?humv || $?goldwing \
+ "local bradley_any 1"
+if $?drac_any || $?lynx_any || $?tucana_any \
+ "local xgs12_switch 1"
+if $?firebolt_any || $?easyrider_any || $?bradley_any \
+ "local xgs3_switch 1"
+if $?xgs12_switch || $?xgs3_switch \
+ "local xgs_switch 1"
+if $?herc_any \
+ "local xgs_fabric 1"
+if $?xgs_fabric || $?xgs_switch \
+ "local xgs 1"
+if !$?xgs \
+ "local strata 1"
+if $?strata && !$?gsl \
+ "local PBMP_ALL 0x0bffffff"
+if $?strata && $?gsl \
+ "local PBMP_ALL 0x080000ff"
+if $?BCM56214_A0 || $?BCM56014_A0 || $?BCM56215_A0 || \
+ $?BCM56214_A1 || $?BCM56014_A1 || $?BCM56215_A1 && \
+ !$?BCM956024P48REF \
+ "local rap24_ref 1"
+
+if $?BCM5655_A0 || $?BCM5655_B0 \
+ "local tucana_nohg 1"
+
+if $?BCM956024P48REF || $?BCM956224P48REF || $?BCM956024R50T || \
+ $?BCM956224R50T \
+ "local raven_eb_48p 1"
+
+if $?BCM953314R24GS \
+ "local hawkeye_p24 1"
+
+if $?BCM953314K24 \
+ "local hawkeye_k24 1"
+
+if $?firebolt_any && $?lm48p || $?lm48p_D \
+ "config add lmfb48=1"
+
+# Set software's wait for S-Channel response to 3 seconds for QuickTurn
+# (Recommend at least 10 seconds if the ARL is 100% busy with inserts.)
+if $?quickturn "stimeout 3000000"
+if $?plisim "stimeout 60000000"
+
+# Direct phy led programming: 5464 activity led becomes link/activity
+if $?drac_any && $?lancelot || $?lynxalot || $?guenevere \
+ "config add phy_led_ctrl=0x18"
+
+# Shutdown threads if system is already running
+if $?triumph3 \
+ "ibodSync off"
+counter off
+linkscan off
+if $?feature_arl_hashed && !$?simulator \
+ "l2mode off"
+if $?feature_ces && $?BCM56440_A0 \
+ "ces off"
+
+# Test on-chip memory before initializing
+#if !$?simulator "init soc; bist l3 arl cbp"
+init soc
+
+# Initialize miscellaneous chip registers
+init misc
+
+# Initialize external TCAM if necessary
+# NOTE : tcam is initialized during "init misc" unless
+# tcam_reset_toggle = 1 is configured
+if "expr $rcdone + 0" && !"expr $tcam_reset_toggle + 0" \
+ "dispatch attach 0 esw 0"
+if !"expr $tcam_reset_toggle + 0" "muxsel 0; muxsel 0x80"
+if !"expr $tcam_reset_toggle + 0" "init tcam; $echo rc: TCAM initialized"
+
+# Initialize the StrataSwitch MMU registers
+init mmu
+
+# Uncomment to turn off Single-Bit Error reporting on 5670
+#if $?herc "m mmu_intcntl pp_sbe_en=0"
+
+# Initialize Cell Free Address Pool
+# NOTE: this should NOT be done unless chip is known to have bad CFAP
+# memory entries that need to be mapped out.
+if $?cfap_tests "$echo rc: Initializing CFAP; cfapinit"
+
+$echo rc: MMU initialized
+
+#
+# Load uKernel
+#
+
+if $?feature_cmicm && !$?rcpu_only && !$ihost_mode\
+ "mcsload 0 ${drivername}_0.srec InitMCS=true; \
+ mcsload 1 ${drivername}_1.srec;"
+
+#
+# Init CLI and BCM API
+#
+# This must be done after the raw register writes to avoid having state
+# clobbered. NOTE: Tables are cleared by "init bcm" below. If
+# table modifications are required, put them after "init bcm". Some
+# registers might also be affected.
+#
+
+if !$?no_bcm \
+ "init bcm; \
+ $echo rc: BCM driver initialized"
+
+if $?no_bcm \
+ "$echo rc: *** NOT initializing BCM driver ***"
+
+if $?no_bcm && $?strata \
+ 'write vtable 0 1 VLAN_TAG=0,PORT_BITMAP=0,UT_PORT_BITMAP=0; \
+ insert vtable VLAN_TAG=1,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ local pv \
+ VLAN_TAG=1,SP_ST=3,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ write ptable 0 32 PTYPE=0; \
+ if !$?gsl "write ptable 0 24 $pv,PTYPE=1"; \
+ if !$?gsl "write ptable 24 2 $pv,PTYPE=2"; \
+ if $?gsl "write ptable 0 8 $pv,PTYPE=2"; \
+ write ptable 27 1 $pv,PTYPE=3; \
+ local pv'
+
+# Turn on mirroring of hardware ARL operations into software ARL table.
+if $?feature_arl_sorted \
+ "arlmode intr_dma; \
+ $echo rc: ARL DMA shadowing enabled"
+
+if $?feature_arl_hashed && !$?simulator && !$?rcpu_only \
+ "l2mode interval=3000000; \
+ $echo rc: L2 Table shadowing enabled"
+
+# If running BCM library, start linkscan task and set port modes
+
+if !$?no_bcm && !$?rcpu_only \
+ "linkscan 250000; \
+ port fe,ge linkscan=on autoneg=on \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port st linkscan=on txpause=false rxpause=false; \
+ port xe,ce linkscan=on autoneg=off \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?rcpu_only \
+ "linkscan 250000; \
+ port e linkscan=on; \
+ port st linkscan=on; \
+ port xe linkscan=on; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?shadow \
+ "port il linkscan=on; \
+ $echo rc: Interlaken Port mode initialized"
+
+# No spanning tree is running, so put ports all in the forwarding state
+# stp support not available for shadow device.
+
+if !$?no_bcm && !$?shadow \
+ "stg stp 1 all forward"
+
+# Start counter task unless already started by "init bcm" above.
+if $?plisim "local dma false"
+if !$?plisim "local dma true"
+if $?device_eb_vli "local dma false"
+if $?no_bcm && !$?rcpu_only\
+ "counter Interval=1000 Pbm=all Dma=$dma; \
+ $echo rc: Counter collection enabled"
+if $?rcpu_only \
+ "counter Interval=2000000 Pbm=all Dma=false; \
+ $echo rc: Counter collection enabled"
+
+# Resynchronize the saved values kept by the 'show counter' command.
+if !$?simulator \
+ "counter sync"
+
+# By default, dump data of packets that go to CPU.
+if !$?testinit \
+ "pw report +raw"
+
+# Default LED processor program for various SDKs and reference designs.
+# Source code can be found in $SDK/led/examples.
+
+if !$?p48 "local ledcode '\
+ E0 28 60 7F 67 2F 67 6B 06 7F 80 D2 1A 74 01 12 \
+ 7E 85 05 D2 0F 71 19 52 00 12 7D 85 05 D2 1F 71 \
+ 23 52 00 12 7C 85 05 D2 05 71 2D 52 00 3A 68 32 \
+ 00 97 75 3B 12 A0 FE 7F 02 0A 50 32 01 97 75 47 \
+ 12 BA FE 7F 02 0A 50 12 BA FE 7F 95 75 59 85 12 \
+ A0 FE 7F 95 75 A8 85 77 9A 12 A0 FE 7F 95 75 63 \
+ 85 77 A1 16 7C DA 02 71 A1 77 A8 32 05 97 71 76 \
+ 06 7D D2 01 71 9A 06 7F 67 93 75 9A 32 02 97 71 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 7E D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5605.hex
+
+if $?p48 "local ledcode '\
+ E0 28 60 7F 67 43 67 3C 67 35 67 2F 06 7F 80 D2 \
+ 18 74 01 28 60 7F 67 9B 67 89 67 BF 67 83 67 3C \
+ 67 73 67 68 67 5D 06 7F 80 D2 1A 74 13 3A 70 67 \
+ AD 71 C3 77 BF 32 03 97 71 C3 77 BF 32 05 97 71 \
+ C3 77 BF 12 BA FE 7F 32 01 97 75 4F 02 06 50 32 \
+ 00 97 75 57 02 06 50 95 75 C3 85 77 BF 67 AD 75 \
+ BF 32 04 97 71 C3 77 BF 67 AD 75 BF 32 03 97 71 \
+ C3 77 BF 67 AD 75 BF 32 03 97 71 BF 32 04 97 71 \
+ BF 77 C3 67 B6 71 C3 77 BF 12 A0 FE 7F 32 00 97 \
+ 75 95 02 06 50 95 75 C3 85 77 BF 12 BA FE 7F 32 \
+ 01 97 75 A7 02 06 50 95 75 C3 85 77 BF 06 7F 12 \
+ 80 F8 15 1A 00 57 06 7F 12 80 F8 15 1A 07 57 32 \
+ 0F 87 57 32 0E 87 57'" # p48.hex
+
+if $?herc && !$?black_knight "local ledcode '\
+ 02 01 67 36 29 32 08 D7 87 32 07 D7 87 32 01 D7 \
+ 87 32 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 \
+ 74 24 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 \
+ 87 91 74 2D 3A 28 10 DA 07 75 3E FA 02 57 EA 06 \
+ 57'" # sdk5670.hex
+
+if $?herc && $?black_knight "local ledcode '\
+ 2A 03 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 00 \
+ D7 87 2A 06 32 08 D7 87 32 07 D7 87 32 01 D7 87 \
+ 32 00 D7 87 3A 08'" # knigget.hex
+
+if $?drac_any "local ledcode '\
+ E0 28 60 C3 67 4E 67 8A 06 C3 80 D2 0C 74 01 28 \
+ 60 C3 32 00 D7 87 32 01 D7 87 32 07 D7 87 32 08 \
+ D7 87 32 0F 87 32 0F 87 32 0F 87 32 0F 87 12 C2 \
+ 85 05 D2 0F 71 38 52 00 12 C1 85 05 D2 1F 71 42 \
+ 52 00 12 C0 85 05 D2 05 71 4C 52 00 3A 38 32 00 \
+ 97 75 5A 12 A0 FE C3 02 0A 50 32 01 97 75 66 12 \
+ AD FE C3 02 0A 50 12 AD FE C3 95 75 78 85 12 A0 \
+ FE C3 95 75 C0 85 77 B9 12 A0 FE C3 95 75 82 85 \
+ 77 C7 16 C0 DA 02 71 C7 77 C0 32 05 97 71 9A 32 \
+ 02 97 71 B9 06 C1 D2 01 71 B9 06 C3 67 B2 75 B9 \
+ 32 03 97 71 C0 32 04 97 75 C7 06 C2 D2 07 71 C7 \
+ 77 C0 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5690.hex
+
+if $?draco_k12 "local ledcode '\
+ 02 0B A2 01 28 A2 01 60 C3 67 32 67 6E 06 C3 90 \
+ 75 02 12 C2 85 05 D2 0F 71 1C 52 00 12 C1 85 05 \
+ D2 1F 71 26 52 00 12 C0 85 05 D2 05 71 30 52 00 \
+ 3A 30 32 00 97 75 3E 12 A0 FE C3 02 0A 50 32 01 \
+ 97 75 4A 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 \
+ 5C 85 12 A0 FE C3 95 75 A6 85 77 9F 12 A0 FE C3 \
+ 95 75 66 85 77 AD 16 C0 DA 02 71 AD 77 A6 32 05 \
+ 97 71 7E 32 02 97 71 9F 06 C1 D2 01 71 9F 06 C3 \
+ 67 96 75 9F 32 03 97 71 A6 32 04 97 75 AD 06 C2 \
+ D2 07 71 AD 77 A6 12 80 A2 01 F8 15 1A 00 57 32 \
+ 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 \
+ 32 0E 87 57'" # k12-5690.hex
+
+if $?herc && $?white_knight "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 07 \
+ D7 87 32 01 D7 87 32 00 D7 87 57'" # wk5670.hex
+
+if $?herc && $?merlin "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # merlin5670.hex
+
+if $?herc && $?lancelot "local ledcode '\
+ 2A 05 67 12 2A 06 67 12 2A 03 67 12 2A 04 67 12 \
+ 3A 10 32 08 D7 87 32 00 D7 87 32 01 D7 87 32 07 \
+ D7 87 57'" # lancelot.hex
+
+if $?xgs_fabric && $?guenevere "local ledcode '\
+ 2A 04 67 0A 2A 05 67 0A 3A 04 32 07 D7 87 32 00 \
+ 32 01 B7 D7 87 57'" # guenevere5670.hex
+
+if $?drac_any && $?white_knight "local ledcode '\
+ E0 28 60 C3 67 2f 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # wk5690.hex
+
+if $?drac_any && $?merlin "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # merlin5690.hex
+
+if $?drac_any && $?galahad "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # galahad.hex
+
+if $?drac_any && $?lm "local ledcode '\
+E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+32 0F 87 57 32 0F 87 32 0E 87 57'" # lm5690.hex
+
+if $?twolynx "local ledcode '\
+ 2A 01 67 0A 2A 00 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # twolynx.hex
+
+if $?lynx_any && $?herculynx || $?lynxalot || $?lm || $?guenevere \
+ "local ledcode '\
+12 C0 85 05 D2 03 71 0A 52 00 2A 00 67 10 3A 04 \
+32 08 D7 87 06 C0 D2 01 71 22 32 0F 87 32 0F 87 \
+77 2A 32 00 D7 87 32 01 D7 87 32 07 D7 87 57'" # herculynx.hex
+
+if $?tucana && !$?magnum "local ledcode '\
+ E0 67 23 D2 18 74 01 02 20 67 23 D2 38 74 09 02 \
+ 18 67 23 D2 1C 74 11 E9 02 80 45 80 81 DA 0D 74 \
+ 1A 3A 68 28 60 E3 67 4A 67 36 06 E4 30 87 06 E5 \
+ 30 87 06 E3 80 57 32 00 97 71 45 32 01 97 71 45 \
+ 02 0F 60 E5 57 02 0E 60 E5 57 06 E3 12 A0 F8 15 \
+ 1A 00 75 59 02 0E 60 E4 57 02 0F 60 E4 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC 67 5A 67 9C 06 FA 67 DA 06 FB 67 DA \
+ 06 FC 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0E 74 51 3A 70 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 D7 85 77 D1 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 D4 16 FF DA 02 02 FA 71 D4 77 D7 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 D1 06 FC 67 CA 02 FB 75 \
+ D1 32 02 97 71 D1 32 03 97 71 D7 32 04 97 75 D4 \
+ 06 FD D2 07 02 FB 71 D4 77 D7 12 A0 F8 15 1A 00 \
+ 57 42 00 57 42 01 57 42 02 57 D2 02 74 E3 32 0F \
+ 87 77 E6 32 0E 87 D2 01 74 EE 32 0F 87 57 32 0E \
+ 87 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 75 09 A2 01 60 FC 28 67 37 67 73 \
+ 06 FB 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 3A 70 32 00 97 75 43 12 C0 FE FC \
+ 02 0A 50 32 01 97 75 4F 12 DC FE FC 02 0A 50 12 \
+ DC FE FC 95 75 61 85 12 C0 FE FC 95 75 B0 85 77 \
+ A2 12 C0 FE FC 95 75 6B 85 77 A9 16 FF DA 02 71 \
+ A9 77 B0 32 05 97 71 7E 06 FE D2 01 71 A2 06 FC \
+ 67 9B 75 A2 32 02 97 71 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 FD D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0F 87 32 0F 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57'" # magnum_sdk.hex
+
+if $?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 71 10 60 FC 28 67 D0 67 C0 77 19 \
+ A2 01 60 FC 28 67 40 67 7C 06 FB 80 D2 1C 74 01 \
+ 12 FD 85 05 D2 0F 71 2A 52 00 12 FE 85 05 D2 1F \
+ 71 34 52 00 12 FF 85 05 D2 05 71 3E 52 00 3A 68 \
+ 32 00 97 75 4C 12 C0 FE FC 02 0A 50 32 01 97 75 \
+ 58 12 DC FE FC 02 0A 50 12 DC FE FC 95 75 6A 85 \
+ 12 C0 FE FC 95 75 B9 85 77 AB 12 C0 FE FC 95 75 \
+ 74 85 77 B2 16 FF DA 02 71 B2 77 B9 32 05 97 71 \
+ 87 06 FE D2 01 71 AB 06 FC 67 A4 75 AB 32 02 97 \
+ 71 AB 32 03 97 71 B9 32 04 97 75 B2 06 FD D2 07 \
+ 71 B2 77 B9 12 A0 F8 15 1A 00 57 32 0F 87 32 0F \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 \
+ 02 0E 32 00 97 71 CD 32 01 97 71 CD 80 30 87 57 \
+ 06 FC 12 A0 F8 15 1A 00 02 0F 75 DD 90 30 87 57'" # magnum.hex
+
+if $?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC D2 18 71 0E 67 E9 67 D9 77 1A 67 5A \
+ 67 9C 06 FA 67 D0 06 FB 67 D0 06 FC 80 D2 1C 74 \
+ 01 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0D 74 51 3A 68 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 CD 85 77 C7 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 CA 16 FF DA 02 02 FA 71 CA 77 CD 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 C7 06 FC 67 C0 02 FB 75 \
+ C7 32 02 97 71 C7 32 03 97 71 CD 32 04 97 75 CA \
+ 12 A0 F8 15 1A 00 57 42 FF 57 42 FE 57 42 EF 57 \
+ 30 87 98 98 98 98 30 87 57 02 0E 32 00 97 71 E6 \
+ 32 01 97 71 E6 80 30 87 57 06 FC 12 A0 F8 15 1A \
+ 00 02 0F 75 F6 90 30 87 57'" # tuc24_ref.hex
+
+if $?herc8_15 "local ledcode '\
+ 02 01 28 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 \
+ 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 74 22 \
+ 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 87 91 \
+ 74 2B 3A 28'" # sdk5675.hex
+
+if $?drac_any && $?lm "local ledcode '\
+ E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+ 00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+ 75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+ C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+ A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+ C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+ 71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+ 71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57 00 00 00 00 00'" # lm5690.hex
+
+if $?drac_any && $?lm48p "local ledcode '\
+ E0 28 60 C3 67 7C 06 C3 80 28 60 C3 67 7C 67 40 \
+ 06 C3 90 28 60 C3 67 40 06 C3 80 80 D2 0C 74 01 \
+ 12 C2 85 05 D2 0F 71 2A 52 00 12 C1 85 05 D2 1F \
+ 71 34 52 00 12 C0 85 05 D2 05 71 3E 52 00 3A 30 \
+ 32 00 97 75 4C 12 A0 FE C3 02 0A 50 32 01 97 75 \
+ 58 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 6A 85 \
+ 12 A0 FE C3 95 75 B9 85 77 AB 12 A0 FE C3 95 75 \
+ 74 85 77 B2 16 C0 DA 02 71 B2 77 B9 32 05 97 71 \
+ 8C 32 02 97 71 AB 06 C1 D2 01 71 AB 06 C3 67 A4 \
+ 75 AB 32 03 97 71 B9 32 04 97 75 B2 06 C2 D2 07 \
+ 71 B2 77 B9 12 80 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695.hex
+
+if $?drac_any && $?lm48p_B "local ledcode '\
+ E0 28 60 C3 67 79 06 C3 67 3D 06 C3 80 28 60 C3 \
+ 67 3D 06 C3 67 79 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 27 52 00 12 C1 85 05 D2 1F 71 31 52 \
+ 00 12 C0 85 05 D2 05 71 3B 52 00 3A 30 32 00 97 \
+ 75 49 12 A0 FE C3 02 0A 50 32 01 97 75 55 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 67 85 12 A0 FE \
+ C3 95 75 B6 85 77 A8 12 A0 FE C3 95 75 71 85 77 \
+ AF 16 C0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 C1 D2 01 71 A8 06 C3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 C2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695_10.hex
+
+if $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 55 67 91 06 E3 80 28 60 E3 67 91 \
+ 67 55 06 E3 80 D2 18 74 01 28 60 E3 67 B9 75 26 \
+ 67 CE 67 55 77 2E 32 0E 87 32 08 87 67 C0 06 E3 \
+ 80 D2 1C 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 3A 70 32 00 97 75 61 12 A0 FE E3 02 0A \
+ 50 32 01 97 75 6D 12 BC FE E3 02 0A 50 12 BC FE \
+ E3 95 75 7F 85 12 A0 FE E3 95 75 CE 85 77 C0 12 \
+ A0 FE E3 95 75 89 85 77 C7 16 E0 DA 02 71 C7 77 \
+ CE 32 05 97 71 A1 32 02 97 71 C0 06 E1 D2 01 71 \
+ C0 06 E3 67 B9 75 C0 32 03 97 71 CE 32 04 97 75 \
+ C7 06 E2 D2 07 71 C7 77 CE 12 80 F8 15 1A 00 57 \
+ 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F \
+ 87 32 0E 87 57'" # sdk56504.hex
+
+#Led program for new rev of FB SDK and Ref design
+if $?firebolt_any && !$?fb24 "local ledcode '\
+ E0 28 60 E3 67 4B 67 87 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AF 75 1C 67 C4 67 4B 77 24 32 0E 87 32 \
+ 08 87 67 B6 06 E3 80 D2 1C 74 0F 12 E2 85 05 D2 \
+ 0F 71 35 52 00 12 E1 85 05 D2 1F 71 3F 52 00 12 \
+ E0 85 05 D2 05 71 49 52 00 3A 70 32 00 97 75 57 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 63 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 75 85 12 A0 FE E3 95 \
+ 75 C4 85 77 B6 12 A0 FE E3 95 75 7F 85 77 BD 16 \
+ E0 DA 02 71 BD 77 C4 32 05 97 71 97 32 02 97 71 \
+ B6 06 E1 D2 01 71 B6 06 E3 67 AF 75 B6 32 03 97 \
+ 71 C4 32 04 97 75 BD 06 E2 D2 07 71 BD 77 C4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56504ref.hex
+
+#Override Default Firebolt LED program for Line Module
+if $?lm && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 79 06 E3 67 3D 06 E3 80 28 60 E3 \
+ 67 3D 06 E3 67 79 06 E3 80 D2 18 74 01 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 60 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B6 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AF 16 E0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 E2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p56504.hex
+
+#Override Default Firebolt LED program for Line Module -50 version
+if $?lm && $?lm48p_D && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 6D 06 E3 67 31 06 E3 80 D2 18 74 \
+ 01 12 E2 85 05 D2 0F 71 1B 52 00 12 E1 85 05 D2 \
+ 1F 71 25 52 00 12 E0 85 05 D2 05 71 2F 52 00 3A \
+ 60 32 00 97 75 3D 12 A0 FE E3 02 0A 50 32 01 97 \
+ 75 49 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 5B \
+ 85 12 A0 FE E3 95 75 AA 85 77 9C 12 A0 FE E3 95 \
+ 75 65 85 77 A3 16 E0 DA 02 71 A3 77 AA 32 05 97 \
+ 71 7D 32 02 97 71 9C 06 E1 D2 01 71 9C 06 E3 67 \
+ 95 75 9C 32 03 97 71 AA 32 04 97 75 A3 06 E2 D2 \
+ 07 71 A3 77 AA 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # lm48p56504_50.hex
+
+if $?lm && $?firebolt_10x4 "local ledcode '\
+ 02 18 28 32 07 67 1E 75 0A D7 87 32 01 D7 87 32 \
+ 00 D7 87 32 08 D7 87 80 D2 1C 74 02 3A 0C 12 80 \
+ F8 15 1A 00 57 '" # lm12pcx456501.hex
+
+if $?fbpoe && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 85 67 49 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AD 75 1A 67 C2 77 20 32 0E 87 32 08 87 \
+ 67 49 06 E3 80 D2 1A 74 0F 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 32 00 97 75 55 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 61 12 BA FE E3 02 0A \
+ 50 12 BA FE E3 95 75 73 85 12 A0 FE E3 95 75 C2 \
+ 85 77 B4 12 A0 FE E3 95 75 7D 85 77 BB 16 E0 DA \
+ 02 71 BB 77 C2 32 05 97 71 95 32 02 97 71 B4 06 \
+ E1 D2 01 71 B4 06 E3 67 AD 75 B4 32 03 97 71 C2 \
+ 32 04 97 75 BB 06 E2 D2 07 71 BB 77 C2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # poe48p56504.hex
+
+#Override Default Firebolt LED program for felix
+if $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0E 87 32 0F 87 57'" # sdk56102.hex
+
+#Override Default Felix LED program for felix48
+if $?felix48 && $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # felix48.hex
+
+if $?easyrider_any "local ledcode '\
+ E0 28 60 E3 67 59 67 95 06 E3 80 28 60 E3 67 95 \
+ 67 59 06 E3 80 D2 0C 74 01 28 60 E3 67 BD 75 26 \
+ 67 D2 67 59 77 2E 32 0E 87 32 08 87 67 C4 06 E3 \
+ 80 D2 0D 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 67 C4 67 C4 3A 38 32 00 97 75 65 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 71 12 AD FE E3 02 0A \
+ 50 12 AD FE E3 95 75 83 85 12 A0 FE E3 95 75 D2 \
+ 85 77 C4 12 A0 FE E3 95 75 8D 85 77 CB 16 E0 DA \
+ 02 71 CB 77 D2 32 05 97 71 A5 32 02 97 71 C4 06 \
+ E1 D2 01 71 C4 06 E3 67 BD 75 C4 32 03 97 71 D2 \
+ 32 04 97 75 CB 06 E2 D2 07 71 CB 77 D2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # sdk56601.hex
+
+#Override Default Easyrider LED program for 56602
+if $?easyrider_1x1 "local ledcode '\
+ E0 60 E1 67 7C 67 7C 06 E1 80 D2 0C 74 01 02 0C \
+ 28 60 E1 67 75 75 1D 67 8A 67 39 77 25 32 0E 87 \
+ 32 08 87 67 7C 06 E1 D2 00 02 00 74 10 12 E0 85 \
+ 05 D2 05 71 37 52 00 3A 38 32 00 97 75 45 12 A0 \
+ FE E1 02 0A 50 32 01 97 75 51 12 AD FE E1 02 0A \
+ 50 12 AD FE E1 95 75 63 85 12 A0 FE E1 95 75 8A \
+ 85 77 7C 12 A0 FE E1 95 75 6D 85 77 83 16 E0 DA \
+ 02 71 83 77 8A 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # sdk56602.hex
+
+#Override Default LED program for 53300
+if $?mirage24 "local ledcode '\
+ E0 28 60 E3 67 6B 67 2F 06 E3 80 D2 18 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A2 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 9E 16 E0 DA 02 71 9E 77 A2 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A2 32 04 97 75 9E 06 E2 D2 07 71 \
+ 9E 77 A2 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E \
+ 87 57 32 0E 87 57'" # sdk53300.hex
+
+#Override Default LED program for 56314
+if $?bcm56314p24ref "local ledcode '\
+ E0 28 60 E3 67 79 67 3D 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 79 67 A8 06 E3 80 D2 1C 74 0F 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 38 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B0 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AC 16 E0 DA 02 71 AC 77 B0 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B0 32 04 97 75 AC 06 E2 D2 07 71 AC 77 \
+ B0 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ 32 0E 87 57'" # bcm956314p24ref.hex
+
+if $?bradley "local ledcode '\
+ E0 28 60 F2 67 1B 06 F2 80 D2 14 74 01 86 F3 12 \
+ F0 85 05 D2 05 71 19 52 00 3A 28 32 00 97 75 27 \
+ 12 A8 FE F2 02 0A 50 32 01 97 75 33 12 BC FE F2 \
+ 02 0A 50 12 BC FE F2 95 75 45 85 12 A8 FE F2 95 \
+ 75 91 85 77 57 12 A8 FE F2 95 75 4F 85 77 8A 16 \
+ F0 DA 02 71 8A 77 91 06 F2 12 94 F8 15 02 02 C1 \
+ 74 6E 02 04 C1 74 6E 02 08 C1 74 6E 77 74 C6 F3 \
+ 74 91 77 8A 06 F2 67 7C 75 83 77 91 12 80 F8 15 \
+ 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 \
+ 57 32 0F 87 32 0E 87 57'" # sdk56800.hex
+
+if $?humv "local ledcode '\
+ E0 28 60 F2 67 21 06 F2 80 D2 08 74 0F F2 02 D2 \
+ 12 74 01 86 F3 12 F0 85 05 D2 05 71 1F 52 00 3A \
+ 20 32 00 97 75 2D 12 A8 FE F2 02 0A 50 32 01 97 \
+ 75 39 12 BA FE F2 02 0A 50 12 BA FE F2 95 75 4B \
+ 85 12 A8 FE F2 95 75 97 85 77 5D 12 A8 FE F2 95 \
+ 75 55 85 77 90 16 F0 DA 02 71 90 77 97 06 F2 12 \
+ 94 F8 15 02 02 C1 74 74 02 04 C1 74 74 02 08 C1 \
+ 74 74 77 7A C6 F3 74 97 77 90 06 F2 67 82 75 89 \
+ 77 97 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56700.hex
+
+if $?bradley_1g "local ledcode '\
+ E0 28 60 E3 67 2F 67 6B 06 E3 80 D2 14 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 50 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 B4 FE E3 02 0A 50 12 B4 FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A8 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 A1 16 E0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 E2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 '" # sdk56800c.hex
+
+if $?goldwing "local ledcode '\
+ E0 28 60 F3 D2 10 75 0E 67 3B 67 94 77 12 67 94 \
+ 67 3B 06 F3 80 D2 14 74 01 86 F4 12 F2 85 05 D2 \
+ 0F 71 25 52 00 12 F1 85 05 D2 1F 71 2F 52 00 12 \
+ F0 85 05 D2 05 71 39 52 00 3A 50 32 00 97 75 47 \
+ 12 A8 FE F3 02 0A 50 32 01 97 75 53 12 BC FE F3 \
+ 02 0A 50 12 BC FE F3 95 75 65 85 12 A8 FE F3 95 \
+ 75 C0 85 77 77 12 A8 FE F3 95 75 6F 85 77 B9 16 \
+ F0 DA 02 71 B9 77 C0 06 F3 12 94 F8 15 02 02 C1 \
+ 74 8E 02 04 C1 74 8E 02 08 C1 74 8E 77 B2 C6 F4 \
+ 74 C0 77 B9 06 F3 67 AB 75 B2 32 04 75 B2 32 03 \
+ 97 71 C0 06 F2 D2 07 71 B9 77 C0 12 80 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 '" # sdk56580.hex
+
+if $?humv && $?lm "local ledcode '\
+ 02 04 28 D2 08 74 0A F2 02 28 32 07 67 29 75 11 \
+ D7 87 60 E4 67 30 06 E4 60 E4 67 4C 06 E4 32 08 \
+ D7 87 80 D2 12 74 02 3A 30 12 80 F8 15 1A 00 57 \
+ 06 E4 12 94 F8 15 02 10 C1 70 42 12 D2 FE E4 02 \
+ 0A 50 12 D2 FE E4 95 75 6D 85 77 68 06 E4 12 94 \
+ F8 15 02 20 C1 70 5E 12 C0 FE E4 02 0A 50 12 C0 \
+ FE E4 95 75 6D 85 77 68 32 0E D7 87 57 32 0F D7 \
+ 87 57 '" # lm12p56802.hex
+
+
+if $?raptor "local ledcode '\
+ 02 06 28 60 FF 67 64 67 93 06 FF 80 D2 36 74 02 \
+ 02 04 28 60 FF 67 BB 75 1E 32 0E 87 77 21 32 0F \
+ 87 67 7D 06 FF 80 D2 06 74 12 02 01 28 60 FF 67 \
+ BB 75 38 32 0E 87 77 3B 32 0F 87 67 7D 06 FF 80 \
+ D2 03 74 2C 12 FE 85 05 D2 0F 71 4E 52 00 12 FD \
+ 85 05 D2 1F 71 58 52 00 12 FC 85 05 D2 05 71 62 \
+ 52 00 3A C8 32 01 97 75 76 32 00 97 75 C9 16 FC \
+ DA 02 71 C9 77 D0 32 00 97 75 C2 77 D0 32 00 97 \
+ 75 86 32 0E 87 57 32 01 97 75 8F 32 0E 87 57 32 \
+ 0F 87 57 32 05 97 71 A3 32 02 97 71 C2 06 FD D2 \
+ 01 71 C2 06 FF 67 BB 75 C2 32 03 97 71 D0 32 04 \
+ 97 75 C9 06 FE D2 07 71 C9 77 D0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" # sdk56018.hex
+
+if $?raptor && $?rap24_ref "local ledcode '\
+ 02 06 60 E1 67 48 67 31 06 E1 80 D2 1E 71 02 02 \
+ 05 60 E1 67 48 67 31 06 E1 90 D2 03 74 11 02 02 \
+ 60 E1 67 48 67 31 06 E1 90 D2 00 74 20 86 E0 3A \
+ 38 06 E1 67 50 75 57 28 32 00 32 01 B7 97 75 57 \
+ 16 E0 CA 05 74 5B 77 57 06 E1 67 50 75 57 77 5B \
+ 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00'" # sdk56214.hex
+
+if $?raven_eb_48p "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 71 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024p48ref.hex
+
+if $?BCM956024R50T "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 75 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024r50t.hex
+
+if $?scorpion || $?conqueror "local ledcode '\
+ 02 18 28 60 E1 67 12 06 E1 90 D2 00 74 02 86 E0 \
+ 3A 18 67 2D 75 34 28 32 00 32 01 B7 97 75 38 16 \
+ E0 CA 05 74 38 77 34 67 2D 75 34 77 38 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 \
+ 00 00 00'" #sdk56820.hex
+
+if $?scorpion && $?BCM956820R24XG "local ledcode '\
+ 02 01 28 67 D0 02 02 28 67 D6 67 D0 02 01 28 67 \
+ D6 02 04 28 67 D0 02 03 28 67 D6 67 D0 02 04 28 \
+ 67 D6 02 05 28 67 D0 02 06 28 67 D6 67 D0 02 05 \
+ 28 67 D6 02 07 28 67 D0 02 08 28 67 D6 67 D0 02 \
+ 07 28 67 D6 02 09 28 67 D0 02 0A 28 67 D6 67 D0 \
+ 02 09 28 67 D6 02 0C 28 67 D0 02 0B 28 67 D6 67 \
+ D0 02 0C 28 67 D6 02 0D 28 67 D0 02 0E 28 67 D6 \
+ 67 D0 02 0D 28 67 D6 02 0F 28 67 D0 02 10 28 67 \
+ D6 67 D0 02 0F 28 67 D6 02 11 28 67 D0 02 12 28 \
+ 67 D6 67 D0 02 11 28 67 D6 02 14 28 67 D0 02 13 \
+ 28 67 D6 67 D0 02 14 28 67 D6 02 15 28 67 D0 02 \
+ 16 28 67 D6 67 D0 02 15 28 67 D6 02 17 28 67 D0 \
+ 02 18 28 67 D6 67 D0 02 17 28 67 D6 86 E0 3A 30 \
+ 67 F1 75 F8 77 FC 67 F1 75 F8 28 32 00 32 01 B7 \
+ 97 75 F8 16 E0 CA 05 74 FC 77 F8 67 F1 75 F8 77 \
+ FC 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ '" #bcm956820r24xg.hex
+
+if $?valkyrie "local ledcode '\
+ 02 02 67 A9 67 94 02 03 67 A9 67 94 02 05 67 A9 \
+ 67 94 02 04 67 A9 67 94 02 06 67 A9 67 94 02 07 \
+ 67 A9 67 94 02 12 67 A9 67 94 02 13 67 A9 67 94 \
+ 02 0E 67 A9 67 94 02 0F 67 A9 67 94 02 11 67 A9 \
+ 67 94 02 10 67 A9 67 94 02 1A 67 A9 67 94 02 20 \
+ 67 A9 67 94 02 21 67 A9 67 94 02 22 67 A9 67 94 \
+ 02 23 67 A9 67 94 02 24 67 A9 67 94 02 2F 67 A9 \
+ 67 94 02 2E 67 A9 67 94 02 1B 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56680.hex
+
+if $?valkyrie2 "local ledcode '\
+ 02 1E 67 A9 67 94 02 1F 67 A9 67 94 02 21 67 A9 \
+ 67 94 02 20 67 A9 67 94 02 22 67 A9 67 94 02 23 \
+ 67 A9 67 94 02 24 67 A9 67 94 02 25 67 A9 67 94 \
+ 02 26 67 A9 67 94 02 27 67 A9 67 94 02 29 67 A9 \
+ 67 94 02 28 67 A9 67 94 02 2A 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 02 2E 67 A9 67 94 02 2F 67 A9 67 94 02 31 67 A9 \
+ 67 94 02 30 67 A9 67 94 02 32 67 A9 67 94 02 33 \
+ 67 A9 67 94 02 34 67 A9 67 94 02 35 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56685.hex
+
+if $?hawkeye_p24 "local ledcode '\
+ 02 01 28 60 E3 67 43 67 1C 06 E3 80 D2 19 74 02 \
+ 12 E0 85 05 D2 03 71 1A 52 00 3A 60 32 00 32 01 \
+ B7 97 75 2B 12 E4 FE E3 02 01 50 12 E4 FE E3 95 \
+ 75 3B 85 06 E3 67 55 75 6A 77 5C 16 E0 DA 01 71 \
+ 6A 77 5C 06 E3 67 55 75 6A 32 03 97 71 5C 32 04 \
+ 97 75 6A 77 63 12 A0 F8 15 1A 00 57 32 0E 87 32 \
+ 0F 87 57 32 0F 87 32 0E 87 57 32 0F 87 32 0F 87 \
+ 57'" #bcm953314p24ref.hex
+
+if $?hawkeye_k24 "local ledcode '\
+ 02 01 28 60 E1 67 3D 67 1C 06 E1 80 D2 19 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 30 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 50 16 E0 DA 02 71 4C 77 50 06 E1 67 \
+ 45 75 50 77 4C 12 A0 F8 15 1A 00 57 32 0E 87 57 \
+ 32 0F 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #bcm953314k24.hex
+
+if !"expr $pcidev + 0 == 0xb624" "local ledcode '\
+ 02 1C 28 67 18 02 1D 28 67 18 02 1E 28 67 18 02 \
+ 1F 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56624.hex
+
+if !"expr $pcidev + 0 == 0xb626" "local ledcode '\
+ 02 1A 28 67 22 02 1B 28 67 22 02 1C 28 67 22 02 \
+ 1D 28 67 22 02 1E 28 67 22 02 1F 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56626.hex
+
+if !"expr $pcidev + 0 == 0xb628" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56628.hex
+
+if !"expr $pcidev + 0 == 0xb629" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56629.hex
+
+if !"expr $pcidev + 0 == 0xb634" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb630" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb636" "local ledcode '\
+ 02 2A 28 67 22 02 32 28 67 22 02 1A 28 67 22 02 \
+ 1B 28 67 22 02 1C 28 67 22 02 1D 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56636.hex
+
+if !"expr $pcidev + 0 == 0xb638" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56638.hex
+
+if !"expr $pcidev + 0 == 0xb639" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56639.hex
+
+if !"expr $pcidev + 0 == 0xb334" "local ledcode '\
+ 02 02 28 60 E1 67 3D 67 1C 06 E1 80 D2 1E 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 38 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 4C 16 E0 DA 02 71 50 77 4C 06 E1 67 \
+ 45 75 4C 77 50 12 A0 F8 15 1A 00 57 32 0F 87 57 \
+ 32 0E 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #sdk56334.hex
+
+if $?apollo "local ledcode '\
+ 02 1E 28 60 E0 67 58 67 73 06 E0 80 28 60 E0 67 \
+ 73 67 58 06 E0 80 D2 36 74 02 02 1A 28 60 E0 67 \
+ 9B 75 29 67 B0 67 58 77 31 32 0E 87 32 08 87 67 \
+ A2 06 E0 80 D2 1E 74 1C 12 E2 85 05 D2 0F 71 42 \
+ 52 00 12 E1 85 05 D2 1F 71 4C 52 00 12 E3 85 05 \
+ D2 05 71 56 52 00 3A 70 32 00 97 75 64 32 01 97 \
+ 71 6B 77 B0 32 01 97 71 A9 77 A2 16 E3 DA 02 71 \
+ A9 77 B0 32 05 97 75 83 32 02 97 71 A2 06 E1 D2 \
+ 01 71 A2 06 E0 67 9B 75 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 E2 D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" #sdk56524.hex
+
+if $?generic8led "local ledcode '\
+ 06 E1 D2 40 71 11 E0 60 E1 16 E3 DA 01 71 15 60 \
+ E3 67 5D 75 2B 12 01 61 E3 67 71 28 67 32 86 E0 \
+ 16 E2 81 61 E2 DA 1E 75 2B 3A 08 E9 61 E2 86 E1 \
+ 77 00 67 5D 75 38 77 3C 67 64 77 64 67 41 67 4F \
+ 57 28 32 01 97 75 64 16 E0 CA 05 74 68 77 64 28 \
+ 32 00 97 75 64 16 E0 CA 05 74 68 77 64 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 09 75 64 77 \
+ 68 12 05 67 6C 12 04 67 6C 12 03 67 6C 12 02 67 \
+ 6C 12 01 67 6C 12 00 67 6C 57 00 00 00 00 00 00'" #generic8led.hex
+
+# Download LED code into LED processor and enable (if applicable).
+
+if $?feature_led_proc && $?ledcode && !$?simulator \
+ "led prog $ledcode; \
+ led auto on; led start"
+
+# If loading multiple rc.soc, upon loading the last unit, restart
+# all LED processors so any common blinking is in sync.
+
+if !"expr $?feature_led_proc && !$?simulator && $unit == $units - 1" \
+ "*:led stop; *:led start"
+
+# Run counter DMA task 4 times per second to achieve better
+# ctr_xaui_activity.
+if $?bradley_any \
+ "ctr interval=250000"
+
+# Initialize Hercules UC modid 0 entry to point to the CPU
+if $?herc_any \
+ "w uc 0 1 1"
+
+# Additional configuration for 48-port in Stacking mode.
+# On the 48-port platform, rc.soc is run twice; once on unit 0 and
+# then once on unit 1. The turbo port on unit N is geN.
+# All turbo port traffic must be tagged; see vlan add below.
+# See $SDK/doc/48-port.txt for more information including how
+# to configure IPG values for line rate operation.
+
+if $?p48 && $?unit0 \
+ "local turbo_port 0; local my_modid 1;"
+
+if $?p48 && $?unit1 \
+ "local turbo_port 1; local my_modid 2;"
+
+if $?p48 \
+ "m config st_is_mirr=0 st_module=1 st_mcnt=1 st_simplex=0 st_link=0; \
+ m config.g$turbo_port st_link=1; \
+ m gmacc2.ge$turbo_port ipgt=8 mclkfq=1; \
+ m fe_maxf maxfr=1560; \
+ m maxfr maxfr=1568; \
+ m config2 my_modid=$my_modid; \
+ port ge$turbo_port speed=2500; \
+ vlan add 1 pbm=ge$turbo_port ubm=none"
+
+if !$?no_bcm && $?drac_any \
+ "m modport_7_0 port_for_mod1=0xc"
+if !$?no_bcm && $?lynx_any \
+ "m modport_7_0 port_for_mod1=0x1"
+if !$?no_bcm && $?tucana \
+ "stkmode modid=0;"
+if !$?no_bcm && $?tucana && !$?magnum && !$?tucana_nohg \
+ "m modport_7_0 port_for_mod2=0x38; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=0 port_for_mod2=0x38; \
+ stkmode modid=0"
+if !$?no_bcm && $?xgs_switch && !$?rcpu_only\
+ "stkmode modid=0; \
+ s CMIC_COS_CTRL_RX CH0_COS_BMP=0,CH1_COS_BMP=0xff, \
+ CH2_COS_BMP=0,CH3_COS_BMP=0"
+
+# Back-to-back Draco setup.
+
+# Draco chips must run at 127MHz. Some older versions
+# are not set to this frequency.
+
+if $?draco_stk && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+# Applies to SDK Baseboard with either internal or external Higigs,
+# as well as the Galahad reference design.
+
+if $?draco_b2b && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if !$?simulator && $?draco_b2b && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_b2b && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Merlin, White Knight, Black Knight setup.
+# Draco unit 1 is on Herc port 8
+# Draco unit 2 is on Herc port 1
+
+if $?draco_herc4 && $?unit0 \
+ "w uc.hpic7 0 1 0x0; \
+ w uc.hpic7 1 1 0x2; \
+ w uc.hpic0 0 1 0x100; \
+ w uc.hpic0 1 1 0x0"
+
+if !$?simulator && $?draco_herc4 && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_herc4 && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if $?draco_herc4 && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Lancelot setup
+# (enabled by adding the property "lancelot=1")
+# Notes:
+# Draco unit 1 is on Herc port 7
+# Draco unit 2 is on Herc port 8
+# Draco unit 3 is on Herc port 1
+# Draco unit 4 is on Herc port 2
+
+if $?lancelot && $?unit0 \
+ "w uc.hpic6 0 1 0x0; \
+ w uc.hpic6 1 1 0x100; \
+ w uc.hpic6 2 1 0x2; \
+ w uc.hpic6 3 1 0x4; \
+ w uc.hpic7 0 1 0x80; \
+ w uc.hpic7 1 1 0x0; \
+ w uc.hpic7 2 1 0x2; \
+ w uc.hpic7 3 1 0x4; \
+ w uc.hpic0 0 1 0x80; \
+ w uc.hpic0 1 1 0x100; \
+ w uc.hpic0 2 1 0x0; \
+ w uc.hpic0 3 1 0x4; \
+ w uc.hpic1 0 1 0x80; \
+ w uc.hpic1 1 1 0x100; \
+ w uc.hpic1 2 1 0x2; \
+ w uc.hpic1 3 1 0x0"
+
+if !$?simulator && $?lancelot && $?unit0 \
+ "i2c probe quiet; bb clock Draco_Core 127"
+
+if $?lancelot && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit3 \
+ "stkmode modid=2; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12"
+
+if $?lancelot && $?unit4 \
+ "stkmode modid=3; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0"
+
+# Lynx SDK (TwoLynx) setup
+# (enabled by adding the property "twolynx=1")
+
+if $?twolynx && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ "
+
+if $?twolynx && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ "
+# HercuLynx setup
+# (enabled by adding the property "herculynx=1")
+# Notes:
+# Lynx unit 1 is on Herc port 1
+# Lynx unit 2 is on Herc port 2
+# Lynx unit 3 is on Herc port 3
+# Lynx unit 4 is on Herc port 4
+# Lynx unit 5 is on Herc port 5
+# Lynx unit 6 is on Herc port 6
+# Lynx unit 7 is on Herc port 7
+# Lynx unit 8 is on Herc port 8
+
+if $?herculynx && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x008; \
+ w uc.hpic0 3 1 0x010; \
+ w uc.hpic0 4 1 0x020; \
+ w uc.hpic0 5 1 0x040; \
+ w uc.hpic0 6 1 0x080; \
+ w uc.hpic0 7 1 0x100; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x008; \
+ w uc.hpic1 3 1 0x010; \
+ w uc.hpic1 4 1 0x020; \
+ w uc.hpic1 5 1 0x040; \
+ w uc.hpic1 6 1 0x080; \
+ w uc.hpic1 7 1 0x100; \
+ ; \
+ w uc.hpic2 0 1 0x002; \
+ w uc.hpic2 1 1 0x004; \
+ w uc.hpic2 2 1 0x008; \
+ w uc.hpic2 3 1 0x010; \
+ w uc.hpic2 4 1 0x020; \
+ w uc.hpic2 5 1 0x040; \
+ w uc.hpic2 6 1 0x080; \
+ w uc.hpic2 7 1 0x100; \
+ ; \
+ w uc.hpic3 0 1 0x002; \
+ w uc.hpic3 1 1 0x004; \
+ w uc.hpic3 2 1 0x008; \
+ w uc.hpic3 3 1 0x010; \
+ w uc.hpic3 4 1 0x020; \
+ w uc.hpic3 5 1 0x040; \
+ w uc.hpic3 6 1 0x080; \
+ w uc.hpic3 7 1 0x100; \
+ ; \
+ w uc.hpic4 0 1 0x002; \
+ w uc.hpic4 1 1 0x004; \
+ w uc.hpic4 2 1 0x008; \
+ w uc.hpic4 3 1 0x010; \
+ w uc.hpic4 4 1 0x020; \
+ w uc.hpic4 5 1 0x040; \
+ w uc.hpic4 6 1 0x080; \
+ w uc.hpic4 7 1 0x100; \
+ ; \
+ w uc.hpic5 0 1 0x002; \
+ w uc.hpic5 1 1 0x004; \
+ w uc.hpic5 2 1 0x008; \
+ w uc.hpic5 3 1 0x010; \
+ w uc.hpic5 4 1 0x020; \
+ w uc.hpic5 5 1 0x040; \
+ w uc.hpic5 6 1 0x080; \
+ w uc.hpic5 7 1 0x100; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x008; \
+ w uc.hpic6 3 1 0x010; \
+ w uc.hpic6 4 1 0x020; \
+ w uc.hpic6 5 1 0x040; \
+ w uc.hpic6 6 1 0x080; \
+ w uc.hpic6 7 1 0x100; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x008; \
+ w uc.hpic7 3 1 0x010; \
+ w uc.hpic7 4 1 0x020; \
+ w uc.hpic7 5 1 0x040; \
+ w uc.hpic7 6 1 0x080; \
+ w uc.hpic7 7 1 0x100; \
+ ; \
+ "
+
+if $?herculynx && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?herculynx && $?unit1 \
+ "stkmode modid=0"
+
+if $?herculynx && $?unit2 \
+ "stkmode modid=1"
+
+if $?herculynx && $?unit3 \
+ "stkmode modid=2"
+
+if $?herculynx && $?unit4 \
+ "stkmode modid=3"
+
+if $?herculynx && $?unit5 \
+ "stkmode modid=4"
+
+if $?herculynx && $?unit6 \
+ "stkmode modid=5"
+
+if $?herculynx && $?unit7 \
+ "stkmode modid=6"
+
+if $?herculynx && $?unit8 \
+ "stkmode modid=7"
+
+# LynxaLot setup
+# (enabled by adding the property "lynxalot=1")
+# Notes:
+# Lynx unit 0 is on Herc port 3 (hg2/hpic2) (mod 0)
+# Lynx unit 1 is on Herc port 4 (hg3/hpic3) (mod 1)
+# Higig conn 0 is on Herc port 5 (hg4/hpic4)
+# Higig conn 1 is on Herc port 6 (hg5/hpic5)
+# Draco unit 3 is on Herc port 7 (hg6/hpic6) (mod 2)
+# Draco unit 4 is on Herc port 8 (hg7/hpic7) (mod 3)
+# Draco unit 5 is on Herc port 1 (hg0/hpic0) (mod 4)
+# Draco unit 6 is on Herc port 2 (hg1/hpic1) (mod 5)
+
+if $?lynxalot && $?unit2 \
+ " \
+ w uc.hpic0 0 1 0x008; \
+ w uc.hpic0 1 1 0x010; \
+ w uc.hpic0 2 1 0x080; \
+ w uc.hpic0 3 1 0x100; \
+ w uc.hpic0 4 1 0x002; \
+ w uc.hpic0 5 1 0x004; \
+ ; \
+ w uc.hpic1 0 1 0x008; \
+ w uc.hpic1 1 1 0x010; \
+ w uc.hpic1 2 1 0x080; \
+ w uc.hpic1 3 1 0x100; \
+ w uc.hpic1 4 1 0x002; \
+ w uc.hpic1 5 1 0x004; \
+ ; \
+ w uc.hpic2 0 1 0x008; \
+ w uc.hpic2 1 1 0x010; \
+ w uc.hpic2 2 1 0x080; \
+ w uc.hpic2 3 1 0x100; \
+ w uc.hpic2 4 1 0x002; \
+ w uc.hpic2 5 1 0x004; \
+ ; \
+ w uc.hpic3 0 1 0x008; \
+ w uc.hpic3 1 1 0x010; \
+ w uc.hpic3 2 1 0x080; \
+ w uc.hpic3 3 1 0x100; \
+ w uc.hpic3 4 1 0x002; \
+ w uc.hpic3 5 1 0x004; \
+ ; \
+ w uc.hpic6 0 1 0x008; \
+ w uc.hpic6 1 1 0x010; \
+ w uc.hpic6 2 1 0x080; \
+ w uc.hpic6 3 1 0x100; \
+ w uc.hpic6 4 1 0x002; \
+ w uc.hpic6 5 1 0x004; \
+ ; \
+ w uc.hpic7 0 1 0x008; \
+ w uc.hpic7 1 1 0x010; \
+ w uc.hpic7 2 1 0x080; \
+ w uc.hpic7 3 1 0x100; \
+ w uc.hpic7 4 1 0x002; \
+ w uc.hpic7 5 1 0x004; \
+ ; \
+ "
+
+if $?lynxalot && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?lynxalot && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?lynxalot && $?unit0 \
+ "stkmode modid=0"
+
+if $?lynxalot && $?unit1 \
+ "stkmode modid=1"
+
+if $?lynxalot && $?unit3 \
+ "stkmode modid=2"
+
+if $?lynxalot && $?unit4 \
+ "stkmode modid=3"
+
+if $?lynxalot && $?unit5 \
+ "stkmode modid=4"
+
+if $?lynxalot && $?unit6 \
+ "stkmode modid=5"
+
+# guenevere setup
+# (enabled by adding the property "guenevere=1")
+# Notes:
+# hgX mapping based on pbmp_valid.0=0x1b7
+# Draco unit 1 is on Herc port 1 (hg0/hpic0) (mod 0)
+# Draco unit 2 is on Herc port 2 (hg1/hpic1) (mod 1)
+# Lynx unit 3 is on Herc port 8 (hg5/hpic7) (mod 2)
+# Lynx unit 4 is on Herc port 7 (hg4/hpic6) (mod 3)
+# Higig conn 0 is on Herc port 4 (hg2/hpic3)
+# Higig conn 1 is on Herc port 5 (hg3/hpic4)
+# Herc port 3 - Unused (hpic2)
+# Herc port 6 - Unused (hpic5)
+if $?guenevere && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x100; \
+ w uc.hpic0 3 1 0x080; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x100; \
+ w uc.hpic1 3 1 0x080; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x100; \
+ w uc.hpic7 3 1 0x080; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x100; \
+ w uc.hpic6 3 1 0x080; \
+ ; \
+ "
+
+if $?guenevere && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?guenevere && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?guenevere && $?unit1 \
+ "stkmode modid=0"
+
+if $?guenevere && $?unit2 \
+ "stkmode modid=1"
+
+if $?guenevere && $?unit3 \
+ "stkmode modid=2"
+
+if $?guenevere && $?unit4 \
+ "stkmode modid=3"
+
+# felix48 setup
+# (enabled by adding the property "felix48=1")
+# Notes:
+# BCM56102 unit-0 higig port (port 26) is connected
+# to BCM56102 Unit-1 higig port (port 26)
+#
+
+if $?felix48 && $?unit0 \
+ "stkmode modid=0 ; \
+ m IEGR_PORT MY_MODID=0; \
+ m XPORT_CONFIG MY_MODID=0; \
+ w MODPORT_MAP 1 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+
+if $?felix48 && $?unit1 \
+ "stkmode modid=1 ; \
+ m IEGR_PORT MY_MODID=1; \
+ m XPORT_CONFIG MY_MODID=1; \
+ w MODPORT_MAP 0 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+# fbpoe setup
+# (enabled by adding the property "fbpoe=1")
+# Notes:
+# BCM56504 unit-0 higig port (port 27,28) is connected
+# to BCM56504 Unit-1 higig port (port 27,28)
+#
+
+if $?unit0 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+if $?unit1 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+# Dual Raptor/Raven boards
+if $?raven_eb_48p || $?rap24_ref \
+ "local rcpu_system 1"
+if $?unit0 && $?rcpu_system \
+ "stkmode modid=0"
+if $?unit1 && $?rcpu_system \
+ "stkmode modid=1"
+
+# LM fb48 platform setup
+# (enabled by adding the property "lm48p=1")
+#
+if $?unit0 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=0"
+
+if $?unit1 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=1"
+
+# Set Firebolt POE power level 170(total) - 110(switch) = 60
+if $?fbpoe \
+ "local poepower 60"
+
+# Set Draco15 POE power level 170(total) - 80(switch) = 90
+if $?drac15\
+ "local poepower 90"
+
+# if enable_poe is set, then enable the POE processor for
+# either Firebolt or Draco15 platform
+if $?unit0 && $?enable_poe && $?fbpoe || $?drac15 \
+ "$echo rc: Enabling POE ...; \
+ poesel reset; \
+ i2c probe quiet; \
+ xpoe verbose off; \
+ xpoe power $poepower; \
+ xpoe verbose on; \
+ poesel enable"
+
+# mark this unit so that subsequent rc runs are quiet
+setenv rc$unit 1
+
+if $?macsec '\
+ macsec sync; \
+ $echo "rc: MACSEC CLI Enabled"'
+
+# cache a copy of rc.soc in memory
+rccache addq rc.soc
+
+# setup chassis if requested
+if !"expr $?autochassis2 && $unit == $units - 1" \
+ "setenv chassis2_no_rc 1; \
+ rcload c2switch.soc; \
+ setenv chassis2_no_rc; \
+ "
+
+# start stacking if requested
+if !"expr $?autostack && $unit == $units - 1" \
+ "rcload stk.soc"
+
+if !"expr $?aedev + 0" && !"expr $unit == $units - 1" \
+ "aedev init"
+
+# hurricane 48p FE platform LED setup for 56146_A0 and 56147_A0 board
+# (enabled by adding the property "fe_hu_48p=1")
+#
+if $?fe_hu_48p && $?BCM56146 || $?BCM56147 \
+ "phy fe0 0x1f 0x008b; \
+ phy fe0 0x1a 0x3f09;\
+ phy fe8 0x1f 0x008b; \
+ phy fe8 0x1a 0x3f09; \
+ phy fe16 0x1f 0x008b; \
+ phy fe16 0x1a 0x3f09"
+
+rcload bal.soc
diff --git a/bal_release/3rdparty/bcm-sdk/rc/kt2/readme.txt b/bal_release/3rdparty/bcm-sdk/rc/kt2/readme.txt
new file mode 100644
index 0000000..b027d55
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/kt2/readme.txt
@@ -0,0 +1,18 @@
+This directory contains bcm files that are needed in the KT2 svk file system to bring up
+the BCM Diag Shell.
+User can also copy the bcm.user linux-kernel-bde.ko and linux-user-bde.ko
+from a private bcm_sdk build to the same KT2 svk file system.
+!!!
+ Do not forget to change the IP in bal.soc to point it to the BAL_CORE
+!!!
+
+The currently supported bcm_sdk version is 6.4.4
+.
+|-- bal.soc
+|-- bcm.user
+|-- linux-kernel-bde.ko
+|-- linux-user-bde.ko
+|-- rc.soc
+
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/bcm88470_board.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/bcm88470_board.soc
new file mode 100755
index 0000000..b944270
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/bcm88470_board.soc
@@ -0,0 +1,211 @@
+# $Id:
+# $Copyright: (c) 1998-2001 Broadcom Corp.
+# All Rights Reserved.$
+#
+
+# Dram dq swaps for BCM88470
+
+#Dram HW properties
+
+#RX polarity
+config add phy_rx_polarity_flip.BCM88470=0
+
+
+#TX polarity
+config add phy_tx_polarity_flip.BCM88470=0
+
+#rx lane swap
+config add phy_rx_lane_map.BCM88470=0x3210
+config add phy_rx_lane_map_quad0.BCM88470=0x3210
+config add phy_rx_lane_map_quad1.BCM88470=0x3210
+config add phy_rx_lane_map_quad2.BCM88470=0x3210
+config add phy_rx_lane_map_quad3.BCM88470=0x3210
+config add phy_rx_lane_map_quad4.BCM88470=0x3210
+config add phy_rx_lane_map_quad5.BCM88470=0x3210
+config add phy_rx_lane_map_quad6.BCM88470=0x3210
+config add phy_rx_lane_map_quad7.BCM88470=0x3210
+config add phy_rx_lane_map_quad8.BCM88470=0x3210
+config add phy_rx_lane_map_quad9.BCM88470=0x3210
+config add phy_rx_lane_map_quad10.BCM88470=0x3120
+config add phy_rx_lane_map_quad11.BCM88470=0x3210
+
+
+#tx lane swap
+config add phy_tx_lane_map.BCM88470=0x3210
+config add phy_tx_lane_map_quad0.BCM88470=0x3210
+config add phy_tx_lane_map_quad1.BCM88470=0x3210
+config add phy_tx_lane_map_quad2.BCM88470=0x3210
+config add phy_tx_lane_map_quad3.BCM88470=0x3210
+config add phy_tx_lane_map_quad4.BCM88470=0x3210
+config add phy_tx_lane_map_quad5.BCM88470=0x3210
+config add phy_tx_lane_map_quad6.BCM88470=0x3210
+config add phy_tx_lane_map_quad7.BCM88470=0x3210
+config add phy_tx_lane_map_quad8.BCM88470=0x3210
+config add phy_tx_lane_map_quad9.BCM88470=0x3210
+config add phy_tx_lane_map_quad10.BCM88470=0x3120
+config add phy_tx_lane_map_quad11.BCM88470=0x3210
+
+# Dram dq swaps for BCM88470
+config add ext_ram_dq_swap_dram0_byte0_bit0.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte0_bit1.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte0_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte0_bit3.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte0_bit4.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte0_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte0_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte0_bit7.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte1_bit0.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte1_bit1.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte1_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte1_bit3.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte1_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte1_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte1_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte1_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte2_bit0.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte2_bit1.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte2_bit2.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte2_bit3.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte2_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte2_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte2_bit6.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte2_bit7.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte3_bit0.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte3_bit1.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte3_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte3_bit3.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte3_bit4.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte3_bit5.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte3_bit6.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte3_bit7.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte0_bit0.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte0_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte0_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte0_bit3.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte0_bit4.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte0_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte0_bit6.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte0_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte1_bit0.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte1_bit1.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte1_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte1_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte1_bit4.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte1_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte1_bit6.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte1_bit7.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte2_bit0.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte2_bit1.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte2_bit2.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte2_bit3.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte2_bit4.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte2_bit5.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte2_bit6.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte2_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte3_bit0.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte3_bit1.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte3_bit2.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte3_bit3.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte3_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte3_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte3_bit6.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte3_bit7.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte0_bit0.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte0_bit1.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte0_bit2.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte0_bit3.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte0_bit4.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte0_bit5.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte0_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte0_bit7.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte1_bit0.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte1_bit1.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte1_bit2.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte1_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte1_bit4.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte1_bit5.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte1_bit6.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte1_bit7.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte2_bit0.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte2_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte2_bit2.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte2_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte2_bit4.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte2_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte2_bit6.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte2_bit7.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte3_bit0.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte3_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte3_bit2.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte3_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte3_bit4.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte3_bit5.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte3_bit6.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte3_bit7.BCM88470=1
+
+# Dram bank addr swaps for BCM88470
+config add ext_ram_addr_bank_swap_dram0_bit7.BCM88470=4
+config add ext_ram_addr_bank_swap_dram0_bit11.BCM88470=5
+config add ext_ram_addr_bank_swap_dram0_bit13.BCM88470=15
+config add ext_ram_addr_bank_swap_dram0_bit14.BCM88470=17
+config add ext_ram_addr_bank_swap_dram0_bit5.BCM88470=6
+config add ext_ram_addr_bank_swap_dram0_bit0.BCM88470=7
+config add ext_ram_addr_bank_swap_dram0_bit8.BCM88470=8
+config add ext_ram_addr_bank_swap_dram0_bit1.BCM88470=9
+config add ext_ram_addr_bank_swap_dram0_bit4.BCM88470=10
+config add ext_ram_addr_bank_swap_dram0_bit16.BCM88470=11
+config add ext_ram_addr_bank_swap_dram0_bit15.BCM88470=12
+config add ext_ram_addr_bank_swap_dram0_bit12.BCM88470=13
+config add ext_ram_addr_bank_swap_dram0_bit6.BCM88470=0
+config add ext_ram_addr_bank_swap_dram0_bit2.BCM88470=1
+config add ext_ram_addr_bank_swap_dram0_bit9.BCM88470=2
+config add ext_ram_addr_bank_swap_dram0_bit10.BCM88470=14
+config add ext_ram_addr_bank_swap_dram0_bit17.BCM88470=16
+config add ext_ram_addr_bank_swap_dram1_bit10.BCM88470=4
+config add ext_ram_addr_bank_swap_dram1_bit14.BCM88470=5
+config add ext_ram_addr_bank_swap_dram1_bit7.BCM88470=15
+config add ext_ram_addr_bank_swap_dram1_bit12.BCM88470=17
+config add ext_ram_addr_bank_swap_dram1_bit4.BCM88470=6
+config add ext_ram_addr_bank_swap_dram1_bit6.BCM88470=7
+config add ext_ram_addr_bank_swap_dram1_bit9.BCM88470=8
+config add ext_ram_addr_bank_swap_dram1_bit1.BCM88470=9
+config add ext_ram_addr_bank_swap_dram1_bit5.BCM88470=10
+config add ext_ram_addr_bank_swap_dram1_bit11.BCM88470=11
+config add ext_ram_addr_bank_swap_dram1_bit8.BCM88470=12
+config add ext_ram_addr_bank_swap_dram1_bit13.BCM88470=13
+config add ext_ram_addr_bank_swap_dram1_bit0.BCM88470=0
+config add ext_ram_addr_bank_swap_dram1_bit15.BCM88470=1
+config add ext_ram_addr_bank_swap_dram1_bit2.BCM88470=2
+config add ext_ram_addr_bank_swap_dram1_bit17.BCM88470=14
+config add ext_ram_addr_bank_swap_dram1_bit16.BCM88470=16
+config add ext_ram_addr_bank_swap_dram2_bit15.BCM88470=4
+config add ext_ram_addr_bank_swap_dram2_bit5.BCM88470=5
+config add ext_ram_addr_bank_swap_dram2_bit11.BCM88470=15
+config add ext_ram_addr_bank_swap_dram2_bit7.BCM88470=17
+config add ext_ram_addr_bank_swap_dram2_bit17.BCM88470=6
+config add ext_ram_addr_bank_swap_dram2_bit0.BCM88470=7
+config add ext_ram_addr_bank_swap_dram2_bit16.BCM88470=8
+config add ext_ram_addr_bank_swap_dram2_bit2.BCM88470=9
+config add ext_ram_addr_bank_swap_dram2_bit13.BCM88470=10
+config add ext_ram_addr_bank_swap_dram2_bit9.BCM88470=11
+config add ext_ram_addr_bank_swap_dram2_bit12.BCM88470=12
+config add ext_ram_addr_bank_swap_dram2_bit6.BCM88470=13
+config add ext_ram_addr_bank_swap_dram2_bit14.BCM88470=0
+config add ext_ram_addr_bank_swap_dram2_bit8.BCM88470=1
+config add ext_ram_addr_bank_swap_dram2_bit1.BCM88470=2
+config add ext_ram_addr_bank_swap_dram2_bit4.BCM88470=14
+config add ext_ram_addr_bank_swap_dram2_bit10.BCM88470=16
+
+##Dram HW properties
+config add ext_ram_present.BCM88470=3
+config add dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT=1
+config add ext_ram_freq.BCM88470=1600
+config add ext_ram_abi.BCM88470=0
+config add ext_ram_write_dbi.BCM88470=0
+config add ext_ram_read_dbi.BCM88470=0
+config add ext_ram_write_crc.BCM88470=0
+config add ext_ram_read_crc.BCM88470=0
+config add ext_ram_cmd_par_latency.BCM88470=6
+config add ext_ram_type.BCM88470=DDR4
+config add ext_ram_total_size.BCM88470=3000
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/combo28_dram.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/combo28_dram.soc
new file mode 100755
index 0000000..d47c1f5
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/combo28_dram.soc
@@ -0,0 +1,560 @@
+#
+# $Id: combo28_dram.soc,v 1.0 2014/04/28 15:50:00 nhefetz Exp $
+#
+# $Copyright: (c) 2014 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+#################### General Notes ########################
+# Our controller support both DDR4 and GDDR5, we need to "modify" ext_ram_columns in the following way:
+# For DDR4, need to use column number as in DRAM Data Sheet, meaning 1024 in drams supported.
+# For GDDR5, need to multiply number in Data Sheet by 8 (representing the 3 address bits, which are constant 000 in DDR4.), meaning 512 in drams supported.
+
+
+if $?dram_type_DDR4_SAMSUNG_K4A4G165WD_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\\
+ config add ext_ram_t_ccd_l=6c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=17c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_MICRON_EDY4016AABG_DRFR_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\\
+ config add ext_ram_t_ccd_l=6c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_DDR4_MICRON_MT40A256M16HA_083EA_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=12c;\\
+ config add ext_ram_t_ccd_l=8c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=18c;\
+ config add ext_ram_c_cas_latency=24c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_DDR4_MICRON_MT40A512M16_8GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=350000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=65536; \
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_HYNIX_H5AN4G6NMFR_VJC_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=4c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=7500;\
+ config add ext_ram_t_rtp_l=7500;\
+ config add ext_ram_t_wtr_s=2500;\
+ config add ext_ram_t_wtr_l=7500;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_crc_wr_latency=12c;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=12c;\\
+ config add ext_ram_t_ccd_l=8c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_c_cas_latency=24c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_GDDR5_SAMSUNG_K4G20325FD_2GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=78000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=8192; \
+ config add ext_ram_banks=16;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_GDDR5_SAMSUNG_K4G41325FC_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+#if $?dram_type_GDDR5_HYNIX_H5GQ2H24AFR_R0C_2GBIT "\
+# config add ext_ram_type=GDDR5; \
+# config add ext_ram_t_rfc=120000;\
+# config add ext_ram_t_rc=48000;\
+# config add ext_ram_t_rcd_wr=14000;\
+# config add ext_ram_t_rcd_rd=18000;\
+# config add ext_ram_t_rrd_l=9c;\
+# config add ext_ram_t_rrd_s=9c;\
+# config add ext_ram_t_ras=32000;\
+# config add ext_ram_t_rp=16000;\
+# config add ext_ram_t_wr=16000;\
+# config add ext_ram_t_faw=30000;\
+# config add ext_ram_t_32aw=245000;\
+# config add ext_ram_t_rtp_s=2c;\
+# config add ext_ram_t_rtp_l=2c;\
+# config add ext_ram_t_wtr_s=8c;\
+# config add ext_ram_t_wtr_l=8c;\
+# config add ext_ram_t_ccd_l=3c;\
+# config add ext_ram_t_ccd_s=2c;\
+# config add ext_ram_t_ref=3900000;\
+# config add ext_ram_c_wr_latency=3c;\
+# config add ext_ram_c_cas_latency=16c;\
+# config add ext_ram_t_crc_rd_latency=2c;\
+# config add ext_ram_t_crc_wr_latency=11c;\
+# config add ext_ram_t_rst=200000000;\
+# config add ext_ram_t_al=1c;\
+# config add ext_ram_columns=512; \
+# config add ext_ram_rows=8192; \
+# config add ext_ram_banks=16;"
+#
+
+###################################################
+# ELPIDA GDDR5
+###################################################
+if $?dram_type_GDDR5_MICRON_EDW4032CABG_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=90000;\
+ config add ext_ram_t_rc=44000;\
+ config add ext_ram_t_rcd_wr=13000;\
+ config add ext_ram_t_rcd_rd=17000;\
+ config add ext_ram_t_rrd_l=5000;\
+ config add ext_ram_t_rrd_s=5000;\
+ config add ext_ram_t_ras=27000;\
+ config add ext_ram_t_rp=17000;\
+ config add ext_ram_t_wr=18000;\
+ config add ext_ram_t_faw=20000;\
+ config add ext_ram_t_32aw=160000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=7c;\
+ config add ext_ram_t_wtr_l=7c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_c_cas_latency=18c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=11c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=2c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+if $?dram_type_GDDR5_HYNIX_H5GC4H24MFR_T2C_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=120000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=14000;\
+ config add ext_ram_t_rcd_rd=18000;\
+ config add ext_ram_t_rrd_l=9c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=16000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_32aw=245000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=8c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_c_cas_latency=18c;\
+ config add ext_ram_t_crc_rd_latency=2c;\
+ config add ext_ram_t_crc_wr_latency=13c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+###############################################################################################
+# Note: For extended devices for example Micron dram_type_DDR4_MICRON_MT40A256M16HA_083E
+# please use none extended parameters for example dram_type_DDR4_MICRON_MT40A256M16HA_083
+###############################################################################################
+if $?dram_type_DDR4_MICRON_MT40A256M16HA_083_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A256M16HA_083_4GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_DDR4_MICRON_MT40A512M16HA_083_8GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=350000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=65536;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A512M16HA_083_8GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_DDR4_MICRON_MT40A256M16GE_062_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1600;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=12c;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=8;\
+ config add ext_ram_c_cas_latency=24c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A256M16GE_062_4GBIT "\
+ config add ext_ram_c_cas_latency=28c;"
+
+if $?dram_type_DDR4_SAMSUNG_K4A4G165WE_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c ;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_SAMSUNG_K4A4G165WE_4GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_GDDR5_MICRON_MT51K256M32HF_50_8GBIT "\
+ config add ext_ram_type=GDDR5;\
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=44000;\
+ config add ext_ram_t_rcd_wr=12000;\
+ config add ext_ram_t_rcd_rd=17000;\
+ config add ext_ram_t_rrd_l=5000;\
+ config add ext_ram_t_rrd_s=5000;\
+ config add ext_ram_t_ras=27000;\
+ config add ext_ram_t_rp=17000;\
+ config add ext_ram_t_wr=18000;\
+ config add ext_ram_t_faw=20000;\
+ config add ext_ram_t_32aw=160000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=6c;\
+ config add ext_ram_t_wtr_l=6c;\
+ config add ext_ram_t_ccd_l=2c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=11c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=2c;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=16384;\
+ config add ext_ram_banks=16;\
+ config add ext_ram_c_cas_latency=16c;"
+expr $ext_ram_write_dbi==1
+if $? && $?dram_type_GDDR5_MICRON_MT51K256M32HF_50_8GBIT "\
+ config add ext_ram_c_cas_latency=16c;"
+
+if $?dram_type_GDDR5_SAMSUNG_K4G41325FE_HC28_4GBIT "\
+ config add ext_ram_type=GDDR5;\
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=3c;\
+ config add ext_ram_t_wtr_l=8c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512;\
+ config add ext_ram_rows=16384;\
+ config add ext_ram_banks=16;\
+ config add ext_ram_c_cas_latency=18c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_GDDR5_SAMSUNG_K4G41325FE_HC28_4GBIT "\
+ config add ext_ram_c_cas_latency=19c;"
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/config.bcm b/bal_release/3rdparty/bcm-sdk/rc/qax/config.bcm
new file mode 100755
index 0000000..4645da3
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/config.bcm
@@ -0,0 +1,2910 @@
+#
+# $Id: config-sand.bcm,v 1.140 2013/09/22 14:29:47 tomerma Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+
+#pci_override_dev.0=0x8375
+
+# Note: comment size is restricted to 128 charecters per line.
+
+#########################################
+##cfg for BCM88640 (PetraB), BCM88650 (Arad) and BCM88202 (Ardon)
+#########################################
+
+## temporary suppressing unknown soc properties warnings - till adding them unknown to property.h/propgen
+## (need to be the first soc property in the file).
+suppress_unknown_prop_warnings=1
+
+
+## Multi device system (Negev): 2 devices, fabric mode is FE, mod id is slot id
+## (Top line card is 0, button is 1).
+#diag_chassis=1
+
+## Disable diag init application. Should be used if one wants to run his own
+## application instead of the diag init example
+#diag_disable=1
+
+## Skip cosq configuration in diag_init
+#diag_cosq_disable=1
+#
+
+stack_enable.BCM88680=1
+tdma_timeout_usec.BCM88680=3000000
+tslam_timeout_usec.BCM88680=3000000
+diag_emulator_partial_init.BCM88680=0
+phy_simul.BCM88680=0
+
+
+## Skip l2 configuration in diag_init
+#diag_l2_disable=1
+
+## L2 mode to load 0=DEFAULT, 1=INGRESS_DIST, 2=INGRESS_CENT, 3=EGRESS_DIST, 4=EGRESS_CENT, 5=EGRESS_INDEPENDENT
+# 6=(INGRESS_CENT + LEARN_CPU), 7=(EGRESS_CENT + LEARN_CPU)
+#l2_mode=0
+
+## Skip stk configuration in diag_init
+#diag_no_appl_stk=1
+
+## Skip itmh programmable mode configuration in diag_init
+#diag_no_itmh_prog_mode=1
+
+# Ingress PMF key allocation optimization
+field_key_allocation_msb_balance_enable=1
+
+## Set modid value. Should be used when running multi-fap system.
+## Each fap should have it's unique modid value. Default is described in diag_chassis.
+#module_id=<modid>
+
+## Set base_modid value. Default is 0.
+#base_module_id=<base_modid>
+
+## Set nof_devices value. Should be set when working on multi-faps system.
+## Default is 1 when diag_chassis is not enabled, or 2 when diag_chassis is enabled.
+#n_devices=<nof_devices>
+
+#########################################
+##cfg for BCM88650 - Arad
+#########################################
+
+### Device configuration ###
+
+## Activate Emulation partial init. Values: 0 - Normal, 1 - Emulation .Default: 0x0.
+diag_emulator_partial_init.BCM88650=0
+#diag_emulator_partial_init.BCM88270=1
+#diag_emulator_partial_init.BCM88680=1
+#diag_emulator_partial_init.BCM88675=2
+
+#real phy isn't connected - remove on silicon arrival
+#phy_simul.BCM88675=1
+
+## General
+# Set the FAP Device mode
+# Options: PP / TM / TDM_OPTIMIZED / TDM_STANDARD
+fap_device_mode.BCM88650=PP
+#
+# FIXME: SDK-91833
+# PP Fixed Followed SDK-91662
+#
+
+# Options: SYMMETRIC / ASYMMETRIC / SINGLE_CORE
+# For faster emulation, use SINGLE_CORE
+device_core_mode.BCM88675=SYMMETRIC
+device_core_mode.BCM88680=SYMMETRIC
+## Credit worth size (Bytes)
+credit_size.BCM88650=1024
+
+## KBP recovery - allow for recovery sequence to run during init and soft reset (only if necessary)
+custom_feature_kbp_recovery_enable=0
+
+## Clock configurations
+# Core clock speed (MHz). Default- BCM88650: 600 MHz, BCM88675: 720 MHz
+core_clock_speed_khz.BCM88650=600000
+core_clock_speed_khz.BCM88675=720000
+core_clock_speed_khz.BCM88470=600000
+core_clock_speed_khz.BCM88680=837500
+core_clock_speed_khz.BCM88270=250000
+
+# System reference clock (MHz). Default- BCM88650: 600 MHz, BCM88675: 800 MHz
+system_ref_core_clock_khz.BCM88650=1200000
+
+#fabric pcp
+fabric_pcp_enable.BCM88675=1
+
+#Using Tcam instead of the KAPS for the IPv4 MC and IPV6 MC
+# 0 - Don't use TACM
+# 1 - Use TCAM for IPV4/6 MC
+# 2 - Use TACM for IPV4/6 MC but don't use the VRF field as a qualifier for IPV4 MC entries
+#custom_feature_l3_mc_use_tcam=0
+
+#for IPv6UC: use Tcam instead of KAPS
+#Note that if this property is enabled the IPV6-UC RPF will be disabled
+#custom_feature_l3_ipv6_uc_use_tcam=0
+
+
+#ams pll override value (only for Jericho A0/A1)- possible values: 0x19, 0x1e, 0x1f. Default value 0x1f
+#custom_feature_ams_pll_override.BCM88675=0x1f
+
+### Network Interface configuration ###
+## Use of the ucode_port_<Local-Port-Id>=<Interface-type>[<Interface-Id>][.<Channel-Id>]
+## Local port range: 0 - 255.
+## Interface types: XAUI/RXAUI/SGMII/ILKN/10GBase-R/XLGE/CGE/CPU/IGNORE
+
+# Map bcm local port to CPU[.channel] interfaces
+ucode_port_0.BCM88650=CPU.0
+
+# Map bcm local port to Network-Interface[.channel] interfaces - TBD
+ucode_port_132.BCM88650=10GBase-R3
+ucode_port_131.BCM88650=10GBase-R2
+ucode_port_130.BCM88650=10GBase-R1
+ucode_port_129.BCM88650=10GBase-R0
+ucode_port_128.BCM88650=10GBase-R46
+#ucode_port_128.BCM88650=GE46
+
+ucode_port_6.BCM88650=10GBase-R22
+ucode_port_5.BCM88650=10GBase-R23
+ucode_port_4.BCM88650=10GBase-R16
+ucode_port_3.BCM88650=10GBase-R17
+ucode_port_2.BCM88650=10GBase-R45
+ucode_port_1.BCM88650=10GBase-R47
+
+custom_feature_nif_recovery_enable.BCM88650=1
+custom_feature_nif_recovery_iter.BCM88650=7
+custom_feature_skip_before_traffic_validation.BCM88675=0
+#custom_feature_mac_fifo_start_tx_thrs.BCM88675=9
+
+#redirect packets that are destined to invalid queues
+invalid_queue_redirect=0
+
+#CLP0
+#ucode_port_1.BCM88675=XE0:core_0.1
+#ucode_port_2.BCM88675=XE1:core_0.2
+#ucode_port_3.BCM88675=XE2:core_0.3
+#ucode_port_4.BCM88675=XE3:core_0.4
+#CLP1
+#ucode_port_5.BCM88675=XE4:core_0.5
+#ucode_port_6.BCM88675=XE5:core_0.6
+#ucode_port_7.BCM88675=XE6:core_0.7
+#ucode_port_8.BCM88675=XE7:core_0.8
+#CLP2
+#ucode_port_9.BCM88675=XE8:core_0.9
+#ucode_port_10.BCM88675=XE9:core_0.10
+#ucode_port_11.BCM88675=XE10:core_0.11
+#ucode_port_12.BCM88675=XE11:core_0.12
+#CLP3
+#ucode_port_13.BCM88675=XE12:core_0.13
+#ucode_port_14.BCM88675=XE13:core_0.14
+#ucode_port_15.BCM88675=XE14:core_0.15
+#ucode_port_16.BCM88675=XE15:core_0.16
+#CLP4
+#ucode_port_17.BCM88675=XE16:core_0.17
+#ucode_port_18.BCM88675=XE17:core_0.18
+#ucode_port_19.BCM88675=XE18:core_0.19
+#ucode_port_20.BCM88675=XE19:core_0.20
+#CLP5
+#ucode_port_21.BCM88675=XE20:core_0.21
+#ucode_port_22.BCM88675=XE21:core_0.22
+#ucode_port_23.BCM88675=XE22:core_0.23
+#ucode_port_24.BCM88675=XE23:core_0.24
+#XLP0
+#ucode_port_25.BCM88675=XE24:core_0.25
+#ucode_port_26.BCM88675=XE25:core_0.26
+#ucode_port_27.BCM88675=XE26:core_0.27
+#ucode_port_28.BCM88675=XE27:core_0.28
+#XLP1
+#ucode_port_29.BCM88675=XE28:core_0.29
+#ucode_port_30.BCM88675=XE29:core_0.30
+#ucode_port_31.BCM88675=XE30:core_0.31
+#ucode_port_32.BCM88675=XE31:core_0.32
+#XLP2
+#ucode_port_33.BCM88675=XE32:core_0.33
+#ucode_port_34.BCM88675=XE33:core_0.34
+#ucode_port_35.BCM88675=XE34:core_0.35
+#ucode_port_36.BCM88675=XE35:core_0.36
+#XLP3
+#ucode_port_37.BCM88675=XE36:core_0.37
+#ucode_port_38.BCM88675=XE37:core_0.38
+#ucode_port_39.BCM88675=XE38:core_0.39
+#ucode_port_40.BCM88675=XE39:core_0.40
+#XLP4 (not as PMQ0)
+#ucode_port_41.BCM88675=XE40:core_0.41
+#ucode_port_42.BCM88675=XE41:core_0.42
+#ucode_port_43.BCM88675=XE42:core_0.43
+#ucode_port_44.BCM88675=XE43:core_0.44
+#XLP5 (not as PMQ1)
+#ucode_port_45.BCM88675=XE44:core_0.45
+#ucode_port_46.BCM88675=XE45:core_0.46
+#ucode_port_47.BCM88675=XE46:core_0.47
+#ucode_port_48.BCM88675=XE47:core_0.48
+#XLP9
+#ucode_port_49.BCM88675=XE60:core_0.49
+#ucode_port_50.BCM88675=XE61:core_0.50
+#ucode_port_51.BCM88675=XE62:core_0.51
+#ucode_port_52.BCM88675=XE63:core_0.52
+#XLP10
+#ucode_port_53.BCM88675=XE64:core_0.53
+#ucode_port_54.BCM88675=XE65:core_0.54
+#ucode_port_55.BCM88675=XE66:core_0.55
+#ucode_port_56.BCM88675=XE67:core_0.56
+#XLP11 (not as PMQ3)
+#ucode_port_57.BCM88675=XE68:core_0.57
+#ucode_port_58.BCM88675=XE69:core_0.58
+#ucode_port_59.BCM88675=XE70:core_0.59
+#ucode_port_60.BCM88675=XE71:core_0.60
+
+
+ucode_port_0.BCM88675=CPU.0:core_0.0
+ucode_port_0.BCM88680=CPU.0:core_0.0
+ucode_port_200.BCM88675=CPU.8:core_1.200
+ucode_port_200.BCM88680=CPU.8:core_1.200
+ucode_port_201.BCM88675=CPU.16:core_0.201
+ucode_port_201.BCM88680=CPU.16:core_0.201
+ucode_port_202.BCM88675=CPU.24:core_1.202
+ucode_port_202.BCM88680=CPU.24:core_1.202
+ucode_port_203.BCM88675=CPU.32:core_0.203
+ucode_port_203.BCM88680=CPU.32:core_0.203
+
+#default ports for Jericho and QMX
+ucode_port_1.BCM88675=CGE0:core_0.1
+ucode_port_2.BCM88675=ILKN1:core_0.2
+ilkn_lanes_1.BCM88675=0xfff000
+ucode_port_3.BCM88675=ILKN2:core_0.3
+ilkn_lanes_2.BCM88675=0xfff
+ucode_port_17.BCM88675=CGE1:core_1.17
+
+#default ports for Jericho
+ucode_port_13.BCM88675=10GBase-R64:core_0.13
+ucode_port_14.BCM88675=10GBase-R65:core_0.14
+ucode_port_15.BCM88675=10GBase-R68:core_1.15
+ucode_port_16.BCM88675=10GBase-R69:core_1.16
+
+#default ports for Jericho Plus
+ucode_port_13.BCM88680=10GBase-R40:core_0.13
+ucode_port_14.BCM88680=10GBase-R43:core_0.14
+ucode_port_15.BCM88680=10GBase-R44:core_1.15
+ucode_port_16.BCM88680=10GBase-R46:core_1.16
+
+#default ports for QMX
+ucode_port_13.BCM88375_A0=10GBase-R64:core_0.13
+ucode_port_14.BCM88375_A0=10GBase-R66:core_0.14
+ucode_port_15.BCM88375_A0=10GBase-R69:core_1.15
+ucode_port_16.BCM88375_A0=10GBase-R71:core_1.16
+
+
+ucode_port_13.BCM88375_B0=10GBase-R64:core_0.13
+ucode_port_14.BCM88375_B0=10GBase-R66:core_0.14
+ucode_port_15.BCM88375_B0=10GBase-R69:core_1.15
+ucode_port_16.BCM88375_B0=10GBase-R71:core_1.16
+
+
+#default ports for QAX
+ucode_port_0.BCM88470=CPU.0:core_0.0
+
+ucode_port_200.BCM88470=CPU.8:core_0.200
+
+ucode_port_201.BCM88470=CPU.16:core_0.201
+
+ucode_port_202.BCM88470=CPU.24:core_0.202
+
+ucode_port_203.BCM88470=CPU.32:core_0.203
+
+tm_port_header_type_in_0.BCM88470=INJECTED_2_PP
+tm_port_header_type_out_0.BCM88470=CPU
+
+ucode_port_1.BCM88470=XE47:core_0.1
+ucode_port_2.BCM88470=XE45:core_0.2
+ucode_port_3.BCM88470=XE17:core_0.3
+ucode_port_4.BCM88470=XE16:core_0.4
+ucode_port_5.BCM88470=XE23:core_0.5
+ucode_port_6.BCM88470=XE22:core_0.6
+#port_init_speed_xe1.BCM88470=2500
+pon_application_support_enabled_1.BCM88470=TRUE
+pon_application_support_enabled_3.BCM88470=TRUE
+pon_application_support_enabled_4.BCM88470=TRUE
+pon_application_support_enabled_5.BCM88470=TRUE
+pon_application_support_enabled_6.BCM88470=TRUE
+
+bcm886xx_rx_use_hw_trap_id.BCM88650=0
+
+#ucode_port_128.BCM88470=GE46:core_0.128
+#port_init_speed_ge46.BCM88470=1000
+ucode_port_128.BCM88470=XE46:core_0.128
+ucode_port_132.BCM88470=XE3:core_0.132
+ucode_port_131.BCM88470=XE2:core_0.131
+ucode_port_130.BCM88470=XE1:core_0.130
+ucode_port_129.BCM88470=XE0:core_0.129
+
+bcm886xx_rx_use_hw_trap_id.BCM88470=0
+
+stable_filename.BCM88270=/tmp/warmboot_data
+fap_device_mode.BCM88270=PP
+#default ports for QUX
+ucode_port_0.BCM88270=CPU.0:core_0.0
+ucode_port_200.BCM88270=CPU.8:core_0.100
+ucode_port_201.BCM88270=CPU.16:core_0.101
+ucode_port_202.BCM88270=CPU.24:core_0.102
+ucode_port_203.BCM88270=CPU.32:core_0.103
+ucode_port_1.BCM88270=XE0:core_0.1
+ucode_port_2.BCM88270=XE1:core_0.2
+ucode_port_3.BCM88270=XE2:core_0.3
+ucode_port_13.BCM88270=GE12:core_0.13
+ucode_port_14.BCM88270=GE13:core_0.14
+ucode_port_15.BCM88270=GE14:core_0.15
+ucode_port_16.BCM88270=GE15:core_0.16
+ucode_port_17.BCM88270=GE16:core_0.17
+
+
+#Firmware mode:
+#(Documantation relevant for BCM886xx and BCM887xx)
+# 0=DEFAULT
+# 1=SFP_OPT_SR4 - optical short range
+# 2=SFP_DAC - direct attach copper
+# 3=XLAUI - 40G XLAUI mode
+# 4=FORCE_OSDFE - force over sample digital feedback equalization
+# 5=FORCE_BRDFE - force baud rate digital feedback equalization
+# 6=SW_CL72 - software cl72 with AN on
+# 7=CL72_WITHOUT_AN - cl72 without AN
+#For Negev2 chassis enable DFE is recommended
+serdes_firmware_mode.BCM88650=2
+serdes_firmware_mode_il.BCM88650=4
+serdes_firmware_mode_sfi.BCM88650=0
+serdes_firmware_mode_sfi.BCM88675=4
+serdes_firmware_mode_sfi.BCM88470=4
+serdes_firmware_mode_sfi.BCM88270=4
+serdes_firmware_mode_sfi.BCM88680=4
+
+
+#ucode_port_1.BCM88650=10GBase-R0
+#ucode_port_2.BCM88650=10GBase-R1
+#ucode_port_3.BCM88650=10GBase-R2
+#ucode_port_4.BCM88650=10GBase-R3
+#ucode_port_5.BCM88650=10GBase-R4
+#ucode_port_6.BCM88650=10GBase-R5
+#ucode_port_7.BCM88650=10GBase-R6
+#ucode_port_8.BCM88650=10GBase-R7
+#ucode_port_9.BCM88650=10GBase-R8
+#ucode_port_10.BCM88650=10GBase-R9
+#ucode_port_11.BCM88650=10GBase-R10
+#ucode_port_12.BCM88650=10GBase-R11
+#ucode_port_13.BCM88650=10GBase-R12
+#ucode_port_14.BCM88650=10GBase-R13
+#ucode_port_15.BCM88650=10GBase-R14
+#ucode_port_16.BCM88650=10GBase-R15
+#ucode_port_17.BCM88650=10GBase-R16
+#ucode_port_18.BCM88650=10GBase-R17
+#ucode_port_19.BCM88650=10GBase-R18
+#ucode_port_20.BCM88650=10GBase-R19
+ucode_port_200.BCM88650=CPU.8
+ucode_port_201.BCM88650=CPU.16
+ucode_port_202.BCM88650=CPU.24
+ucode_port_203.BCM88650=CPU.32
+
+#40G
+#ucode_port_1.BCM88650=XLGE0
+#ucode_port_2.BCM88650=XLGE1
+#ucode_port_3.BCM88650=XLGE2
+#ucode_port_4.BCM88650=XLGE3
+#ucode_port_5.BCM88650=XLGE4
+#ucode_port_6.BCM88650=XLGE5
+#ucode_port_7.BCM88650=XLGE6
+
+#ILKN configuration - basic config
+#ucode_port_31.BCM88650=ILKN0
+#ucode_port_32.BCM88650=ILKN1
+#ucode_port_32.BCM88675=ILKN1:core_0.32
+#ilkn_num_lanes_0.BCM88650=12
+#ilkn_num_lanes_1.BCM88650=12
+#port_init_speed_il.BCM88650=10312
+
+
+#ILKN per port channel stat
+#ilkn_counters_mode.BCM88650=PACKET_PER_CHANNEL
+
+#ILKN configuration - advanced
+#ilkn_metaframe_sync_period=2048
+#ILKN burst configuration - ILKN max burst suppored values: 128, 256
+#ILKN burst short should be lesser or equal to burst max /2
+#ilkn_burst_max.BCM88675=256
+#ilkn_burst_min.BCM88675=32
+# Enable\Disable ILKN status message sent through an out-of-band interface.
+# ilkn_interface_status_oob_ignore.BCM88650=1
+
+# ilkn_is_burst_interleaving<ilkn_id>
+# 1 - The channelized interface functions in burst interleaving mode (default). 0 - in full packet mode.
+#ilkn_is_burst_interleaving_1.BCM88675=0
+
+##ILKN retransmit
+#ilkn_retransmit_enable_rx.BCM88650=1
+#ilkn_retransmit_enable_tx.BCM88650=1
+#ilkn_retransmit_buffer_size.BCM88650=250
+#ilkn_retransmit_num_requests_resent.BCM88650=15
+#ilkn_retransmit_num_sn_repetitions_tx.BCM88650=1
+#ilkn_retransmit_num_sn_repetitions_rx.BCM88650=1
+#ilkn_retransmit_rx_timeout_words.BCM88650=3800
+#ilkn_retransmit_rx_timeout_sn.BCM88650=250
+#ilkn_retransmit_rx_ignore.BCM88650=80
+#ilkn_retransmit_rx_reset_when_error_enable.BCM88650=1
+#ilkn_retransmit_rx_watchdog.BCM88650=0
+#ilkn_retransmit_rx_reset_when_alligned_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_retry_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_after_disc_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_before_disc_error_enable.BCM88650=0
+#ilkn_retransmit_rx_reset_when_timout_error_enable.BCM88650=0
+#ilkn_retransmit_tx_wait_for_seq_num_change_enable.BCM88650=1
+#ilkn_retransmit_tx_ignore_requests_when_fifo_almost_empty.BCM88650=1
+
+#ucode_port_40.BCM88650=RCY.0
+#ucode_port_41.BCM88650=RCY.1
+#ucode_port_42.BCM88650=RCY.2
+
+## CAUI Configuration
+#ucode_port_41.BCM88650=CGE0
+#ucode_port_42.BCM88650=CGE1
+caui_num_lanes_0.BCM88650=10
+caui_num_lanes_1.BCM88650=10
+#Required for working IXIA 100G port:
+mld_lane_swap_lane20_ce.BCM88650=0
+mld_lane_swap_lane21_ce.BCM88650=1
+mld_lane_swap_lane0_ce.BCM88650=20
+mld_lane_swap_lane1_ce.BCM88650=21
+
+# This configures the lane polarity
+pb_serdes_lane_swap_polarity_tx_phy1.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy3.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy4.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy5.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy6.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy7.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy8.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy13.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy14.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy18.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy19.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy22.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy23.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy24.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy25.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy27.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy28.BCM88650=1
+
+pb_serdes_lane_swap_polarity_rx_phy1.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy2.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy3.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy5.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy10.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy13.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy14.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy17.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy20.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy21.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy23.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy24.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy27.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy28.BCM88650=1
+
+xgxs_tx_lane_map_quad0.BCM88650=0x1032
+xgxs_tx_lane_map_quad1.BCM88650=0x2310
+xgxs_tx_lane_map_quad2.BCM88650=0x3210
+xgxs_tx_lane_map_quad3.BCM88650=0x3210
+xgxs_tx_lane_map_quad4.BCM88650=0x1230
+xgxs_tx_lane_map_quad5.BCM88650=0x3201
+xgxs_tx_lane_map_quad6.BCM88650=0x2103
+xgxs_tx_lane_map_quad7.BCM88650=0x0123
+
+xgxs_rx_lane_map_quad0.BCM88650=0x3012
+xgxs_rx_lane_map_quad1.BCM88650=0x0132
+xgxs_rx_lane_map_quad2.BCM88650=0x1230
+xgxs_rx_lane_map_quad3.BCM88650=0x0123
+xgxs_rx_lane_map_quad4.BCM88650=0x3012
+xgxs_rx_lane_map_quad5.BCM88650=0x2013
+xgxs_rx_lane_map_quad6.BCM88650=0x2103
+
+
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88650=1
+
+#Port init mode
+#port_init_duplex=0
+#port_init_adv=0
+#port_init_autoneg=0
+
+
+# This disables serdes initialization
+# phy_null.BCM88650=1
+
+## Number of Internal ports
+# Enable the ERP port. Values: 0 / 1.
+num_erp_tm_ports.BCM88650=1
+# Enable the OLP port. Values: 0 / 1.
+num_olp_tm_ports.BCM88650=1
+
+## Firmware Load Method
+load_firmware.BCM88650=0x102
+load_firmware.BCM88675=0x102
+load_firmware_fabric.BCM88675=0x102
+load_firmware_fabric.BCM88680=0x102
+
+### Headers configuration ###
+
+## Use of the tm_port_header_type_<Local-Port-Id>=<Header-type>
+## Default header type is derived from fap_device_mode: If fap_device_mode is
+## PP, default header type is ETH. Otherwise, defualt header type is TM.
+## Header type per port can be overriden.
+## All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/UDH_ETH
+## Injected header types: if PTCH, INJECTED (local Port of type TM) or INJECTED_PP (PP)
+## if PTCH-2, INJECTED_2 (local Port of type TM) or INJECTED_2_PP (PP)
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88650=TM
+
+tm_port_header_type_in_0.BCM88650=INJECTED_2
+tm_port_header_type_out_0.BCM88650=TM
+
+tm_port_header_type_in_200.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_200.BCM88650=ETH
+tm_port_header_type_in_201.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_201.BCM88650=ETH
+tm_port_header_type_in_202.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_202.BCM88650=ETH
+tm_port_header_type_in_203.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_203.BCM88650=ETH
+
+
+### Parser Configuration ###
+# Parser has 4 custom macros that are allocated dynamically and
+# configured according to the following features and soc properties:
+# Trill (1 macro) - trill_mode
+# FCoE (2 macros) - bcm886xx_fcoe_switch_mode
+# VxLAN (1 macro) - bcm886xx_vxlan_enable
+# IPv6-Extension-header (2 macros) - bcm886xx_ipv6_ext_hdr_enable
+# UDP (1 macro) - UDP parsing is enabled by default, and can be
+# disabled with soc property custom_feature_udp_parse_disable
+# When disabling UDP parsing VxLAN and 1588oUDP are affected
+
+
+# In FCoE NPV switch, if set to 1,
+# packets that ingress from the N_PORT are treated as bridge
+# and packets that ingress from the NP_PORT are treated as router
+#fcoe_npv_bridge_mode=1
+# Enable IPv6 Extension Header, 0 - disable (default), 1 - enable
+#bcm886xx_ipv6_ext_hdr_enable=1
+
+# Disable UDP parsing, 0 - enable (default), 1 - disable
+#custom_feature_udp_parse_disable=1
+
+#OAMP/SAT port
+#tm_port_header_type_out_232.BCM88650=CPU
+tm_port_header_type_out_232.BCM88675=CPU
+
+### SAT
+## Enable SAT Interface. 0 - Disable, 1 - Enable (Default)
+sat_enable=1
+
+# Set the recycling port processing to be raw (static forwarding)
+tm_port_header_type_rcy.BCM88650=RAW
+
+### RCPU
+# Valid CPU local ports on which RCPU packets can be received by slave device.
+#rcpu_rx_pbmp=0xf00000000000000000000000000000000000000000000000001
+
+#tm_port_header_type_514.BCM88650=RAW
+
+## Header extensions
+# Set if an FTMH Out-LIF extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS
+fabric_ftmh_outlif_extension.BCM88650=IF_MC
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88660: ENABLED, FULL_HASH
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY
+# / 16B_STACKING_ROUTE_HISTORY / STANDBY_MC_LB (available only for AradPlus)
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88650=DISABLED
+
+# Set if an OTMH Out-LIF (CUD) Extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS / DOUBLE_TAG (two hop scheduling) / EXTENDED: Extended 24 bit CUD
+# Default: NEVER
+# tm_port_otmh_outlif_ext_mode_13.BCM88650=NEVER
+
+# Set if an OTMH Source-System-Port Extension is present.
+# Option: 0/1
+# Default: 0
+# tm_port_otmh_src_ext_enable_13.BCM88650=0
+
+#Trunk hash format, relevant only for AradPlus. Possible values: NORMAL (default) / INVERTED / DUPLICATED.
+#trunk_hash_format=NORMAL
+
+## Stacking Application
+#stacking_enable.BCM88650=1
+
+## Determine if FTMH Destination System Port Extension is added to all Ethernet packets.
+#ftmh_dsp_extension_add=1
+
+## Determine if FTMH Destination System Port Extension of mirrored/snooped packets is stamped with the original destination.
+#mirror_stamp_sys_on_dsp_ext=1
+
+## System RED
+# Set System-Red functionality.
+#system_red_enable.BCM88650=1
+
+# Indicate the size (Bytes) of a first header to skip
+# before the major header at ingress (e.g. Ethernet, ITMH)
+# It can be set per port also
+first_header_size.BCM88650=0
+
+# Indicate the size (Bytes) of the PMF Extension Headers
+# to remove for TM header type ports (expecting ITMH)
+# Set per port
+#post_headers_size_0.BCM88650=4
+
+# Indicate the size (Bytes) of the User-Headers: configurable
+# headers located in the fabric between internal headers and
+# Ethernet. Their values are set by Ingress FP, and can be used
+# by Egress FP or Egress Editor.
+# units: bits. 4 values can be set:
+# 0 - size of the 1st User-Header, for the Egress PMF. 0b / 8b / 16b
+# 1 - size of the 2nd User-Header, for the Egress PMF. 0b / 8b / 16b
+# The sum of these 2 values should be under 16b
+# 2, 3 - size of the 1st/2nd User-Header, for the Egress Editor.
+# 0b / 8b / 16b / 24b / 32b
+# Each of the global User-Header size must be under 32 bits, but not 24 bits.
+# The Egress FP field is always at the MSB of the User-Header
+# Not available for 88650-A0.
+#field_class_id_size_0.BCM88650=8
+#field_class_id_size_1.BCM88650=0
+#field_class_id_size_2.BCM88650=24
+#field_class_id_size_3.BCM88650=0
+
+
+### Trunk - LAG configuration ###
+# Set the number of LAGs: 1024, 512, 256, 128 or 64
+number_of_trunks.BCM88650=256
+# Using the lb-key's MSB in trunk resolutions.
+# 0 = use LSB (default)
+# 1 = use MSB
+trunk_resolve_use_lb_key_msb_stack = 0
+trunk_resolve_use_lb_key_msb_smooth_division = 0
+
+### SYNCE configuration ###
+## Synchronous Ethernet Signal Mode.
+## Options: TWO_DIFF_CLK, TWO_CLK_AND_VALID. Default: TWO_CLK_AND_VALID
+#sync_eth_mode.BCM88650=TWO_CLK_AND_VALID
+
+## Clock Source (single SerDes) lane in the specified NIF port.
+## Usage: sync_eth_clk_to_nif_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_nif_id_clk_0.BCM88650=1
+#sync_eth_clk_to_nif_id_clk_1.BCM88650=1
+
+## Clock Divider for the selected recovered clock. Valid values: 1/2/4. Default: 1.
+## Usage: sync_eth_clk_divider_clk_<clk_number>=<1/2/4>
+#sync_eth_clk_divider_clk_0.BCM88650=1
+#sync_eth_clk_divider_clk_1.BCM88650=1
+
+## Usage: sync_eth_clk_to_port_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_port_id_clk_0.BCM88675=13
+#sync_eth_clk_to_port_id_clk_1.BCM88675=13
+
+## Clock frequency selector for the selected recovered clock. Valid values: <125MHz-0/156.25MHz-1/25MHz-2>. Default: 1.
+## Usage: sync_eth_clk_divider_clk<clk_id>=<0-125MHz/1-156.25MHz/2-25MHz>
+#sync_eth_clk_divider_clk0.BCM88675=1
+#sync_eth_clk_divider_clk1.BCM88675=1
+
+## Enable the automatic squelch function for the recovered clock. Valid values: 0/1. Default: 0.
+## Usage: sync_eth_clk_squelch_enable_clk_<clk_number>=<0/1>
+#sync_eth_clk_squelch_enable_clk_0.BCM88650=0
+#sync_eth_clk_squelch_enable_clk_1.BCM88650=0
+
+### ELK configuration ###
+## External lookup (TCAM) Device type select, Indicate the External lookup Device type.
+# Value Options: NONE/NL88650. Default: NONE.
+#ext_tcam_dev_type=NL88650
+
+
+##External lookup (elk) ILKN lanes swap. If set, reverse the lanes numbering order on elk device side. DNX system default is 1.
+#ext_ilkn_reverse=0
+
+## Set ELK FWD table Size.
+# format: ext_xxx_fwd_table_size.
+# where xxx replaced by FWD options: ip4_uc_rpf/ip4_mc/ip6_uc_rpf/ip6/ip6_mc/trill_uc/trill_mc/mpls/coup_mpls
+# Value Options: (0) - External table disabled, >0: number of entries. Default: 0.
+#ext_ip4_uc_rpf_fwd_table_size=8192
+#ext_ip4_mc_fwd_table_size=8192
+
+#External TCAM result size, allows to modify each external tcam result size.
+#The total size of the external result for NL12K = 120bit .
+#The size of each segment updates the corresponding qualifier bcmFieldQualifyExternalValue.
+#Default values according to the device property.
+#in-case of double capacity use the following values: 48,48,24,24 and ext_tcam_result_size_segment_pad_3=24
+
+#ext_tcam_result_size_segment_0=48
+#ext_tcam_result_size_segment_1=32
+#ext_tcam_result_size_segment_2=24
+#ext_tcam_result_size_segment_3=16
+#ext_tcam_result_size_segment_4=32
+#ext_tcam_result_size_segment_5=32
+
+## Set ELK IP FWD use NetRoute ALG.
+# Value Options: ALG_LPM_LPM/ALG_LPM_NETROUTE/ALG_LPM_TCAM. Default: ALG_LPM_TCAM.
+#ext_fwd_algorithm_lpm=ALG_LPM_TCAM
+
+## Set ELK interface mode.
+# Change ELK interface configuration to support CAUI port.
+# Value Options: 0/1. 0 - Normal mode, 1 2 CAUI port + ELK mode. Default: 0.
+#ext_interface_mode=0
+
+### Configure MDIO interface
+# External MDIO clock rate divisor . Default: 0x24.
+#rate_ext_mdio_divisor=0x36
+# External MDIO clock rate divisor. Default: 0x1.
+#rate_ext_mdio_dividend=1
+
+### TDM - OTN configuration ###
+# Options: 0 / TDM_OPTIMIZED / TDM_STANDARD
+fap_tdm_bypass.BCM88650=0
+
+### TDM - RAW/PACKET configuration ###
+# if fap_tdm_packet config to be true, enable specific ports on the device to configure for tdm packet mode traffic.
+fap_tdm_packet.BCM88650=0
+
+# Indicate if a Petra-B device is connected to the actual device
+# For TDM/OTN applications,
+# system_is_petra_b_in_system.BCM88650=0
+##Indicate if TDM can arrive throgh primary pipe.
+#Should be 1 for a System with PetraB that connected to fabric over primary pipe.
+fabric_tdm_over_primary_pipe.BCM88650=0
+
+### Fabric configuration ###
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88650=2
+#Possible values - KR_FEC, 64_66, RS_FEC, LL_RS_FEC
+backplane_serdes_encoding.BCM88675=RS_FEC
+backplane_serdes_encoding.BCM88470=RS_FEC
+backplane_serdes_encoding.BCM88270=RS_FEC
+backplane_serdes_encoding.BCM88680=RS_FEC
+
+#SFI speed rate
+port_init_speed_sfi.BCM88650=10312
+port_init_speed_sfi.BCM88675=25000
+port_init_speed_sfi.BCM88470=25000
+port_init_speed_sfi.BCM88270=25000
+port_init_speed_sfi.BCM88680=25000
+
+#CL72
+port_init_cl72_sfi.BCM88650=1
+port_init_cl72_sfi.BCM88675=1
+fabric_segmentation_enable.BCM88650=1
+
+## Fabric transmission mode
+# Set the Connect mode to the Fabric
+# Options: FE - presence of a Fabric device (single stage) / MULT_STAGE_FE - Multi-stage /
+# SINGLE_FAP - stand-alone device / MESH - mesh / BACK2BACK - 2 devices in Mesh
+#fabric_connect_mode.BCM88650=SINGLE_FAP
+fabric_connect_mode.BCM88650=FE
+# The Jericho configuration below will be overriden in jer.soc for multi device configurations
+fabric_connect_mode.BCM88675=SINGLE_FAP
+fabric_connect_mode.BCM88470=SINGLE_FAP
+fabric_connect_mode.BCM88270=SINGLE_FAP
+fabric_connect_mode.BCM88680=SINGLE_FAP
+
+
+## Cell format configuration
+# Indicate if the traffic can be sent in dual pipe
+is_dual_mode.BCM88650=0
+# Indicate on the existance of dual pipe device mode in system
+system_is_dual_mode_in_system.BCM88650=0
+
+# Indicate the format of the cell:
+# A VCS128 cell is used if system_is_vcs_128_in_system or system_is_fe600_in_system is TRUE
+system_is_vcs_128_in_system.BCM88650=0
+system_is_fe600_in_system.BCM88650=0
+
+### WRED ###
+
+# Set the maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88650=0
+
+### OCB (On-Chip Buffer) configuration ###
+# Enable the OCB
+# Enable MODES:
+# 0/FALSE --> OCB_DISABLED --> No OCB use
+# 1/TRUE --> OCB_ENABLED --> Like in Arad-A0/B0. Some packets may use both DRAM and OCB resources
+# ONE_WAY_BYPASS --> Depends on number of present drams (available only for AradPlus):
+# 0 drams: - OCB_ONLY
+# 1 drams: - OCB_ONLY_1_DRAM --> : OCB-only with 1 DRAM for the free pointers
+# 2-8 drams: - OCB_DRAM_SEPARATE --> : OCB and DRAM coexist separately
+# Default: TRUE.
+bcm886xx_ocb_enable.BCM88650=1
+
+## OCB (On-Chip Buffer) configuration
+# OCB modes:
+# 0 - Disabled
+# 1 - Enabled (Default).
+bcm886xx_ocb_enable.BCM88675=1
+
+# OCB Data Buffer size. Possible values: 128/256/512/1024. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88650=256
+# OCB Data Buffer size. Jericho allowed values: 256/512. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88675=256
+# Repartition between Unicast and Full Multicast buffers.
+# 0: 80% Unicast and 20% Multicast, 1: Unicast-Only
+bcm886xx_ocb_repartition.BCM88650=0
+
+
+### PDM configuration ###
+# Set the PDM Mode.
+# 0: simple (default), 1: extended (mandatory for LLFC-VSQ, PFC-VSQ, or ST-VSQ)
+bcm886xx_pdm_mode.BCM88650=0
+
+### Multicast Number of DBuff mode ###
+# Set IQM FMC buffers-replication sizes
+# Options for 88650: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE/ARAD_INIT_FMC_64_REP_128K_DBUFF_MODE
+# Default: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88650=ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+
+### Multicast Number of DBuff mode ###
+# Set FMC buffers-replication sizes
+# Options for 88675:
+# JERICHO_INIT_FMC_64_REP_512K_DBUFF_MODE
+# JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE (Default)
+# JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88675=JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88470=JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88270=JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88680=JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE
+
+
+### Multicast configuration ###
+# Multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_max.BCM88650=4095
+
+#### Jericho configuration of the number of ingress/egress multicast groups
+# Ingress max MCID can be up to 131070, Egress max MCID in Mesh or single FAP modes is up to 65535,
+# or otherwise is up to 131071.
+#multicast_ingress_group_id_range_max.BCM88675=32768
+#multicast_egress_group_id_range_max.BCM88675=60000
+
+### VOQ - Flow configuration ###
+
+# Set the VOQ mapping mode:
+# DIRECT: More than 4K System Ports are supported. System-level WRED is not supported.
+# INDIRECT: similar to Petra-B. Up to 4K System Ports.
+voq_mapping_mode.BCM88650=INDIRECT
+
+#Enable/disable HQOS support - mapping of many system ports to single modport
+hqos_mapping_enable.BCM88650=0
+
+# Set the Base Queue to be added to the packet flow-id
+# when the Flow-Id is set explicitely either by the ITMH
+# or by the Destination resolution in the Packet processing
+flow_mapping_queue_base.BCM88650=0
+
+
+# The allocation of the total per core resources between source and
+# queue based reservation depends on one of two guarantee modes: strict and loose.
+#ingress_congestion_management_guarantee_mode={STRICT,LOOSE} default: STRICT
+ingress_congestion_management_guarantee_mode=LOOSE
+# Each DP has its own thresholds for source based (dynamic) and for queue based (pools 0,1 and headroom).
+# ingress_congestion_management_{source,queue,all}_threshold_percentage_color_[0-3]=[0-100] default: 100,85,75,0
+# ingress_congestion_management_{ocb_only,dram_mix}_{pool_{0,1},headroom}=size default: 0
+# ingress_congestion_management_min_resource_percentage_dynamic=[0-80] default: 20
+
+# Configure maximum IDs of ST-VSQs, maximum IDs of TM-ports, and enabling/disabling header compensation.
+ingress_congestion_management_stag_max_id.BCM88675=0
+ingress_congestion_management_tm_port_max_id.BCM88675=255
+ingress_congestion_management_pkt_header_compensation_enable.BCM88675=0
+
+# The number of packet buffers used for the allocation of DMA memory at BCM RX task
+# The pool size determined by nof_pkts (256) * 16K.
+#rx_pool_nof_pkts.BCM88675=256
+
+
+# Set the number of priorities supported at egress per Port
+# Options: 1 / 2 / 8
+port_priorities.BCM88650=8
+port_priorities.BCM88675=2
+port_priorities.BCM88470=2
+port_priorities.BCM88270=2
+port_priorities.BCM88680=2
+
+
+# Set the shared multicast resource mode: Strict / Discrete
+egress_shared_resources_mode.BCM88650=Strict
+
+# Define outgoing port rate mode in data rate or packet rate.
+# Options: DATA / PACKET
+otm_port_packet_rate.BCM88650=DATA
+
+# Set Port egress recycling scheduler configuration.
+# 0: Strict Priority Scheduler, 1: Round Robin Scheduler
+port_egress_recycling_scheduler_configuration.BCM88650=0
+
+# Set statically the region mode per region id
+# 0: queue connectors only (InterDigitated = FALSE, OddEven = TRUE)
+# 1: queue connectors, SE (InterDigitated =TRUE, OddEven = TRUE)
+# 2: queue connectors, SE (InterDigitated =TRUE, OddEven = FALSE)
+dtm_flow_mapping_mode_region_65.BCM88650=0
+dtm_flow_mapping_mode_region_66.BCM88650=0
+dtm_flow_mapping_mode_region_67.BCM88650=0
+dtm_flow_mapping_mode_region_68.BCM88650=0
+dtm_flow_mapping_mode_region_69.BCM88650=0
+dtm_flow_mapping_mode_region_70.BCM88650=0
+dtm_flow_mapping_mode_region_71.BCM88650=0
+dtm_flow_mapping_mode_region_72.BCM88650=0
+dtm_flow_mapping_mode_region_73.BCM88650=0
+dtm_flow_mapping_mode_region_74.BCM88650=0
+dtm_flow_mapping_mode_region_75.BCM88650=0
+dtm_flow_mapping_mode_region_76.BCM88650=0
+dtm_flow_mapping_mode_region_77.BCM88650=0
+dtm_flow_mapping_mode_region_78.BCM88650=0
+dtm_flow_mapping_mode_region_79.BCM88650=0
+dtm_flow_mapping_mode_region_80.BCM88650=0
+dtm_flow_mapping_mode_region_81.BCM88650=1
+dtm_flow_mapping_mode_region_82.BCM88650=1
+dtm_flow_mapping_mode_region_83.BCM88650=1
+dtm_flow_mapping_mode_region_84.BCM88650=1
+dtm_flow_mapping_mode_region_85.BCM88650=1
+dtm_flow_mapping_mode_region_86.BCM88650=1
+dtm_flow_mapping_mode_region_87.BCM88650=1
+dtm_flow_mapping_mode_region_88.BCM88650=1
+dtm_flow_mapping_mode_region_89.BCM88650=1
+dtm_flow_mapping_mode_region_90.BCM88650=1
+dtm_flow_mapping_mode_region_91.BCM88650=1
+dtm_flow_mapping_mode_region_92.BCM88650=1
+dtm_flow_mapping_mode_region_93.BCM88650=1
+dtm_flow_mapping_mode_region_94.BCM88650=1
+dtm_flow_mapping_mode_region_95.BCM88650=1
+dtm_flow_mapping_mode_region_96.BCM88650=1
+dtm_flow_mapping_mode_region_97.BCM88650=1
+dtm_flow_mapping_mode_region_98.BCM88650=1
+dtm_flow_mapping_mode_region_99.BCM88650=2
+dtm_flow_mapping_mode_region_100.BCM88650=2
+dtm_flow_mapping_mode_region_101.BCM88650=2
+dtm_flow_mapping_mode_region_102.BCM88650=2
+dtm_flow_mapping_mode_region_103.BCM88650=2
+dtm_flow_mapping_mode_region_104.BCM88650=2
+dtm_flow_mapping_mode_region_105.BCM88650=2
+dtm_flow_mapping_mode_region_106.BCM88650=2
+dtm_flow_mapping_mode_region_107.BCM88650=2
+dtm_flow_mapping_mode_region_108.BCM88650=2
+dtm_flow_mapping_mode_region_109.BCM88650=2
+dtm_flow_mapping_mode_region_110.BCM88650=2
+dtm_flow_mapping_mode_region_111.BCM88650=2
+dtm_flow_mapping_mode_region_112.BCM88650=2
+dtm_flow_mapping_mode_region_113.BCM88650=2
+dtm_flow_mapping_mode_region_114.BCM88650=2
+dtm_flow_mapping_mode_region_115.BCM88650=2
+dtm_flow_mapping_mode_region_116.BCM88650=2
+dtm_flow_mapping_mode_region_117.BCM88650=2
+dtm_flow_mapping_mode_region_118.BCM88650=2
+dtm_flow_mapping_mode_region_119.BCM88650=2
+dtm_flow_mapping_mode_region_120.BCM88650=2
+dtm_flow_mapping_mode_region_121.BCM88650=2
+dtm_flow_mapping_mode_region_122.BCM88650=2
+dtm_flow_mapping_mode_region_123.BCM88650=2
+dtm_flow_mapping_mode_region_124.BCM88650=2
+dtm_flow_mapping_mode_region_125.BCM88650=2
+dtm_flow_mapping_mode_region_126.BCM88650=2
+dtm_flow_mapping_mode_region_127.BCM88650=2
+dtm_flow_mapping_mode_region_128.BCM88650=2
+
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88650=2
+dtm_flow_nof_remote_cores_region_2.BCM88650=2
+dtm_flow_nof_remote_cores_region_3.BCM88650=2
+dtm_flow_nof_remote_cores_region_4.BCM88650=2
+dtm_flow_nof_remote_cores_region_5.BCM88650=2
+dtm_flow_nof_remote_cores_region_6.BCM88650=2
+dtm_flow_nof_remote_cores_region_7.BCM88650=2
+dtm_flow_nof_remote_cores_region_8.BCM88650=2
+dtm_flow_nof_remote_cores_region_9.BCM88650=2
+dtm_flow_nof_remote_cores_region_10.BCM88650=2
+dtm_flow_nof_remote_cores_region_11.BCM88650=2
+dtm_flow_nof_remote_cores_region_12.BCM88650=2
+dtm_flow_nof_remote_cores_region_13.BCM88650=2
+dtm_flow_nof_remote_cores_region_14.BCM88650=2
+dtm_flow_nof_remote_cores_region_15.BCM88650=2
+dtm_flow_nof_remote_cores_region_16.BCM88650=2
+dtm_flow_nof_remote_cores_region_17.BCM88650=2
+dtm_flow_nof_remote_cores_region_18.BCM88650=2
+dtm_flow_nof_remote_cores_region_19.BCM88650=2
+dtm_flow_nof_remote_cores_region_20.BCM88650=2
+dtm_flow_nof_remote_cores_region_21.BCM88650=2
+dtm_flow_nof_remote_cores_region_22.BCM88650=2
+dtm_flow_nof_remote_cores_region_23.BCM88650=2
+dtm_flow_nof_remote_cores_region_24.BCM88650=2
+dtm_flow_nof_remote_cores_region_25.BCM88650=2
+dtm_flow_nof_remote_cores_region_26.BCM88650=2
+dtm_flow_nof_remote_cores_region_27.BCM88650=2
+dtm_flow_nof_remote_cores_region_28.BCM88650=2
+dtm_flow_nof_remote_cores_region_29.BCM88650=2
+dtm_flow_nof_remote_cores_region_30.BCM88650=2
+dtm_flow_nof_remote_cores_region_31.BCM88650=2
+dtm_flow_nof_remote_cores_region_32.BCM88650=2
+dtm_flow_nof_remote_cores_region_33.BCM88650=2
+dtm_flow_nof_remote_cores_region_34.BCM88650=2
+dtm_flow_nof_remote_cores_region_35.BCM88650=2
+dtm_flow_nof_remote_cores_region_36.BCM88650=2
+dtm_flow_nof_remote_cores_region_37.BCM88650=2
+dtm_flow_nof_remote_cores_region_38.BCM88650=2
+dtm_flow_nof_remote_cores_region_39.BCM88650=2
+dtm_flow_nof_remote_cores_region_40.BCM88650=2
+dtm_flow_nof_remote_cores_region_41.BCM88650=2
+dtm_flow_nof_remote_cores_region_42.BCM88650=2
+dtm_flow_nof_remote_cores_region_43.BCM88650=2
+dtm_flow_nof_remote_cores_region_44.BCM88650=2
+dtm_flow_nof_remote_cores_region_45.BCM88650=2
+dtm_flow_nof_remote_cores_region_46.BCM88650=2
+dtm_flow_nof_remote_cores_region_47.BCM88650=2
+dtm_flow_nof_remote_cores_region_48.BCM88650=2
+dtm_flow_nof_remote_cores_region_49.BCM88650=2
+dtm_flow_nof_remote_cores_region_50.BCM88650=2
+dtm_flow_nof_remote_cores_region_51.BCM88650=2
+dtm_flow_nof_remote_cores_region_52.BCM88650=2
+dtm_flow_nof_remote_cores_region_53.BCM88650=2
+dtm_flow_nof_remote_cores_region_54.BCM88650=2
+dtm_flow_nof_remote_cores_region_55.BCM88650=2
+dtm_flow_nof_remote_cores_region_56.BCM88650=2
+dtm_flow_nof_remote_cores_region_57.BCM88650=2
+dtm_flow_nof_remote_cores_region_58.BCM88650=2
+dtm_flow_nof_remote_cores_region_59.BCM88650=2
+dtm_flow_nof_remote_cores_region_60.BCM88650=2
+#dtm_flow_nof_remote_cores_region_core0_2.BCM88675=2
+
+## Configure number of symmetric cores each region supports ##
+#device_core_mode.BCM88470=SINGLE_CORE
+# IL region has offset of 63, i.e. region_1 here will show as region 64 in code
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88470=2
+dtm_flow_nof_remote_cores_region_2.BCM88470=2
+dtm_flow_nof_remote_cores_region_3.BCM88470=1
+dtm_flow_nof_remote_cores_region_4.BCM88470=1
+dtm_flow_nof_remote_cores_region_5.BCM88470=2
+dtm_flow_nof_remote_cores_region_6.BCM88470=1
+dtm_flow_nof_remote_cores_region_7.BCM88470=2
+dtm_flow_nof_remote_cores_region_8.BCM88470=2
+dtm_flow_nof_remote_cores_region_9.BCM88470=1
+dtm_flow_nof_remote_cores_region_10.BCM88470=1
+dtm_flow_nof_remote_cores_region_11.BCM88470=1
+dtm_flow_nof_remote_cores_region_12.BCM88470=1
+dtm_flow_nof_remote_cores_region_13.BCM88470=1
+dtm_flow_nof_remote_cores_region_14.BCM88470=1
+dtm_flow_nof_remote_cores_region_15.BCM88470=1
+dtm_flow_nof_remote_cores_region_16.BCM88470=1
+dtm_flow_nof_remote_cores_region_17.BCM88470=1
+dtm_flow_nof_remote_cores_region_18.BCM88470=2
+dtm_flow_nof_remote_cores_region_19.BCM88470=1
+dtm_flow_nof_remote_cores_region_20.BCM88470=1
+dtm_flow_nof_remote_cores_region_21.BCM88470=1
+dtm_flow_nof_remote_cores_region_22.BCM88470=1
+dtm_flow_nof_remote_cores_region_23.BCM88470=1
+dtm_flow_nof_remote_cores_region_24.BCM88470=1
+dtm_flow_nof_remote_cores_region_25.BCM88470=1
+dtm_flow_nof_remote_cores_region_26.BCM88470=1
+dtm_flow_nof_remote_cores_region_27.BCM88470=1
+dtm_flow_nof_remote_cores_region_28.BCM88470=1
+dtm_flow_nof_remote_cores_region_29.BCM88470=1
+dtm_flow_nof_remote_cores_region_30.BCM88470=1
+dtm_flow_nof_remote_cores_region_31.BCM88470=1
+dtm_flow_nof_remote_cores_region_32.BCM88470=1
+dtm_flow_nof_remote_cores_region_33.BCM88470=1
+dtm_flow_nof_remote_cores_region_34.BCM88470=1
+dtm_flow_nof_remote_cores_region_35.BCM88470=1
+dtm_flow_nof_remote_cores_region_36.BCM88470=1
+
+dtm_flow_nof_remote_cores_region_37.BCM88470=1
+dtm_flow_nof_remote_cores_region_38.BCM88470=1
+dtm_flow_nof_remote_cores_region_39.BCM88470=1
+dtm_flow_nof_remote_cores_region_40.BCM88470=1
+dtm_flow_nof_remote_cores_region_41.BCM88470=1
+dtm_flow_nof_remote_cores_region_42.BCM88470=1
+dtm_flow_nof_remote_cores_region_43.BCM88470=1
+dtm_flow_nof_remote_cores_region_44.BCM88470=1
+dtm_flow_nof_remote_cores_region_45.BCM88470=1
+dtm_flow_nof_remote_cores_region_46.BCM88470=1
+dtm_flow_nof_remote_cores_region_47.BCM88470=1
+dtm_flow_nof_remote_cores_region_48.BCM88470=1
+dtm_flow_nof_remote_cores_region_49.BCM88470=1
+dtm_flow_nof_remote_cores_region_50.BCM88470=1
+dtm_flow_nof_remote_cores_region_51.BCM88470=1
+dtm_flow_nof_remote_cores_region_52.BCM88470=1
+dtm_flow_nof_remote_cores_region_53.BCM88470=1
+dtm_flow_nof_remote_cores_region_54.BCM88470=1
+dtm_flow_nof_remote_cores_region_55.BCM88470=1
+dtm_flow_nof_remote_cores_region_56.BCM88470=1
+dtm_flow_nof_remote_cores_region_57.BCM88470=1
+dtm_flow_nof_remote_cores_region_58.BCM88470=1
+dtm_flow_nof_remote_cores_region_59.BCM88470=1
+dtm_flow_nof_remote_cores_region_60.BCM88470=1
+
+dtm_flow_mapping_mode_region_33.BCM88470=0
+dtm_flow_mapping_mode_region_34.BCM88470=0
+dtm_flow_mapping_mode_region_35.BCM88470=0
+dtm_flow_mapping_mode_region_36.BCM88470=0
+dtm_flow_mapping_mode_region_37.BCM88470=0
+dtm_flow_mapping_mode_region_38.BCM88470=0
+dtm_flow_mapping_mode_region_39.BCM88470=0
+dtm_flow_mapping_mode_region_40.BCM88470=0
+
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88270=2
+dtm_flow_nof_remote_cores_region_2.BCM88270=2
+dtm_flow_nof_remote_cores_region_3.BCM88270=2
+dtm_flow_nof_remote_cores_region_4.BCM88270=2
+dtm_flow_nof_remote_cores_region_5.BCM88270=2
+dtm_flow_nof_remote_cores_region_6.BCM88270=2
+dtm_flow_nof_remote_cores_region_7.BCM88270=2
+dtm_flow_nof_remote_cores_region_8.BCM88270=2
+dtm_flow_nof_remote_cores_region_9.BCM88270=2
+dtm_flow_nof_remote_cores_region_10.BCM88270=2
+dtm_flow_nof_remote_cores_region_11.BCM88270=2
+dtm_flow_nof_remote_cores_region_12.BCM88270=2
+dtm_flow_nof_remote_cores_region_13.BCM88270=2
+dtm_flow_nof_remote_cores_region_14.BCM88270=2
+dtm_flow_nof_remote_cores_region_15.BCM88270=2
+dtm_flow_nof_remote_cores_region_16.BCM88270=2
+dtm_flow_nof_remote_cores_region_17.BCM88270=2
+dtm_flow_nof_remote_cores_region_18.BCM88270=2
+dtm_flow_nof_remote_cores_region_19.BCM88270=1
+dtm_flow_nof_remote_cores_region_20.BCM88270=1
+dtm_flow_nof_remote_cores_region_21.BCM88270=1
+dtm_flow_nof_remote_cores_region_22.BCM88270=1
+dtm_flow_nof_remote_cores_region_23.BCM88270=1
+dtm_flow_nof_remote_cores_region_24.BCM88270=1
+dtm_flow_nof_remote_cores_region_25.BCM88270=1
+dtm_flow_nof_remote_cores_region_26.BCM88270=1
+dtm_flow_nof_remote_cores_region_27.BCM88270=1
+dtm_flow_nof_remote_cores_region_28.BCM88270=1
+dtm_flow_nof_remote_cores_region_29.BCM88270=1
+dtm_flow_nof_remote_cores_region_30.BCM88270=1
+dtm_flow_nof_remote_cores_region_31.BCM88270=1
+dtm_flow_nof_remote_cores_region_32.BCM88270=1
+
+dtm_flow_mapping_mode_region_17.BCM88270=0
+dtm_flow_mapping_mode_region_18.BCM88270=0
+dtm_flow_mapping_mode_region_19.BCM88270=0
+dtm_flow_mapping_mode_region_20.BCM88270=0
+
+### Flow Control configuration ###
+# Set the Flow control type per Port.
+# Options: LL (Link-level) / CB2 (Class-Based - 2 classes) /
+# CB8 (Class-Based - 8 classes)
+# flow_control_type.BCM88650=LL
+
+## Out-Of-Band Flow control configuration
+#spn_FC_OOB_TYPE, spn_FC_OOB_MODE, spn_FC_OOB_CALENDER_LENGTH, spn_FC_OOB_CALENDER_REP_COUNT,
+
+## Set voltage mode for oob interfaces
+#HSTL_1.5V
+#3.3V
+#HSTL_1.5V_VDDO_DIV_2
+ext_voltage_mode_oob=3.3V
+
+## Inband Interlaken configuration
+# spn_FC_INBAND_INTLKN_MODE, spn_FC_INBAND_INTLKN_CALENDER_LENGTH, spn_FC_INBAND_INTLKN_CALENDER_REP_COUNT
+# spn_FC_INBAND_INTLKN_CALENDER_LLFC_MODE, spn_FC_INBAND_INTLKN_LLFC_MUB_ENABLE_MASK
+
+### Meter engine configuration ###
+
+# Specify meter operation mode
+# 32 - Two meters per packet (32k total)
+# 64 - One meter per packet (64k total) or two meter per packet in dual core device configured as SINGLE_CORE (128K total)
+# 128 - One meter per packet in dual core device configured as SINGLE_CORE (128K total)
+# Options: 0, 32, 64, 128
+policer_ingress_count.BCM88650=32
+policer_ingress_count.BCM88470=32
+policer_ingress_count.BCM88270=32
+policer_ingress_count.BCM88680=32
+
+
+# For meters in double 32k/64K mode, determine the sharing mode
+# Options:
+# 0 - NONE - For 64k or 128K (one meter per packet)
+# 1 - SERIAL - 32k mode only (two meters per packet)
+# 2 - PARALLEL - For 32k or 64k (two meter per packet)
+policer_ingress_sharing_mode.BCM88650=1
+policer_ingress_sharing_mode.BCM88470=1
+policer_ingress_sharing_mode.BCM88270=1
+policer_ingress_sharing_mode.BCM88680=1
+
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine the mapping
+# Options: BEST, WORST
+# policer_result_parallel_color_map.BCM88650=WORST
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine how the buckets are changed
+# Options: CONSTANT, TRANSPARENT, DEFERRED
+# policer_result_parallel_bucket_update.BCM88650=CONSTANT
+
+# Applies only to Arad+ (88660)
+# Set the Ethernet policer to work in color blind mode
+# rate_color_blind.BCM88650=1
+
+# L2 learn limit mode
+# Options: VLAN, VLAN_PORT, TUNNEL or the numeric equivalent 0-2.
+# Default: VLAN
+# l2_learn_limit_mode = VLAN_PORT
+
+# Applies only to Arad+ (88660)
+# Determines the L2 learn limit ranges when l2_learn_limit_mode is set to VLAN_PORT
+# Two range bases can be selected, each of 16K size.
+# Options: 0, 16K, 32K, 48K.
+# Default: 0 & 16K
+# l2_learn_lif_range_base_0 = 0
+# l2_learn_lif_range_base_1 = 16K
+
+# SW shadow mode for exact match tables. Required for SER support and DBAL diagnostics.
+# 0 - Disabled (Default)
+# 1 - Enabled
+# 2 - Disabled for LEM, enabled for other exact match tables
+exact_match_tables_shadow_enable.BCM88650 = 1
+exact_match_tables_shadow_enable.BCM88675 = 2
+
+# determine how many cmcs connected to the CPU.
+# default value = 1
+# applies only to jericho and above.
+pci_cmcs_num.88675 = 3
+pci_cmcs_num.88470 = 3
+
+### Counter engine configuration ###
+
+# Set the Counter source
+# Options: INGRESS_FIELD / INGRESS_VOQ / INGRESS_VSQ / INGRESS_CNM /
+# INGRESS_LATENCY / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM (per queue) / EGRESS_TM_PORT (per port)
+# EGRESS_RECEIVE_VSI / EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM (per queue) / EGRESS_RECEIVE_TM_PORT (per port)
+# INGRESS_OAM / EGRESS_OAM
+# 2 Counter-Pointers can be set (with _0 and _1) for
+# INGRESS_FIELD / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT
+# Range extension can be set (with _LSB and _MSB) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT /EGRESS_RECEIVE_VSI /
+# EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM / EGRESS_RECEIVE_TM_PORT
+counter_engine_source_0.BCM88650=INGRESS_FIELD_0
+counter_engine_source_1.BCM88650=INGRESS_FIELD_1
+counter_engine_source_2.BCM88650=INGRESS_VOQ
+counter_engine_source_3.BCM88650=EGRESS_FIELD
+
+# Configure the statistic interface egress transmit PP source and the ingress received PP source
+# Options for egress: EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT (the default is TM)
+# Options for ingress: INGRESS_VSI / INGRESS_IN_LIF / INGRESS_TM (the default is TM)
+# valid just when there is no conflict with the other counter engines
+#counter_engine_source_egress_pp_stat0.BCM88650=EGRESS_TM
+#counter_engine_source_egress_pp_stat1.BCM88650=EGRESS_VSI
+#counter_engine_source_ingress_pp_stat0.BCM88650=INGRESS_IN_LIF
+#counter_engine_source_ingress_pp_stat1.BCM88650=INGRESS_TM
+
+
+# Set the Counter engine resolution
+# SIMPLE_COLOR = green, not green
+# SIMPLE_COLOR_FWD = fwd green, fwd not green (BCM88660_A0 only)
+# SIMPLE_COLOR_DROP = drop green, drop not green (BCM88660_A0 only)
+# FWD_DROP = forwarded, dropped
+# GREEN_NOT_GREEN = fwd grn, drop grn, fwd not grn, drop not grn
+# FULL_COLOR = fwd grn, drop grn, fwd not grn, drop yel, drop red
+# ALL = received
+# FWD = forwarded, DROP = droped (not supported by ARAD_A0)
+# CONFIGURABLE = defined by counter_engine_map_ SOC properties (BCM88660_A0 only)
+counter_engine_statistics_0.BCM88650=FULL_COLOR
+counter_engine_statistics_1.BCM88650=FULL_COLOR
+counter_engine_statistics_2.BCM88650=FULL_COLOR
+counter_engine_statistics_3.BCM88650=FULL_COLOR
+
+# Set the Counter format
+# Options: PACKETS_AND_BYTES / PACKETS / BYTES
+# / MAX_QUEUE_SIZE / LATENCY / PACKETS_AND_PACKETS(supported just in FWD_DROP statistic in BCM88660_A0)
+# If not PACKETS_AND_BYTES or PACKETS_AND_PACKETS, the HW Counter width is 59 bits, thus
+# no background SW operation is performed
+counter_engine_format_0.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_1.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_2.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_3.BCM88650=PACKETS_AND_BYTES
+
+# #enable/disable counter processor background thread (default:1-enable)
+# counter_engine_sampling_interval=1
+
+
+### Configurable mode configuration (BCM88660_A0 only)###
+# counter_engine_statistics_0.BCM88660_A0=CONFIGURABLE
+# counter_engine_map_enable_0.BCM88660_A0=1
+# counter_engine_map_size_0.BCM88660_A0=4
+# counter_engine_map_fwd_green_offset_0.BCM88660_A0=0
+# counter_engine_map_fwd_yellow_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_red_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_black_offset_0.BCM88660_A0=2
+# counter_engine_map_drop_green_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_yellow_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_red_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_black_offset_0.BCM88660_A0=3
+
+### Statistic-Report configuration ###
+# Enable the Statistic-Interface configuration
+# stat_if_enable_<port> - not supported by ARAD_A0
+# stat_if_enable.BCM88650=1
+
+# ## Statistic-Report Properties
+# # Set Statistic-Report interface rate in Mbps
+# # If Value is '0' the statistics port rate will be used. Default: 0.
+# stat_if_rate.BCM88650=0
+# # Set the Statistic-Report mode
+# # Options: BILLING / BILLING_QUEUE_NUMBER (not supported by ARAD_A0)/ QSIZE
+# stat_if_report_mode.BCM88650=QSIZE
+# #Indicate if idle reports must be sent
+# #when the Statistic-report rate is too low
+# stat_if_idle_reports_present.BCM88650=0
+# # Indicate if the reported packet size is the original packet size
+# stat_if_report_original_pkt_size.BCM88650=1
+# #If set then a single ingress-billing report will be generated
+# #for the whole set of the multicast copies
+# stat_if_report_multicast_single_copy=1
+# ## Statistic Packet configurations
+# # Set the Statistic Packet size (Bytes)
+# # Valid values: 65B/126B/248B/492B (Queue-Size), 64B/128B/256B/512B/1024B (Billing).
+# stat_if_pkt_size=64B
+#
+# ## Scrubber configuration
+# # Set the range of VOQs to scrub. Range: 0 - 96K-1.
+# stat_if_scrubber_queue_min.BCM88650=0
+# stat_if_scrubber_queue_max.BCM88650=0
+#
+# # Set the scrubber rate range
+# # If set to 0 (default), the scrubber is disabled. Units: nanoseconds
+# stat_if_scrubber_rate_min.BCM88650=0
+# stat_if_scrubber_rate_max.BCM88650=0
+#
+# # Set the thresholds (thresh_id 0 - 15) defining
+# # occupancy range per resource type:
+# # DRAM Buffers, Buffer descriptors, Buffer descriptors buffers
+# stat_if_scrubber_bdb_th.BCM88650=0
+# stat_if_scrubber_buffer_descr_th.BCM88650=0
+# stat_if_uc_dram_buffer_descr_th.BCM88650=0
+#
+# #Relective report for queue size mode - not supported by ARAD_A0
+# #Reports will be created for queue num range (stat_if_selective_report_queue_min -stat_if_selective_report_queue_max)
+# #Default - all range
+# stat_if_selective_report_queue_min.BCM88650_B0=0
+# stat_if_selective_report_queue_max.BCM88650_B0=98303
+
+### Transaction - DMA configuration ###
+# Time to wait for SCHAN channel response (from CMIC). Units: microseconds.
+
+
+### Counter threads ###
+# # set port bitmap on which statistics collection will be enabled (default all ports)
+# bcm_stat_pbmp.BCM88675=0xfffffffff000000000000000000000000000000000000000000000000000000000003e002
+#
+# # set statistics collection interval in microseconds (default is 1000000)
+# bcm_stat_interval.BCM88675=1000000
+
+### Control optimization of cosq port initializations: speed for memory ###
+runtime_performance_optimize_enable_sched_allocation.BCM88650=1
+runtime_performance_optimize_enable_sched_allocation.BCM88675=1
+
+### static tables initiation (Supported for Jericho) ###
+# Options: 1 - initiating static tables, 0 - doesn't initiate tables (Default Value for PCID/emulation)
+#custom_feature_static_tbl_full_init.BCM88675=1
+#custom_feature_dynamic_tbl_full_init.BCM88675=1
+
+### Interrupts ###
+## Set interrupts global parameters.
+# Options: 1 - Polling interrupt mode, 0 - Line/MSI interrupt mode. Default: 1.
+polled_irq_mode.BCM88650=0
+polled_irq_mode.BCM88675=0
+# Set the delay in microsecond between the polling, relevant only to Polling mode. Default: 0x0.
+polled_irq_delay.BCM88650=50000
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling, relevant only to Polling completion mode.
+# SCHAN:
+#schan_intr_enable.0=1
+schan_timeout_usec.BCM88650=300000
+# TDMA
+tdma_intr_enable.BCM88650=1
+tdma_intr_enable.BCM88675=0
+tdma_timeout_usec.BCM88650=5000000
+tdma_timeout_usec.BCM88675=560000000
+# TSLAM
+tslam_intr_enable.BCM88650=1
+tslam_intr_enable.BCM88675=0
+tslam_timeout_usec.BCM88650=5000000
+tslam_timeout_usec.BCM88675=560000000
+# MIIM
+#miim_intr_enable.0=1
+miim_timeout_usec.0=300000
+
+### DRAM configuration ###
+
+# DRAM buffer (Dbuff) size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88650=1024
+ext_ram_dbuff_size.BCM88470=4096
+ext_ram_dbuff_size.BCM88270=4096
+
+# Number of external DRAMs.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# Allowed values for 88660: 0/1/2/3/4/6/8. A value of 1 is permitted only in ONE WAY BYPASS ocb mode.
+# Allowed values for 88675: 0/2/3/41/42/6/8. '41' - configure 4 drams in Single Side mode (A, B, C, D).
+# '42' - configure 4 drams in symmetric mode (A, C, F, H).
+# Value of 0 disables the DRAM.
+ext_ram_present.BCM88650=8
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+ext_ram_present.BCM88470=3
+ext_ram_present.BCM88270=1
+
+### Dram Tuning (Shmoo)
+# 3 = Skip Dram Tuning (Shmoo).
+# 2 = Use Dram saved config Parameters, if no Parameters Perform Shmoo on init. Default option.
+# 1 = Perform Shmoo on init.
+# 0 = Use Dram saved config Parameters, if no Parameters do nothing.
+ddr3_auto_tune.BCM88650=2
+ddr3_auto_tune.BCM88270=2
+ddr3_auto_tune.BCM88470=2
+
+##### DDR Tuning parameters for IL SVK4
+combo28_tune_dq_wr_min_vdl_byte3_ci1.0=0x00000004,0x00000003,0x00000007,0x00000003,0x00000002,0x00000000,0x00000006,0x00000004,
+combo28_tune_dq_rd_min_vdl_byte1_ci2.0=0x00000017,0x00000014,0x00000016,0x00000014,0x00000017,0x00000018,0x00000017,0x00000017,
+combo28_tune_common_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci1.0=0x00000003,
+combo28_tune_control_regs_read_clock_config_ci0.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci0.0=0x00000018,0x00000017,0x00000017,0x00000018,0x00000017,0x00000014,0x00000015,0x00000017,
+combo28_tune_dq_read_max_vdl_fsm_ci1.0=0x0000004c,0x0000004c,0x0000004c,0x0000004c,
+combo28_tune_aq_u_max_vdl_ctrl_ci1.0=0x00000214,
+combo28_tune_dq_rd_max_vdl_dqsn_ci1.0=0x00000017,0x00000019,0x0000002d,0x0000002d,
+combo28_tune_dq_ren_fifo_config_ci0.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_wr_min_vdl_dbi_ci1.0=0x00000001,0x00000004,0x00000002,0x00000003,
+combo28_tune_aq_u_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_dq_rd_min_vdl_edc_ci1.0=0x00000016,0x00000016,0x00000017,0x0000001a,
+combo28_tune_aq_l_max_vdl_addr_ci1.0=0x00000214,
+combo28_tune_dq_wr_max_vdl_data_ci2.0=0x00000238,0x00000406,0x00000247,0x00000416,
+combo28_tune_dq_wr_min_vdl_byte3_ci2.0=0x00000000,0x00000003,0x00000000,0x00000000,0x00000000,0x00000003,0x00000001,0x00000001,
+combo28_tune_common_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci2.0=0x00000003,
+combo28_tune_control_regs_read_clock_config_ci1.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci1.0=0x00000015,0x00000015,0x00000019,0x00000017,0x00000014,0x00000016,0x00000018,0x00000016,
+combo28_tune_dq_read_max_vdl_fsm_ci2.0=0x0000004d,0x0000004d,0x0000004d,0x0000004d,
+combo28_tune_aq_u_max_vdl_ctrl_ci2.0=0x00000048,
+combo28_tune_dq_rd_max_vdl_dqsn_ci2.0=0x00000023,0x00000022,0x0000002c,0x00000020,
+combo28_tune_dq_ren_fifo_config_ci1.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_wr_min_vdl_dbi_ci2.0=0x00000002,0x00000001,0x00000003,0x00000001,
+combo28_tune_aq_u_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_dq_rd_min_vdl_edc_ci2.0=0x00000016,0x00000017,0x00000016,0x00000017,
+combo28_tune_aq_l_max_vdl_addr_ci2.0=0x00000048,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci0.0=0x0000000f,
+combo28_tune_common_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_read_clock_config_ci2.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci2.0=0x00000018,0x00000016,0x00000015,0x00000014,0x00000015,0x00000015,0x00000014,0x00000015,
+combo28_tune_dq_wr_min_vdl_byte0_ci0.0=0x00000001,0x00000002,0x00000000,0x00000002,0x00000002,0x00000003,0x00000004,0x00000001,
+combo28_tune_dq_ren_fifo_config_ci2.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_rd_min_vdl_byte3_ci0.0=0x00000019,0x00000017,0x0000001a,0x0000001c,0x00000017,0x00000018,0x00000014,0x00000014,
+combo28_tune_aq_u_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci1.0=0x0000000f,
+combo28_tune_aq_l_max_vdl_ctrl_ci0.0=0x00000201,
+combo28_tune_control_regs_input_shift_ctrl_ci0.0=0x00000070,
+combo28_tune_dq_wr_min_vdl_byte0_ci1.0=0x00000005,0x00000001,0x00000000,0x00000000,0x00000001,0x00000000,0x00000000,0x00000003,
+combo28_tune_dq_rd_min_vdl_byte3_ci1.0=0x00000018,0x00000017,0x0000001c,0x0000001d,0x00000014,0x00000017,0x0000001e,0x0000001d,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci2.0=0x0000000f,
+combo28_tune_dq_rd_max_vdl_dqsp_ci0.0=0x00000018,0x00000019,0x00000025,0x0000002b,
+combo28_tune_aq_l_max_vdl_ctrl_ci1.0=0x00000214,
+combo28_tune_control_regs_input_shift_ctrl_ci1.0=0x00000070,
+combo28_tune_dq_wr_min_vdl_byte0_ci2.0=0x00000000,0x00000005,0x00000003,0x00000003,0x00000003,0x00000003,0x00000003,0x00000002,
+combo28_tune_dq_wr_min_vdl_edc_ci0.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_rd_min_vdl_byte3_ci2.0=0x00000015,0x00000017,0x00000014,0x00000015,0x00000016,0x00000018,0x00000018,0x00000019,
+combo28_tune_dq_wr_min_vdl_byte1_ci0.0=0x00000002,0x00000002,0x00000002,0x00000003,0x00000002,0x00000001,0x00000002,0x00000000,
+combo28_tune_control_regs_edcen_fifo_central_init_ci0.0=0x00000000,
+combo28_tune_dq_macro_reserved_reg_ci0.0=0x00000026,0x00000026,0x00000025,0x00000026,
+combo28_tune_dq_rd_max_vdl_dqsp_ci1.0=0x00000017,0x00000019,0x0000002d,0x0000002d,
+combo28_tune_aq_l_max_vdl_ctrl_ci2.0=0x00000048,
+combo28_tune_control_regs_input_shift_ctrl_ci2.0=0x00000070,
+combo28_tune_dq_rd_min_vdl_dbi_ci0.0=0x00000016,0x00000017,0x00000017,0x00000018,
+combo28_tune_dq_wr_min_vdl_edc_ci1.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_wr_min_vdl_byte1_ci1.0=0x00000006,0x00000007,0x00000005,0x00000005,0x00000000,0x00000001,0x00000007,0x00000005,
+combo28_tune_dq_edcen_fifo_config_ci0.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_control_regs_edcen_fifo_central_init_ci1.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci0.0=0x00760000,0x00740000,0x00800000,0x007c0000,
+combo28_tune_dq_macro_reserved_reg_ci1.0=0x00000026,0x0000002a,0x00000028,0x00000029,
+combo28_tune_dq_rd_max_vdl_dqsp_ci2.0=0x00000023,0x00000022,0x0000002c,0x00000020,
+combo28_tune_dq_rd_min_vdl_byte0_ci0.0=0x00000016,0x00000014,0x00000014,0x00000016,0x00000015,0x00000015,0x00000016,0x00000016,
+combo28_tune_dq_rd_min_vdl_dbi_ci1.0=0x00000016,0x00000016,0x00000017,0x0000001a,
+combo28_tune_aq_u_max_vdl_addr_ci0.0=0x00000201,
+combo28_tune_dq_wr_max_vdl_dqs_ci0.0=0x00000440,0x0000044a,0x00000422,0x00000430,
+combo28_tune_dq_wr_min_vdl_edc_ci2.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_wr_min_vdl_byte1_ci2.0=0x00000003,0x00000000,0x00000002,0x00000001,0x00000002,0x00000001,0x00000004,0x00000001,
+combo28_tune_dq_edcen_fifo_config_ci1.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_control_regs_edcen_fifo_central_init_ci2.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci1.0=0x007e0000,0x007a0000,0x00820000,0x00820000,
+combo28_tune_dq_macro_reserved_reg_ci2.0=0x00000028,0x00000028,0x0000002a,0x0000002b,
+combo28_tune_dq_wr_min_vdl_byte2_ci0.0=0x00000001,0x00000000,0x00000003,0x00000002,0x00000005,0x00000005,0x00000003,0x00000005,
+combo28_tune_dq_rd_min_vdl_byte0_ci1.0=0x00000015,0x00000017,0x00000017,0x00000017,0x00000017,0x00000015,0x00000014,0x00000015,
+combo28_tune_dq_rd_min_vdl_dbi_ci2.0=0x00000016,0x00000017,0x00000016,0x00000017,
+combo28_tune_control_regs_shared_vref_dac_config_ci0.0=0x00920000,
+combo28_tune_aq_u_max_vdl_addr_ci1.0=0x00000214,
+combo28_tune_dq_wr_max_vdl_dqs_ci1.0=0x00000440,0x00000446,0x0000042d,0x00000434,
+combo28_tune_dq_edcen_fifo_config_ci2.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_aq_l_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci2.0=0x00840000,0x007e0000,0x008a0000,0x00820000,
+combo28_tune_dq_wr_min_vdl_byte2_ci1.0=0x00000000,0x00000001,0x00000002,0x00000004,0x00000003,0x00000000,0x00000004,0x00000007,
+combo28_tune_dq_rd_min_vdl_byte0_ci2.0=0x00000014,0x00000015,0x00000015,0x00000014,0x00000016,0x00000017,0x00000015,0x00000016,
+combo28_tune_control_regs_shared_vref_dac_config_ci1.0=0x00920000,
+combo28_tune_aq_u_max_vdl_addr_ci2.0=0x00000048,
+combo28_tune_dq_wr_max_vdl_dqs_ci2.0=0x00000424,0x00000435,0x0000043c,0x00000444,
+combo28_tune_dq_rd_min_vdl_byte1_ci0.0=0x00000017,0x00000017,0x00000018,0x00000018,0x00000014,0x00000015,0x00000015,0x00000015,
+combo28_tune_aq_l_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_dq_wr_min_vdl_byte2_ci2.0=0x00000004,0x00000000,0x00000004,0x00000005,0x00000002,0x00000003,0x00000004,0x00000004,
+combo28_tune_dq_wr_max_vdl_data_ci0.0=0x00000416,0x00000428,0x00000232,0x00000241,
+combo28_tune_control_regs_shared_vref_dac_config_ci2.0=0x00920000,
+combo28_tune_dq_wr_min_vdl_byte3_ci0.0=0x00000005,0x00000005,0x00000005,0x00000004,0x00000003,0x00000003,0x00000003,0x00000000,
+combo28_tune_dq_rd_min_vdl_byte1_ci1.0=0x00000018,0x00000018,0x00000018,0x00000014,0x00000014,0x00000014,0x00000018,0x00000014,
+combo28_tune_aq_l_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci0.0=0x00000003,
+combo28_tune_dq_read_max_vdl_fsm_ci0.0=0x0000004b,0x0000004b,0x0000004b,0x0000004b,
+combo28_tune_aq_u_max_vdl_ctrl_ci0.0=0x00000201,
+combo28_tune_dq_rd_max_vdl_dqsn_ci0.0=0x00000018,0x00000019,0x00000025,0x0000002b,
+combo28_tune_dq_wr_min_vdl_dbi_ci0.0=0x00000001,0x00000001,0x00000003,0x00000003,
+combo28_tune_dq_rd_min_vdl_edc_ci0.0=0x00000016,0x00000017,0x00000017,0x00000018,
+combo28_tune_aq_l_max_vdl_addr_ci0.0=0x00000201,
+combo28_tune_dq_wr_max_vdl_data_ci1.0=0x00000414,0x0000041e,0x00000234,0x00000245,
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Defult: 1.
+# bist_enable_dram.BCM88650=1
+bist_enable_dram.BCM88270=1
+bist_enable_dram.BCM88470=1
+
+### Example for Dram Saved config Parameters.
+## This example is for ci=14 (Dram=7).
+#ddr3_tune_addrc_ci14=0x000000ae
+#ddr3_tune_wr_dq_wl1_ci14=0x92929292,0x92929292,0x92929292,0x92929292
+#ddr3_tune_wr_dq_wl0_ci14=0x93939393,0x93939393,0x92929292,0x92929292
+#ddr3_tune_wr_dq_ci14=0x80808080
+#ddr3_tune_vref_ci14=0x000007df
+#ddr3_tune_rd_dqs_ci14=0x96969191,0x90909191
+#ddr3_tune_rd_dq_wl1_rn_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rn_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_dq_wl1_rp_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rp_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_en_ci14=0x009d9e9d,0x00a2a3a1
+#ddr3_tune_rd_data_dly_ci14=0x00000505
+
+
+### Dram type: Select ONLY ONE of the following DRAM types, to configure all dram related parameteres per type.
+
+# Dram Type for Arad:
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800=1
+#dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_933=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_800=1
+#dram_type_DDR3_MICRON_MT42J64M16LA_15E_667=1
+#dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_933=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_800=1
+
+# Dram Type for Jericho:
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT=1
+dram_type_DDR4_MICRON_MT40A256M16HA_083EA_4GBIT=1
+#dram_type_DDR4_HYNIX_H5AN4G6NMFR_VJC_4GBIT=1
+#dram_type_GDDR5_SAMSUNG_K4G20325FD_2GBIT=1
+#dram_type_GDDR5_SAMSUNG_K4G41325FC_4GBIT=1
+#dram_type_GDDR5_MICRON_EDW4032CABG_4GBIT=1
+#dram_type_GDDR5_HYNIX_H5GC4H24MFR_T2C_4GBIT=1
+
+# Dram Type for Ardon:
+#dram_type_DDR4_MICRON_EDY4016AABG_DRFR_4GBIT=1
+
+# DRAM frequency
+ext_ram_freq.BCM88675=1600
+
+### Setting dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 Parameters as Default:
+## All other dram types parameter resides in arad.soc. choosing another Dram Type will override the following parameters.
+ext_ram_t_rrd=6000
+ext_ram_columns=1024
+ext_ram_banks=8
+ext_ram_ap_bit_pos=10
+ext_ram_burst_size=32
+ext_ram_t_ref=3900000
+ext_ram_t_wr=15000
+ext_ram_t_wtr=7500
+ext_ram_t_rtp=7500
+ext_ram_freq=1066
+ext_ram_rows=16384
+ext_ram_jedec=29
+ext_ram_t_rc=46090
+ext_ram_t_rcd_rd=13090
+ext_ram_t_rcd_wr=13090
+ext_ram_t_rp=13090
+ext_ram_t_rfc=160000
+ext_ram_t_ras=33000
+ext_ram_c_wr_latency=10
+ext_ram_t_faw=35000
+ext_ram_c_cas_latency=14
+ddr3_mem_grade=0x141414
+
+## address or bank address swap example
+#swaps are found in bcm88xxx_board.soc
+#ext_ram_addr_bank_swap_dramX_bitY=M
+
+## dq swap example
+#swaps are found in bcm88xxx_board.soc
+#bit swap example:
+#ext_ram_dq_swap_dramX_byteY_bitZ=M
+#byte swap example:
+#ext_ram_dq_swap_dramX_byteY=M
+
+## Dram Gear down mode. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_gear_down_mode.BCM88675=0
+
+## Alert_n de-assertion period above which error is considered parity error
+#ext_ram_alert_n_period_thrs.BCM88675=20
+
+## Dram Address bus inversion. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_abi.BCM88675=0
+
+## Data bus inversion on write/read direction. Valid values: 0 - Disable, 1 - Enable. Default: 0x0.
+## those socs are configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_write_dbi.BCM88675=0
+#ext_ram_read_dbi.BCM88675=0
+
+## Enable write/read CRC (DDR4 does not support read CRC). Default: 0x0.
+## those socs are configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_write_crc.BCM88675=1
+#ext_ram_read_crc.BCM88675=0
+
+## Command parity latency. Valid values: 0 - Disable, 4,5 or 6 - Valid values. Default: 0x0.
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_cmd_par_latency.BCM88675=6
+
+# DRAM pre-configurations according to config variables which defines
+# Dram Type. BCM88650 supports only DDR3.
+# Dram Type. BCM88675 supports DDR4 and GDDR5.
+ext_ram_type.BCM88650=DDR3
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_type.BCM88675=DDR4
+
+# Total Dram Size (MBytes)
+# For 8 drams interfaces, 2 channel each, Each channel 2Gbit Dram. the total DRAM size is 32GBits=4000MBytes.
+ext_ram_total_size.BCM88650=4000
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_total_size.BCM88675=8000
+
+# Total buffer size allocated for User buffer. Units: Mbytes. Default: '0x0'.
+# Supported suffix:
+# dram - the buffer size will be subtracted from the DRAM size available for packet memory.
+#user_buffer_size=0
+#user_buffer_size_dram=50
+
+# DRAM ClamShell (interface swap its HW PIN pairs during init.)
+# Note: Only one of DRAMs can have its PIN swapped
+# Valid values: 0/1
+#dram0_clamshell_enable.BCM88650=1
+#dram1_clamshell_enable.BCM88650=1
+
+# DRAM maximum number of crc error per buffer, buffer deleted by interrupt application.
+#dram_crc_del_buffer_max_reclaims=0
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+## If set, always configures synthesizers, even if the configured rate is equal to
+## their nominal rate. Can be disabled to speedup bringup time (keep in mind that if
+## disabled, changing a synt to a non-nominal freq and than back to nominal will not
+## work
+#synt_over.BCM88650=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88650=100000000
+synt_ddr.BCM88650=125000000
+synt_phy.BCM88650=156250000
+# in Jericho, this freq is used only for the core synth
+synth_dram_freq.BCM88650=25
+
+#Configure the reference clock frequencies for NIF and Fabric SerDes
+# Options: 0 - 125MHz, 1 - 156.25MHz, -1 - Disable
+serdes_nif_clk_freq.BCM88650=1
+serdes_fabric_clk_freq.BCM88650=1
+#serdes_nif_clk_freq.BCM88270=-1
+#serdes_fabric_clk_freq.BCM88270=-1
+serdes_nif_clk_freq.BCM8206=-1
+serdes_fabric_clk_freq.BCM8206=-1
+#serdes_nif_clk_freq_out0.BCM88675=1
+#serdes_nif_clk_freq_out1.BCM88675=1
+#serdes_nif_clk_freq_out2.BCM88675=1
+#serdes_nif_clk_freq_in0.BCM88675=1
+#serdes_nif_clk_freq_in1.BCM88675=1
+#serdes_nif_clk_freq_in2.BCM88675=1
+#serdes_fabric_clk_freq_out0.BCM88675=1
+#serdes_fabric_clk_freq_out1.BCM88675=1
+#serdes_fabric_clk_freq_in0.BCM88675=1
+#serdes_fabric_clk_freq_in1.BCM88675=1
+
+
+# IEEE 1588 / Broadsync -
+# configure clock :
+# DPLL mode/lock: 0 - eci ts pll clk disabled, 1 - configure eci ts pll clk
+# DPLL phase/freq. Default initial: lo = 0x40000000, hi = 0x10000000.
+#phy_1588_dpll_frequency_lock.BCM88650=1
+#phy_1588_dpll_phase_initial_lo.BCM88650=0x40000000
+#phy_1588_dpll_phase_initial_hi.BCM88650=0x10000000
+# IEEE 1588 -
+# port external MAC
+# indication whether external MAC exists or not.
+# 0: 1588 external MAC does not exist
+# 1: 1588 external MAC exists
+# the external MAC substracts the RX time from the correction field
+# and adds the TX time to the correction field.
+#ext_1588_mac_enable_14.BCM88650=1
+# If set, 48 bits stamping is used for 1588 packets. otherwise 32 bit stamping is used
+# 0: 1588 32b stamping (Default)
+# 1: 1588 48b stamping
+#bcm88660_1588_48b_stamping_enable.BCM88660=1
+
+## Trill configurations
+# Trill mode: 0 (disabled) / 1 (coarse-grained) / 2 (fine-grained)
+#trill_mode.BCM88650=1
+
+# Trill multicast prunning mode:
+# 0: no prunning - vsi is not part of the key
+# 1: VSI prunning: Key is dist-tree,esadit-bit,VSI.
+trill_mc_prune_mode.BCM88650=0
+
+# Enable SA authentication
+#sa_auth_enabled=1
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88650=0
+logical_port_drop.BCM88650=1
+
+#logical_port_mim_in.BCM88650=2
+#logical_port_mim_out.BCM88650=4096
+
+# Enable EVB application
+#evb_enable=1
+
+# Enable Flexible QinQ application
+#vlan_translation_match_ipv4=1
+
+# Enable presel mgmt advance mode
+#field_presel_mgmt_advanced_mode=1
+
+# Enable ITMH programmable mode
+# ITMH processing fully programmable (not fixed) by using the FP APIs.
+# In this mode ITMH processing uses the TCAM/direct table for TM programs lookup, in same manner as Ethernet frames.
+itmh_programmable_mode_enable.BCM88675=1
+itmh_programmable_mode_enable.BCM88470=1
+itmh_programmable_mode_enable.BCM88270=1
+itmh_programmable_mode_enable.BCM88680=1
+
+
+
+# Prepend tag to be 4 bytes or 8 bytes. Default: 4B.
+# Applicable only from ARAD+
+#prepend_tag_bytes=4B
+
+# The Prepend Tag is located at (12 + 2*offset) bytes from the start of the packet.
+# Range: 0-7. Default: 0
+#prepend_tag_offset=0
+
+# Enable ARP (next hop mac extension) feature
+bcm886xx_next_hop_mac_extension_enable.BCM88650=1
+
+# Set VLAN translate mode.
+# 0: normal
+# 1: advanced mode. Enable vlan edit settings with enhanced user control
+#bcm886xx_vlan_translate_mode=0
+
+# Set MPLS termination database mode
+# Set MPLS databases location for each MPLS namespace (L1,L2,L3)
+#bcm886xx_mpls_termination_database_mode=0
+
+# Enable , Disable MPLS indexed.
+# MPLS termination with known label stack location.
+# Must be enabled in case device supports more than 2 MPLS label terminations (L1,L2,L3)
+#mpls_termination_label_index_enable=1
+
+# Enable FastReRoute labels in device.
+#fast_reroute_labels_enable=0
+
+# Enable MPLS Context specific. Upstream label assignment in device.
+#mpls_context_specific_label_enable=0
+
+# MPLS context.
+# Can be global, per port , per interface or per port,interface.
+#mpls_context=global
+
+# MPLS TP MC reserved mac address (01-00-5E-90-00-00).
+# If set device will support My-MAC termination of reserved MC Ethernet
+#mpls_tp_mymac_reserved_address=0
+
+# MPLS ELI enable disable
+mpls_entropy_label_indicator_enable=0
+
+#########################################
+##cfg for BCM88202 - Ardon
+#########################################
+
+#Core clock and system reference clock (KHz)
+core_clock_speed_khz.BCM88202=450000
+system_ref_core_clock_khz.BCM88202=1200000
+
+## Set TM as device mode
+fap_device_mode.BCM88202=TM
+
+## Set CPU ports header type
+tm_port_header_type_in_0.BCM88202=TM
+tm_port_header_type_out_0.BCM88202=TM
+tm_port_header_type_in_200.BCM88202=TM
+tm_port_header_type_out_200.BCM88202=TM
+tm_port_header_type_in_201.BCM88202=TM
+tm_port_header_type_out_201.BCM88202=TM
+tm_port_header_type_in_202.BCM88202=TM
+tm_port_header_type_out_202.BCM88202=TM
+tm_port_header_type_in_203.BCM88202=TM
+tm_port_header_type_out_203.BCM88202=TM
+
+##### Application configuration
+### Default SDK Application
+ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+ucode_port_13.BCM88202=TM_INTERNAL_PKT.1
+ucode_port_14.BCM88202=TM_INTERNAL_PKT.2
+ucode_port_15.BCM88202=TM_INTERNAL_PKT.3
+ucode_port_16.BCM88202=TM_INTERNAL_PKT.4
+ucode_port_17.BCM88202=TM_INTERNAL_PKT.5
+
+### PortOpriority (additonal ports can be added)
+#diag_cosq_disable.BCM88202=1
+#ucode_port_1.BCM88202=IGNORE
+#ucode_port_13.BCM88202=IGNORE
+#ucode_port_14.BCM88202=IGNORE
+#ucode_port_15.BCM88202=IGNORE
+#ucode_port_16.BCM88202=IGNORE
+#ucode_port_17.BCM88202=IGNORE
+#ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+#ucode_port_2.BCM88202=TM_INTERNAL_PKT.1
+#ucode_port_3.BCM88202=TM_INTERNAL_PKT.2
+#ucode_port_4.BCM88202=TM_INTERNAL_PKT.3
+#ucode_port_5.BCM88202=TM_INTERNAL_PKT.4
+#ucode_port_6.BCM88202=TM_INTERNAL_PKT.5
+#ucode_port_7.BCM88202=TM_INTERNAL_PKT.6
+#ucode_port_8.BCM88202=TM_INTERNAL_PKT.7
+#ucode_port_9.BCM88202=TM_INTERNAL_PKT.8
+#ucode_port_10.BCM88202=TM_INTERNAL_PKT.9
+#ucode_port_11.BCM88202=TM_INTERNAL_PKT.10
+#ucode_port_12.BCM88202=TM_INTERNAL_PKT.11
+#ucode_port_13.BCM88202=TM_INTERNAL_PKT.12
+#ucode_port_14.BCM88202=TM_INTERNAL_PKT.13
+#ucode_port_15.BCM88202=TM_INTERNAL_PKT.14
+#ucode_port_16.BCM88202=TM_INTERNAL_PKT.15
+#ucode_port_17.BCM88202=TM_INTERNAL_PKT.16
+#ucode_port_18.BCM88202=TM_INTERNAL_PKT.17
+#ucode_port_19.BCM88202=TM_INTERNAL_PKT.18
+#ucode_port_20.BCM88202=TM_INTERNAL_PKT.19
+#ucode_port_21.BCM88202=TM_INTERNAL_PKT.20
+#ucode_port_22.BCM88202=TM_INTERNAL_PKT.21
+#ucode_port_23.BCM88202=TM_INTERNAL_PKT.22
+#ucode_port_24.BCM88202=TM_INTERNAL_PKT.23
+#ucode_port_25.BCM88202=TM_INTERNAL_PKT.24
+
+#dtm_flow_nof_remote_cores_region_1.BCM88202=1
+#dtm_flow_nof_remote_cores_region_2.BCM88202=1
+#dtm_flow_nof_remote_cores_region_3.BCM88202=1
+#dtm_flow_nof_remote_cores_region_4.BCM88202=1
+#dtm_flow_nof_remote_cores_region_5.BCM88202=1
+#dtm_flow_nof_remote_cores_region_6.BCM88202=1
+#dtm_flow_nof_remote_cores_region_7.BCM88202=1
+#dtm_flow_nof_remote_cores_region_8.BCM88202=1
+#dtm_flow_nof_remote_cores_region_9.BCM88202=1
+#dtm_flow_nof_remote_cores_region_10.BCM88202=1
+
+### PriorityOPort
+#diag_cosq_disable.BCM88202=1
+#stack_enable.BCM88202=0
+#ucode_port_17.BCM88202=IGNORE
+#ucode_port_16.BCM88202=IGNORE
+#ucode_port_15.BCM88202=IGNORE
+#ucode_port_14.BCM88202=IGNORE
+#ucode_port_13.BCM88202=IGNORE
+#ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+
+## Credit worth resolution (Fix the Interface rate)
+credit_worth_resolution.BCM88202=medium
+
+### Interrupts
+polled_irq_mode.BCM88202=1
+
+## To use MC-ID in the range of < 255
+egress_multicast_direct_bitmap_max.BCM88202=255
+
+### Flow Control
+## Enable Flow Control to CL SCH. Relevant only to Priority Over Port application
+## Valid values: 1 - Enable, 0 - Disable. Default: 0x0.
+custom_feature_cl_scheduler_fc.BCM88202=1
+
+## Valid values: 1 - Enable, 0 - Disable. Default: 0x0.
+#custom_feature_high_vsi_fp.BCM88660=0
+
+## Use lower CL. Ardon FC is mapped to CL 0-255.
+dtm_flow_mapping_mode_region_65.BCM88202=1
+dtm_flow_mapping_mode_region_66.BCM88202=1
+
+### Statistic-Report Properties
+stat_if_enable.BCM88202=1
+stat_if_rate.BCM88202=10000
+stat_if_pkt_size.BCM88202=126B
+## Set the Statistic-Report mode
+stat_if_report_mode.BCM88202=QSIZE
+## Enable statistics reports on EnQueue. Valid valued: 0/1. Default: '1'.
+stat_if_report_enqueue_enable.BCM88202=1
+## Enable statistics reports on DeQueue. Valid valued: 0/1. Default: '1'.
+stat_if_report_dequeue_enable.BCM88202=1
+
+## Disable removed features
+phy_1588_dpll_frequency_lock.BCM88202=0
+low_power_nif_mac.BCM88202=0
+low_power_fabric_mac.BCM88202=0
+custom_feature_nif_recovery_enable.BCM88202=0
+phy_null.BCM88202=0
+
+## Disable counter thread
+bcm_stat_interval.BCM88202=0
+#bcm_stat_sync_timeout.BCM88202=0xfffffff
+
+### EMUL changes
+#diag_emulator_partial_init.BCM88202=1
+#schan_timeout_usec.BCM88202=0x7fffffff
+#tdma_timeout_usec.BCM88202=0x7fffffff
+#tslam_timeout_usec.BCM88202=0x7fffffff
+#phy_null.BCM88202=0
+
+### Disable DMA
+#tdma_timeout_usec.BCM88202=0
+#tslam_timeout_usec.BCM88202=0
+#table_dma_enable.BCM88202=0
+#tslam_dma_enable.BCM88202=0
+
+### Dram setup
+# Number of external DRAMs.
+# Allowed values for 88202: 0 / 1 (Dram D) / 2 (Dram's C, D) / 3 (Dram's B, C, D) / 4 (Dram's A, B, C, D) /
+ext_ram_present.BCM88202=0
+
+### Total size of ram
+ext_ram_total_size.BCM88202=2000
+
+### OCB
+bcm886xx_ocb_databuffer_size.BCM88202=1024
+
+# DRAM frequency (DQ/2)
+ext_ram_freq.BCM88202=1200
+
+# Dram Type. Ardon supports only DDR4.
+ext_ram_type.BCM88202=DDR4
+
+### Dram Features
+
+## Dram Gear down mode. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+#ext_ram_gear_down_mode.BCM88202=1
+
+## Alert_n de-assertion period above which error is considered parity error
+#ext_ram_alert_n_period_thrs.BCM88202=0
+
+## Dram Address bus inversion. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_abi.BCM88202=0
+
+## Data bus inversion on write/read direction. Valid values: 0 - Disable, 1 - Enable. Default: 0x0.
+ext_ram_write_dbi.BCM88202=0
+ext_ram_read_dbi.BCM88202=0
+
+## Enable write/read CRC (DDR4 does not support read CRC). Default: 0x0.
+#ext_ram_write_crc=.BCM882021
+#ext_ram_read_crc=.BCM882021
+
+## Command parity latency. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_cmd_par_latency.BCM88202=6
+
+## DRAM ClamShell (interface swap its HW PIN pairs during init.)
+# Note: Only one of DRAMs can have its PIN swapped). Valid values: 0/1.
+dram1_clamshell_enable_0.BCM88202=1
+dram1_clamshell_enable_1.BCM88202=1
+dram1_clamshell_enable_2.BCM88202=1
+dram1_clamshell_enable_3.BCM88202=1
+
+## Dram DQ Swap.
+## Format: ext_ram_dq_swap_dramX_byteY_bitZ=M. Means, In dram X, Byte Y swap DQ Z and M. Default: No swapping.
+#ext_ram_dq_swap_dram1_byte2_bit3.BCM88202=4
+#ext_ram_dq_swap_dram4_byte3_bit2.BCM88202=1
+
+### Dram Tuning (Shmoo)
+ddr3_auto_tune.BCM88202=2
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Default: 1.
+bist_enable_dram.BCM88202=1
+
+### Fabric
+## Enable fabric links
+serdes_qrtt_active_0.BCM88202=1
+serdes_qrtt_active_1.BCM88202=1
+serdes_qrtt_active_2.BCM88202=1
+serdes_qrtt_active_3.BCM88202=1
+
+## Firmware Load Method
+load_firmware.BCM88202=2
+
+#SFI speed rate
+port_init_speed_sfi.BCM88202=11500
+
+#LC PLL in. Default: 156.25MHz.
+#xgxs_lcpll_xtal_refclk=125
+
+#########################################
+##cfg for BCM88640_A0 - Petra
+#########################################
+
+force_clk_m_n_divisors_zero_nif0.BCM88640_A0=0
+force_clk_m_n_divisors_zero_fabric0.BCM88640_A0=1
+force_clk_m_n_divisors_zero_comb0.BCM88640_A0=0
+
+combo_ref_clock.BCM88640=312500
+
+nif_ref_clock.BCM88640_A0=312500
+
+# Use variable cell size
+system_cell_format.BCM88640_A0=VCS128
+
+# Core clock speed (MHz)
+core_clock_speed.BCM88640_A0=300
+
+# Map bcm local port to CPU/NIF interfaces
+ucode_port_0.BCM88640_A0=CPU.0
+ucode_port_73.BCM88640_A0=CPU.1
+ucode_port_74.BCM88640_A0=CPU.2
+ucode_port_75.BCM88640_A0=CPU.3
+ucode_port_76.BCM88640_A0=CPU.4
+ucode_port_77.BCM88640_A0=CPU.5
+ucode_port_78.BCM88640_A0=CPU.6
+
+# Interlaken ports basic configuration (temporary).
+# This configuration replaces the above XAUI/RXAUI ports config
+# The following PB design constraint is not enforced in SW, so must be taken
+# care of here, when mapping ports to interfaces:
+# If using ilkn0, port 1 (if used) must be mapped to ilkn0
+# If using ilkn1, port 2 (if used) must be mapped to ilkn1
+# Note that in our default mapping, port 2 is mapped to RXAUI 6, thus won't
+# work. If one wants to use front panel port 2 with ilkn1, he should be map
+# RAXUI6 to a port != 2.
+#ilkn_num_lanes_0.BCM88640_A0=12
+#ucode_port_1.BCM88640_A0=ILKN0.0
+#ucode_port_2.BCM88640_A0=ILKN0.1
+#ucode_port_3.BCM88640_A0=ILKN0.2
+#ilkn_num_lanes_1.BCM88640_A0=12
+#ucode_port_4.BCM88640_A0=RXAUI6
+#ucode_port_5.BCM88640_A0=ILKN1.0
+#ucode_port_6.BCM88640_A0=ILKN1.1
+#ucode_port_7.BCM88640_A0=ILKN1.2
+
+# Default header type is derived from fap_device_mode: If fap_device_mode is
+# PP, default header type is ETH. Otherwise, defualt header type is TM.
+# Header type per port can be overriden.
+# All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/INJECTED
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88640_A0=TM
+tm_port_header_type_in_0.BCM88640_A0=TM
+tm_port_header_type_out_0.BCM88640_A0=CPU
+tm_port_header_type_73.BCM88640_A0=TM
+tm_port_header_type_74.BCM88640_A0=TM
+tm_port_header_type_75.BCM88640_A0=TM
+tm_port_header_type_76.BCM88640_A0=TM
+tm_port_header_type_77.BCM88640_A0=TM
+tm_port_header_type_78.BCM88640_A0=TM
+# recycling port
+tm_port_header_type_40.BCM88640_A0=RAW
+ucode_port_40.BCM88640_A0=RCY.0
+
+# Enable ERP and OLP ports
+num_erp_tm_ports.BCM88640_A0=1
+num_olp_tm_ports.BCM88640_A0=1
+num_recycle_tm_ports.BCM88640_A0=1
+
+# Dram configuration
+# 600 Mhz
+ext_ram_pll_r.BCM88640_A0=4
+ext_ram_pll_f.BCM88640_A0=47
+ext_ram_pll_q.BCM88640_A0=1
+ext_ram_freq.BCM88640_A0=600
+
+# Dbuff size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88640_A0=1024
+
+# Number of external DRAMs.
+# Allowed values for 88x4x: 0/2/3/4/6.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# ext_ram_total_size below assumed this value is 6 for 88x4x and 8 for
+ext_ram_present.BCM88640_A0=6
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram
+# related parameteres per type.
+# Dram Type for Pb:
+#dram_type_DDR3_MICRON_MT41J64M16_15E.BCM88640_A0=1
+#dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600.BCM88640_A0=1
+#dram_type_GDDR3_SAMSUNG_K4J52324QE.BCM88640_A0=1
+dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G.BCM88640_A0=1
+
+# QDR configuration
+# Parity. Allowed values: PARITY/ECC.
+ext_qdr_protection_type.BCM88640_A0=PARITY
+ext_qdr_size_mbit.BCM88640_A0=72
+#QDR type: QDR/QDR2P/QDR3/NONE.
+ext_qdr_type.BCM88640_A0=QDR
+
+# QDR can use the core clock, or using it's own pll. Current example is for 250MHz pll (if used).
+# QDR using own pll configuration
+#ext_qdr_use_core_clock_freq.BCM88640_A0=0
+#ext_qdr_pll_m.BCM88640_A0=4
+#ext_qdr_pll_n.BCM88640_A0=4
+#ext_qdr_pll_p.BCM88640_A0=0
+
+# QDR using core clock
+ext_qdr_use_core_clock_freq.BCM88640_A0=1
+
+#Configure MDIO. If parameter is not defined, MDIO is disabled.
+mdio_clock_freq_khz.BCM88640_A0=1000
+
+# Streaming interface configuration
+streaming_if_enable_timeoutcnt.BCM88640_A0=1
+streaming_if_timeout_prd.BCM88640_A0=70
+streaming_if_quiet_mode.BCM88640_A0=0
+streaming_if_discard_bad_parity.BCM88640_A0=0
+
+# maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88640_A0=0
+
+# multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_max.BCM88640_A0=4095
+
+# configure flow mapping base to 0
+flow_mapping_queue_base.BCM88640_A0=0
+
+dtm_flow_mapping_mode_region_25.BCM88640_A0=0
+dtm_flow_mapping_mode_region_26.BCM88640_A0=0
+dtm_flow_mapping_mode_region_27.BCM88640_A0=0
+dtm_flow_mapping_mode_region_28.BCM88640_A0=0
+dtm_flow_mapping_mode_region_29.BCM88640_A0=0
+dtm_flow_mapping_mode_region_30.BCM88640_A0=0
+dtm_flow_mapping_mode_region_31.BCM88640_A0=0
+dtm_flow_mapping_mode_region_32.BCM88640_A0=0
+dtm_flow_mapping_mode_region_33.BCM88640_A0=1
+dtm_flow_mapping_mode_region_34.BCM88640_A0=1
+dtm_flow_mapping_mode_region_35.BCM88640_A0=1
+dtm_flow_mapping_mode_region_36.BCM88640_A0=1
+dtm_flow_mapping_mode_region_37.BCM88640_A0=1
+dtm_flow_mapping_mode_region_38.BCM88640_A0=1
+dtm_flow_mapping_mode_region_39.BCM88640_A0=1
+dtm_flow_mapping_mode_region_40.BCM88640_A0=1
+dtm_flow_mapping_mode_region_41.BCM88640_A0=1
+dtm_flow_mapping_mode_region_42.BCM88640_A0=2
+dtm_flow_mapping_mode_region_43.BCM88640_A0=2
+dtm_flow_mapping_mode_region_44.BCM88640_A0=2
+dtm_flow_mapping_mode_region_45.BCM88640_A0=2
+dtm_flow_mapping_mode_region_46.BCM88640_A0=2
+dtm_flow_mapping_mode_region_47.BCM88640_A0=2
+dtm_flow_mapping_mode_region_48.BCM88640_A0=2
+dtm_flow_mapping_mode_region_49.BCM88640_A0=2
+dtm_flow_mapping_mode_region_50.BCM88640_A0=2
+dtm_flow_mapping_mode_region_51.BCM88640_A0=2
+dtm_flow_mapping_mode_region_52.BCM88640_A0=2
+dtm_flow_mapping_mode_region_53.BCM88640_A0=2
+dtm_flow_mapping_mode_region_54.BCM88640_A0=2
+dtm_flow_mapping_mode_region_55.BCM88640_A0=2
+
+# Power up state (DOWN/UP/UP_AND_RELOCK). Can be configured per lane.
+pb_serdes_lane_power_state.BCM88640_A0=UP_AND_RELOCK
+
+# SeDes media type: Pre-configuration for tx params, according to
+# media type.
+# Allowed values: SHORT_BACKPLANE/LONG_BACKPLANE/CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type.BCM88640_A0=SHORT_BACKPLANE
+pb_serdes_lane_tx_phys_media_type_28.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_29.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_30.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_31.BCM88640_A0=CHIP2CHIP
+
+system_is_fe1600_in_system.BCM88640_A0=0
+
+# Counter engine configuration
+counter_engine_source_1.BCM88640_A0=0
+counter_engine_statistics_1.BCM88640_A0=4
+counter_engine_source_2.BCM88640_A0=1
+counter_engine_statistics_2.BCM88640_A0=4
+
+# Statistic Reporting
+stat_if_enable=0
+
+# Clock Phases: 0/90/180/270
+stat_if_phase=0
+
+# Rate in nm
+stat_if_sync_rate=0
+
+# TRUE/FALSE
+stat_if_parity_enable=FALSE
+
+# BILLING/FAP20V
+stat_if_report_mode=BILLING
+
+# Billing Mode
+# EGR_Q_NB/CUD/VSI_VLAN/BOTH_LIFS
+stat_if_report_billing_mode=VSI_VLAN
+
+# Fap20V Mode
+# QUEUE/PACKET
+stat_if_report_fap20v_mode=QUEUE
+
+# QUEUE_NUM/MC_ID (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_fabric_mc=QUEUE_NUM
+stat_if_report_fap20v_ing_mc=QUEUE_NUM
+
+# TRUE/FALSE (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_cnm_report=FALSE
+
+# TRUE/FALSE
+stat_if_report_fap20v_count_snoop=FALSE
+stat_if_report_original_pkt_size=FALSE
+stat_if_report_fap20v_single_copy_reported=FALSE
+
+schan_timeout_usec.BCM88640_A0=300000
+
+
+polled_irq_mode.BCM88640_A0=0
+polled_irq_delay.BCM88640_A0=1000
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88650: ENABLED
+# Options for 88640 compatible:
+# DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88640=DISABLED
+
+#########################################
+##cfg for BCM88750 (FE1600)
+#########################################
+
+fabric_device_mode.BCM88750=SINGLE_STAGE_FE2
+
+is_dual_mode.BCM88750=0
+system_is_vcs_128_in_system.BCM88750=0
+
+system_is_dual_mode_in_system.BCM88750=0
+system_is_single_mode_in_system.BCM88750=1
+
+system_is_fe600_in_system.BCM88750=0
+
+system_ref_core_clock_khz.BCM88750=1200000
+
+fabric_merge_cells.BCM88750=0
+fabric_multicast_mode.BCM88750=DIRECT
+fabric_load_balancing_mode.BCM88750=NORMAL_LOAD_BALANCE
+fabric_tdm_fragment.BCM88750=0x180
+##Allows single pipe device to send TDM traffic over the fabric primary pipe - available for Fe1600_B0 only
+#change vcs128_unicast_priority to be lower than 2 - when enabling
+fabric_tdm_over_primary_pipe.BCM88750=0
+fabric_optimize_partial_links.BCM88750=0
+vcs128_unicast_priority.BCM88750=2
+
+polled_irq_mode.BCM88750=0
+polled_irq_delay.BCM88750=1000
+
+#Selects if to run MBIST (Memory Built In Self Test) of internal memory (tables) during startup.
+#Supported values: 0=don't run, 1=run, 2=run with extra logs
+#bist_enable.BCM88650=1
+bist_enable.BCM88750=1
+bist_enable.BCM88470=0
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88750=0
+load_firmware.BCM88750=2
+
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88750=2
+
+#enable\disable CL72
+port_init_cl72.BCM88750=1
+#Avaliable speeds for BCM88750: 5750, 6250, 10312, 11500, 12500
+port_init_speed.BCM88750=10312
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88750=1
+serdes_fabric_clk_freq_out.BCM88750=1
+serdes_mixed_rate_enable.BCM88750_B0=0
+
+# VSC128 or VSC256
+fabric_cell_format.BCM88750=VSC256
+
+# Core clock speed (MHz)
+core_clock_speed_khz.BCM88750=533333
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88750=0
+schan_timeout_usec.BCM88750=300000
+# TDMA
+tdma_intr_enable.BCM88750=0
+tdma_timeout_usec.BCM88750=5000000
+# TSLAM
+tslam_intr_enable.BCM88750=0
+tslam_timeout_usec.BCM88750=5000000
+# MIIM
+miim_intr_enable.BCM88750=0
+miim_timeout_usec.BCM88750=300000
+
+#########################################
+##cfg for BCM88950 (FE3200)
+#########################################
+#Device operation
+fabric_device_mode.BCM88950=SINGLE_STAGE_FE2
+fabric_load_balancing_mode.BCM88950=NORMAL_LOAD_BALANCE
+
+#Cell format
+system_is_vcs_128_in_system.BCM88950=0
+
+#Fabric pipe configuration
+
+fabric_num_pipes.BCM88950=1
+fabric_pipe_map.BCM88950=0
+system_contains_multiple_pipe_device.BCM88950=0
+
+#multicast table mode
+fabric_multicast_mode.BCM88950=DIRECT
+fe_mc_id_range.BCM88950=128K_HALF
+
+#Core clock and system reference clock (KHz)
+system_ref_core_clock_khz.BCM88950=1200000
+core_clock_speed_khz.BCM88950=720000
+
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88950=0
+serdes_fabric_clk_freq_out.BCM88950=1
+
+#TODO
+polled_irq_mode.BCM88950=1
+polled_irq_delay.BCM88950=1000
+
+#Memory Bist
+bist_enable.BCM88950=0
+
+#High voltage driver strap. If 0, connected to 1.25V supply;
+#if 1, connected to 1V mode (For unused Falcon Quads that are connected to 1.0V).
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88950=0
+load_firmware.BCM88950=0x102
+
+
+##Per port properties
+#Possible values - KR_FEC, 64_66, RS_FEC, LL_RS_FEC
+backplane_serdes_encoding.BCM88950=RS_FEC
+
+#enable\disable CL72
+port_init_cl72.BCM88950=1
+
+#link speed
+port_init_speed.BCM88950=25000
+
+#Link connected to a reapter
+#Values: 0/1. Default: 0
+#repeater_link_enable_<port>.BCM88950=0
+
+##Fabric cell FIFO DMA
+fabric_cell_fifo_dma_enable.BCM88950=1
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88950=0
+schan_timeout_usec.BCM88950=300000
+# TDMA
+tdma_intr_enable.BCM88950=0
+tdma_timeout_usec.BCM88950=5000000
+# TSLAM
+tslam_intr_enable.BCM88950=0
+tslam_timeout_usec.BCM88950=5000000
+# MIIM
+miim_intr_enable.BCM88950=0
+miim_timeout_usec.BCM88950=300000
+
+##############################
+# Configuration for devices run in emulation
+##############################
+#diag_emulator_partial_init.BCM88470=2
+#phy_simul.BCM88470=1
+#system_ref_core_clock_khz.BCM88470=250000
+#system_ref_core_clock_khz.BCM88470=600000
+#phy_simul.BCM88270=1
+
+polled_irq_mode.BCM88470=1
+polled_irq_mode.BCM88270=1
+
+schan_intr_enable.BCM88470=0
+schan_intr_enable.BCM88270=0
+
+# For emulation use:
+#schan_timeout_usec.BCM88470=600000000
+schan_timeout_usec.BCM88470=300000
+schan_timeout_usec.BCM88270=200000
+
+# TDMA
+tdma_intr_enable.BCM88470=0
+#tdma_intr_enable.BCM88270=0
+
+# For emulation use:
+#tdma_timeout_usec.BCM88470=600000000
+tdma_timeout_usec.BCM88470=60000000
+tdma_timeout_usec.BCM88270=500000
+
+# TSLAM
+tslam_intr_enable.BCM88470=0
+tslam_intr_enable.BCM88270=0
+
+# For emulation use:
+#tslam_timeout_usec.BCM88470=600000000
+tslam_timeout_usec.BCM88470=60000000
+tslam_timeout_usec.BCM88270=500000
+
+#otm_base_q_pair.BCM88470=2
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+# Support (and configure on init) packet processing features.
+# If not defined - only traffic management capabilities are enabled.
+packet_processing=1
+
+## PCP (Petra Co-Processor) features
+#pcp_elk.BCM88640_A0=1
+#pcp_oam.BCM88640_A0=1
+#pcp_dma.BCM88640_A0=1
+
+## Set/Override TDM related config variables
+#tdm.BCM88640_A0=1
+
+# If set, always configures synthesizers, even if the configured rate is
+# equal to
+# their nominal rate. Can be disabled to speedup bringup time
+# (keep in mind that if disabled, changing a synt to a non-nominal freq and
+# than back to nominal will not work
+#synt_over.BCM88640_A0=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88640_A0=100000000
+synt_ddr.BCM88640_A0=125000000
+synt_phy.BCM88640_A0=156250000
+
+
+############################
+### Warmboot & SW State ####
+############################
+#
+#HW journal working mode. Allowed values: 0-2.
+# 0 : Disabled
+# 1 : Commit After Each Api
+# 2 : Commit Upon User Request
+ha_hw_journal_mode=0
+
+ha_hw_journal_size=15728640
+ha_sw_journal_size=15728640
+ha_crash_recovery=1
+
+
+# stable_size - a strict bound on the application's external storage size
+stable_size.BCM88950=200000
+stable_size.BCM88750=200000
+stable_size.BCM88650=281000000
+stable_size.BCM88675=500000000
+stable_size.BCM88680=500000000
+stable_size.BCM88690=500000000
+stable_size.BCM88470=350000000
+stable_size.BCM88270=650000000
+stable_size=420000000
+
+# determine the memory size pre-allocated for the SDK's SW State
+sw_state_max_size.BCM88650=210000000
+sw_state_max_size.BCM88675=350000000
+sw_state_max_size.BCM88680=350000000
+sw_state_max_size.BCM88470=300000000
+sw_state_max_size.BCM88270=210000000
+sw_state_max_size=350000000
+
+# stable location
+## part of scache initialization for warmboot persistent storage.
+## values: 1-2:Not Valid for dnx 3: Store in a file 4: Use Shared Mem.
+# 4 is the preffered option, using 3 for Arad and FE in order to regress both modes.
+stable_location.BCM88950=3
+stable_location.BCM88750=3
+stable_location.BCM88650=3
+stable_location.BCM88660=3
+stable_location.BCM88675=3
+stable_location=3
+
+# stable_filename - the warmboot file name (if stored on a file)
+stable_filename=/tmp/warmboot_data
+
+# emulation file name
+stable_filename.BCM88470=/tmp/warmboot_data
+
+
+# create the file in memory for a faster warmboot debug
+#stable_filename=/dev/shm/warmboot_data
+
+# stable_flags - not in use
+stable_flags=0
+
+############################
+############################
+
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88640=1
+logical_port_drop.BCM88640=-1
+
+#logical_port_mim_in.BCM88640=2
+#logical_port_mim_out.BCM88640=3
+
+## IPV6 tunnel
+bcm886xx_ipv6_tunnel_enable=1
+
+## Inlif Profile Management Mode - QoS L3 L2 marking mode
+#
+# BCM88660 ONLY
+#
+# QoS L3 L2 marking allows changing the DSCP and/or EXP values
+# of IP and/or MPLS packets according to the incoming port
+# (or inlif), and the Traffic Class/Drop Precedence.
+#
+# The inlif profile is used to control the DSCP/EXP marking.
+# This SOC property controls which mode is used for the inlif profile:
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the DSCP/EXP marking).
+# 0: Advanced mode (the user controls which inlif profile values perform DSCP/EXP marking directly).
+#bcm886xx_qos_l3_l2_marking=1
+
+## Unicast RPF mode per RIF
+#
+# This SOC property allows the user to set the unicast RPF mode - loose, strict or disabled - per RIF.
+# If disabled, the unicast RPF mode of a RIF is set globally.
+# Options: 0 / 1
+
+##Jericho only, number of inrif mac termination combinations. Legal values 0 - 16, default value 16 */
+#Note: Two sets of identical mac termination combinations with different RPF modes (loose and strict)
+#will consume two termination combinations resources.
+#Two sets of identical mac termination combinations with and without loose RPF will consume only one resource.
+number_of_inrif_mac_termination_combinations=8
+
+##Jericho only, ipmc_l3mcastl2_mode SOC allows a per RIF program selection in the case of ipv4 MC with IPMC disable
+#instead of the global bcmSwitchL3McastL2 switch control selection.
+#Legal values:
+#0: bcmSwitchL3McastL2 switch control.
+#1: PER In-RIF selection.
+#Note that enabling this SOC will reduce the number of In-RIF mac termination combinations bits by one to a maximum of 3 bits
+#so it can't be enabled with number_of_inrif_mac_termination_combinations larger than 8.
+ipmc_l3mcastl2_mode = 1
+
+# The bcm_ipmc_add adds bridge or route entries according to the BCM_IPMC_L2 flag.
+# Setting custom_feature_ipmc_set_entry_type_by_rif=1 will use the related IN-RIF IPMC state (enable/disable)
+# to select the bcm_ipmc_add entry type (bridge/route).
+#custom_feature_ipmc_set_entry_type_by_rif=0
+
+# bcm886xx_l3_ingress_urpf_enable=1
+
+## BOS handling mode
+# BCM8866X ONLY
+#
+# There are two ways to handle BOS, controlled by bcm886xx_mpls_termination_mode:
+# 0 - Use BOS as key in lookup.
+# 1 - Don't use it (except for reserved labels).
+#
+#bcm886xx_mpls_termination_key_mode=0
+
+# Color resolution mode allows the user to have more detailed metering color information.
+# BCM88660 ONLY
+#
+# Options: 0-2
+# 0: A red result from both Ethernet policer and meter implies DP=3.
+# 1: A red result from meter implies that DP=2, while a red result from rate (Ethernet policer) implies DP=3.
+#policer_color_resolution_mode=1
+
+## Inlif Profile Management Mode - Disable Same Interface Filter
+# BCM8866X ONLY
+#
+# Controls which mode is used for the inlif profile management.
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the same-interface filter).
+# 0: Advanced mode (the user controls which inlif profile values have the same-interface filter disabled for them).
+#bcm886xx_logical_interface_bridge_filter_enable=1
+
+## Default Block Forwarding Strength
+#
+# Configure the default forwarding strength of blocks.
+#
+# SOC Properties:
+#block_trap_strength_vtt - VTT block forwarding strength
+#block_trap_strength_flp - FLP block forwarding strength
+#block_trap_strength_hash - SLB block forwarding strength (BCM8866X ONLY)
+#block_trap_strength_pmf_0 - PMF 1st lookup forwarding strength
+#block_trap_strength_pmf_1 - PMF 2nd lookup forwarding strength
+#
+# Options: 0-7
+
+## Stateful Load Balancing
+# BCM8866X ONLY
+#
+# Stateful Load Balancing (SLB) allows the load balancing of ECMP and LAG
+# groups to become stateful.
+# In standard load balancing, removing a member from the ECMP/LAG
+# group may affect the selected member, since the formula
+# depends on group size.
+# In stateful load balancing the member is selected once and saved.
+# Later, the member is always retrieved, and does not depend on
+# the size of the LAG/ECMP group.
+#
+# resilient_hash_enable - Enable/disable SLB. Values:
+# 1 - Enable SLB.
+# 0 - Disable SLB.
+#resilient_hash_enable=1
+
+# When this flag is set (and speculative parsing is used) it is possible for a packet of L4oIPv4/6oMPLS(1-3 labels)oETH
+# with MPLS forwarding to use the L4 header, otherwise the IPv4/6 is the last known header.
+#Note: setting this flag can cause unexpected behavior when BOS is used in the scenario above.
+#custom_feature_speculative_L4_support=0
+
+#Make Arad SOC properties work for Arad+, by mapping the BCM88660 suffix to BCM88650
+soc_family.BCM88660=BCM88650
+#Make Arad SOC properties work for Jericho, by mapping the BCM88675 suffix to BCM88650
+soc_family.BCM88675=BCM88650
+#Make Arad SOC properties work for QMX, by mapping the BCM88375 suffix to BCM88650
+soc_family.BCM88375=BCM88650
+#Make Arad SOC properties work for Ardon, by mapping the BCM88202 suffix to BCM88650
+soc_family.BCM88202=BCM88650
+#Make FE3200 SOC properties work for FE3200 SKU 8952, by mapping the BCM88952 suffix to BCM88950
+soc_family.BCM88952=BCM88950
+#Make FE1600 SOC properties work for FE1600 SKU 8753, by mapping the BCM88753 suffix to BCM88750
+soc_family.BCM88753=BCM88750
+#Make FE1600 SOC properties work for FE1600 SKU 8752, by mapping the BCM88752 suffix to BCM88750
+soc_family.BCM88752=BCM88750
+#Make Arad SOC properties work for QAX, by mapping the BCM88470 suffix to BCM88650
+soc_family.BCM88470=BCM88650
+
+#Make Arad SOC properties work for QUX, by mapping the BCM88270 suffix to BCM88650
+soc_family.BCM88270=BCM88650
+#Make Arad SOC properties work for FLAIR, by mapping the BCM8206 suffix to BCM88650
+soc_family.BCM8206=BCM88650
+#Make Arad SOC properties work for JERICHO_PLUS, by mapping the BCM88470 suffix to BCM88650
+soc_family.BCM88680=BCM88650
+
+# Use different mymac addresses for ipv4 and ipv6 when using vrrp for mymac termination.
+#l3_vrrp_ipv6_distinct=1
+
+# Enable multiple mymac termination mode.
+# In order to enable it, also set l3_vrrp_ipv6_distinct=0 and l3_vrrp_max_vid=0 since vrrp and
+# multiple mymac mode can't co exist.
+#l3_multiple_mymac_termination_enable=1
+
+# Distinguish between ipv4 and all other l3 protocols when multiple mymac terminating
+#l3_multiple_mymac_termination_mode=1
+
+# Usually the final DP given by the meter (or the In-DP) is unchanged, and can be from 0-3.
+# When this SOC property is set to 1, when the final INGRESS DP is 2,
+# it is mapped to 1 instead, and thus only the values 0-1 and 3 can be output.
+# This has no effect when policer_color_resolution_mode=1.
+#custom_feature_always_map_result_dp_2_to_1=1
+
+# Dynamic port feature
+#custom_feature_dynamic_port=1
+
+# low power nif mac
+#low_power_nif_mac=0
+
+# allow modifications during traffic
+#custom_feature_allow_modifications_during_traffic=1
+
+# mem_cache_enable property
+# Cache memory mode - enable memory caching during init.
+# Note: The user MUST add the property name with suffix '_specific' before providing the list of the cached memories.
+# Possible options (suffixes):
+# _all - enable all tables (excluding read-only/write-only/dynamic/signal)
+# _predefined - enable predefined list of tables
+# _parity - enable tables protected by parity field
+# _ecc - enable tables protected by ecc field
+# _specific - enable specific tables - MUST add this suffix if specific tables should be cached
+# _specific_X - enable caching for memory X, where X is memory name. Note: will not work without the previous suffix
+# Example: (this example will enable caching of the IHP_RECYCLE_COMMAND table)
+# mem_cache_enable_specific.BCM88650=1 #(MUST be added in case specific tables should be cached)
+# mem_cache_enable_specific_IHP_RECYCLE_COMMAND.BCM88650=1
+# mem_cache_enable_specific.BCM88675=1
+# mem_cache_enable_specific_IPS_QUEUE_PRIORITY_TABLE.BCM88675=1
+
+mem_cache_enable_parity.BCM88650=1
+mem_cache_enable_parity.BCM88675=1
+mem_cache_enable_parity.BCM88202=1
+mem_cache_enable_parity.BCM88750=1
+mem_cache_enable_parity.BCM88950=1
+mem_cache_enable_ecc=0
+
+# mem_nocache property
+# Cache memory mode - disable memory caching for specific table during init.
+# Note: the user MUST add the default property name before providing the list of the uncached memories.
+# Possible options (suffixes):
+# specific_X - disable caching for memory X, where X is memory name. Note: will not work without the previous suffix
+# Example: (this example will enable caching of the IHP_TERMINATION_PROFILE_TABLE table)
+# mem_nocache.BCM88660=1 #(MUST be added in case there are uncached memories)
+# mem_nocache_IHP_TERMINATION_PROFILE_TABLE.BCM88660=1
+#mem_nocache.BCM88680=1
+#mem_nocache_PPDB_B_LIF_TABLE_LABEL_PROTOCOL_OR_LSP.BCM88680=1
+#mem_nocache_PPDB_B_LIF_TABLE.BCM88680=1
+
+
+custom_feature_no_backdoor=1
+
+# Jericho split horizon mode
+# 0 - Use 0-1 range for lif orientation.
+# 1 (default) - Use 0-1 range for lif orientation in AC lifs and 0-3 range for orientation in other lif types.
+split_horizon_forwarding_groups_mode.BCM88675=1
+split_horizon_forwarding_groups_mode.BCM88470=1
+split_horizon_forwarding_groups_mode.BCM88680=1
+
+
+# Entries capacities for public and private IP forwarding tables
+private_ip_frwrd_table_size=500000
+public_ip_frwrd_table_size=500000
+
+
+#Enable KAPS ARM and Descriptor-DMA
+dma_desc_aggregator_chain_length_max=500
+dma_desc_aggregator_buff_size_kb=100
+dma_desc_aggregator_timeout_usec=1000
+dma_desc_aggregator_enable_specific_KAPS=1
+
+#In Jericho the KAPS ARM DMA already consumes 64KB of buffer memory
+dma_desc_aggregator_buff_size_kb.BCM88675=40
+
+# Entries capacities for direct access tables in KAPS (8K granularity)
+#pmf_kaps_large_db_size=8096
+
+#enable expose of HW id instead of SW id in Traps.
+bcm886xx_rx_use_hw_trap_id.BCM88675=1
+
+# Jericho - maximum RIF Id ( valid range is 0 to 32*1024-1)
+#rif_id_max=20000
+
+#If set, never add the PPH learn extension (unless explictly required in FP action).
+#bcm886xx_pph_learn_extension_disable.BCM88650=0
+#bcm886xx_pph_learn_extension_disable.BCM88660=0
+#bcm886xx_pph_learn_extension_disable.BCM88675=0
+
+# Jericho - field_ip_first_fragment_parsed
+#field_ip_first_fragment_parsed=0
+
+# learning_fifo_dma_buffer_size in bytes (host memory size). Valid range is 20-327680
+learning_fifo_dma_buffer_size=200000
+# learning_fifo_dma_timeout in microseconds. Valid range is 0-65535. 0 means no timeout.
+learning_fifo_dma_timeout=32767
+# learning_fifo_dma_threshold valid range is 1-16384 (0x4000)
+learning_fifo_dma_threshold=4
+
+###################################
+########### OAM and BFD ###########
+###################################
+
+# OAM / BFD initialization
+# To enable OAM set oam_enable to 1
+# To enable BFD set bfd_enable to 1
+# Be aware that OAM requires more settings (Configuring OAMP and Recycle port)
+
+# oam_enable=1
+# bfd_enable=1
+
+# Set OAMP port
+num_oamp_ports.BCM88650=0
+
+# If BFD is used, runtime_performance_optimize_enable_sched_allocation should be set to 0
+# to prevent high memory consumption
+
+# Disable the following:
+# bcm886xx_next_hop_mac_extension_enable
+# bcm886xx_ipv6_tunnel_enable
+
+# To use IEEE 1588, configure DPLL clock
+
+# Configure recycle port (assuming ucode_port_40=RCY.0)
+
+#oam_rcy_port.BCM88650=40
+#tm_port_header_type_in_40.BCM88650=TM
+#tm_port_header_type_out_40.BCM88650=ETH
+#ucode_port_40.0=RCY.0:core_0.40
+
+# MPLS-TP channel types for OAM/BFD - If MPLS-TP used, channel should be specified
+# Available types: mplstp_bfd_control_channel_type
+# mplstp_pw_ach_channel_type
+# mplstp_dlm_channel_type
+# mplstp_ilm_channel_type
+# mplstp_dm_channel_type
+# mplstp_ipv4_channel_type
+# mplstp_cc_channel_type
+# mplstp_cv_channel_type
+# mplstp_on_demand_cv_channel_type
+# mplstp_pwe_oam_channel_type
+# mplstp_ipv6_channel_type
+# mplstp_fault_oam_channel_type
+# mplstp_g8113_channel_type
+#mplstp_g8113_channel_type=0x8902
+#mplstp_fault_oam_channel_type=0x5678
+
+# Use BFD MPLS TP
+#bfd_encapsulation_mode=1
+
+# Use 1711 protocol
+#custom_feature_y1711_enabled=1
+
+# OAM DMA threshold
+#oamp_fifo_dma_event_interface_enable=1
+#oamp_fifo_dma_event_interface_timeout=0
+#oamp_fifo_dma_event_interface_buffer_size=0x1000
+#oamp_fifo_dma_event_interface_threshold=10
+
+# PORT BASED PWE TERMINATION
+#pwe_termination_port_mode_enable =1
+
+# Walk around for Inlif data Errata, for GAL packets, lookup mpls table with valid mpls label
+# it's not offical solution, just for some dedicated customer.
+# offical solution will be PMF. please refer the relevant doc.
+#custom_feature_gal_lookup_exactly=1
+
+custom_feature_cmodel_loopback=1
+
+#for IPv6UC: use Tcam instead of KAPS
+#custom_feature_l3_ipv6_uc_use_tcam=0
+# ipv6_mc need KPB library
+custom_feature_ipv6_mc_forwarding_disable = 1
+vlan_match_criteria_mode=PON_PCP_ETHERTYPE
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/dnx.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/dnx.soc
new file mode 100644
index 0000000..eb90675
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/dnx.soc
@@ -0,0 +1,192 @@
+#
+# $Id: jer.soc,v 1.90 2013/08/14 08:32:00 ninash Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+debug info
+debug appl rcload warn
+debug appl symtab warn
+debug bcm rx,tx,link,attach warn
+debug soc tests warn
+debug soc rx,phy,schan,reg,socmem,dma,mem,miim,mii,intr,counter,ddr warn
+debug soc common err
+debug sys verinet warn
+debug soc physim warn
+
+if $?QMX_A0 || $?BCM88370_A0 || $?BCM88371_A0 || $?BCM88371M_A0 || $?BCM88375_A0 || $?BCM88376_A0 || $?BCM88376M_A0 || $?BCM88377_A0 || $?BCM88378_A0 || $?BCM88379_A0 || \
+ $?QMX_A1 || $?BCM88370_A1 || $?BCM88371_A1 || $?BCM88371M_A1 || $?BCM88375_A1 || $?BCM88376_A1 || $?BCM88376M_A1 || $?BCM88377_A1 || $?BCM88378_A1 || $?BCM88379_A1 ||\
+ $?QMX_B0 || $?BCM88370_B0 || $?BCM88371_B0 || $?BCM88371M_B0 || $?BCM88375_B0 || $?BCM88376_B0 || $?BCM88376M_B0 || $?BCM88377_B0 || $?BCM88378_B0 || $?BCM88379_B0 \
+ 'local QMX 1'
+if $?JERICHO_A0 || $?BCM88670_A0 || $?BCM88671_A0 || $?BCM88671M_A0 || $?BCM88672_A0 || $?BCM88673_A0 || $?BCM88674_A0 || $?BCM88675_A0 || $?BCM88675M_A0 || $?BCM88676_A0 || $?BCM88676M_A0 || $?BCM88678_A0 || $?BCM88679_A0 || \
+ $?JERICHO_A1 || $?BCM88670_A1 || $?BCM88671_A1 || $?BCM88671M_A1 || $?BCM88672_A1 || $?BCM88673_A1 || $?BCM88674_A1 || $?BCM88675_A1 || $?BCM88675M_A1 || $?BCM88676_A1 || $?BCM88676M_A1 || $?BCM88678_A1 || $?BCM88679_A1 || \
+ $?JERICHO_B0 || $?BCM88670_B0 || $?BCM88671_B0 || $?BCM88671M_B0 || $?BCM88672_B0 || $?BCM88673_B0 || $?BCM88674_B0 || $?BCM88675_B0 || $?BCM88675M_B0 || $?BCM88676_B0 || $?BCM88676M_B0 || $?BCM88678_B0 || $?BCM88679_B0 \
+ 'local JERICHO 1'
+if $?BCM88680_A0 || $?BCM88681_A0 || $?BCM88682_A0 || $?BCM88683_A0 || $?BCM88380_A0 || $?BCM88381_A0 \
+ 'local JERPLUS 1'
+
+if $?BCM88690_A0 \
+ 'local JERTWO 1'
+
+if $?QMX \
+ 'rcload bcm88375_board.soc'
+if $?JERICHO \
+ 'rcload bcm88675_board.soc'
+
+if $?JERPLUS \
+ 'rcload bcm88680_board.soc'
+
+#
+# For Jericho-2:
+# This will have to change when we have bcm88690_board.soc
+#
+if $?JERTWO \
+ 'rcload bcm88680_board.soc'
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+set RCError=off
+debug appl shell warn
+if $?QMX \
+ 'rcload /home/negev/bcm88375_dram_tune.soc'
+
+if $?JERICHO \
+ 'rcload /home/negev/bcm88675_dram_tune.soc'
+
+debug appl shell =
+set RCError=on
+
+set RCError=off
+rcload combo28_dram.soc
+set RCError=on
+
+#Set fabric connect mode as FE for multi FAP system
+if $?diag_chassis " \
+ config add fabric_connect_mode.BCM88675=FE"
+
+# Set modid:
+# If diag_chassis is enabled (two line cards), and 'slot' is defined (slot is defined only when
+# working without a management card - set modid to be 'slot'
+# Otherwise (single line card, or management card), set modid to be 0 for unit 0, and 1 for unit != 0
+if $?diag_chassis && $?slot "\
+ local modid $slot" \
+else "\
+ local modid $unit"
+expr $modid==1; if $? "local modid 2"
+
+if $?module_id " \
+ local modid $module_id"
+
+echo "$unit: modid=$modid"
+
+# Set base_modid:
+# Id base_module_id is set, then set base_modid to have base_module_id value.
+# Otherwise, set base_modid to be 0.
+if $?base_module_id " \
+ local base_modid $base_module_id" \
+else " \
+ local base_modid 0"
+
+expr $base_modid > 0
+if $? " \
+ echo '$unit: base_modid=$base_modid'"
+
+if $?diag_chassis " \
+ local nof_devices 2" \
+else "\
+ local nof_devices 1"
+
+if $?n_devices " \
+ local nof_devices $n_devices"
+
+expr $nof_devices > 1
+if $? " \
+ echo '$unit: nof_devices=$nof_devices'"
+
+if $?mng_cpu " \
+ echo '$unit:management card - polling is set on'; \
+ config add polled_irq_mode.BCM88675=1; \
+ config add schan_intr_enable.BCM88675=0; \
+ config add tdma_intr_enable.BCM88675=0; \
+ config add tslam_intr_enable.BCM88675=0; \
+ config add miim_intr_enable.BCM88675=0; "
+
+#Counters unavailable in cmodel
+if $?cmodel " \
+ config add counter_engine_sampling_interval=0;"
+
+#default values in a case which these parameters are not exist
+if !$?diag_cosq_disable "\
+ local diag_cosq_disable 0"
+if !$?warmboot "\
+ local warmboot 0"
+if !$?diag_disable "\
+ local diag_disable 0"
+if !$?diag_no_itmh_prog_mode "\
+ local diag_no_itmh_prog_mode 0"
+if !$?l2_mode "\
+ local l2_mode 0"
+
+if $?JERPLUS "\
+ local diag_disable 0"
+local init_others NoLinkscan=0
+if $?JERPLUS "\
+ local init_others 'NoIntr=1 NoLinkscan=1 NoApplStk=0'"
+
+#Disable interrupts in cmodel
+if $?cmodel "\
+ local no_intr 1" \
+else "\
+ local no_intr 0"
+
+#
+# For Jericho-2, we TEMPORARILY disable some components to quickly enable
+# a working PCID version.
+#
+if $?JERTWO "\
+ local no_soc 0"
+
+if $?JERTWO "\
+ local no_intr 1"
+
+
+#INIT_DNX ModID=$modid NofDevices=$nof_devices CosqDisable=$diag_cosq_disable NoAppl=$diag_disable Warmboot=$warmboot NoRxLos=1 $init_others NoItmhProgMode=$diag_no_itmh_prog_mode L2Mode=$l2_mode NoIntr=$no_intr NoSoc=$no_soc
+
+INIT_DNX
+
+#LED support section start
+#Program of LED0
+local ledcode_0 '02 05 67 2D 02 01 67 2D 02 11 67 2D 02 09 67 2D\
+ 02 15 67 2D 02 0D 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+#Program of LED1
+local ledcode_1 '02 1D 67 2D 02 2D 67 2D 02 05 67 2D 02 0D 67 2D\
+ 02 09 67 2D 02 01 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+
+#Program of LED2
+local ledcode_2 '02 01 67 2D 02 09 67 2D 02 0D 67 2D 02 05 67 2D\
+ 02 2D 67 2D 02 1D 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+# Download LED code into LED processors and enable (if applicable).
+if $?feature_led_proc && !$?simulator \
+ "led 0 prog $ledcode_0; \
+ led 1 prog $ledcode_1; \
+ led 2 prog $ledcode_2; \
+ led auto on; \
+ led 0 start; \
+ led 1 start; \
+ led 2 start"
+
+
+echo "dnx.soc: Done............................."
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/dune.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/dune.soc
new file mode 100644
index 0000000..57f24ea
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/dune.soc
@@ -0,0 +1,1080 @@
+#
+# $Id: dune.soc,v 1.5 2011/12/20 10:53:28 yaronm Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+# Configure fap device mode (TM/PP/TDM_OPTIMIZED/TDM_STANDARD)
+# and ftmh outlif extension depending on config variables 'packet_processing' and 'tdm' variables
+if $?tdm "\
+ echo '*** TDM MODE ***'; \
+ config add diag_cosq_disable=1; \
+ if !$?fap_device_mode 'config add fap_device_mode=TDM_STANDARD'; \
+ config add fabric_ftmh_outlif_extension=ALWAYS; \
+ config ext_qdr_type=NONE; \
+ config ext_ram_present=0"
+if !$?tdm && $?packet_processing "\
+ echo '*** PACKET PROCESSING MODE ***'; \
+ config add fabric_ftmh_outlif_extension=ALWAYS; \
+ config add fap_device_mode=PP; \
+ config add egress_encap_ip_tunnel_range_min=4095; \
+ config add egress_encap_ip_tunnel_range_max=4095; \
+ config add mpls_tunnel_term_label_range_min_0=1000; \
+ config add mpls_tunnel_term_label_range_max_0=1001; \
+ config add mpls_tunnel_term_label_range_min_1=1002; \
+ config add mpls_tunnel_term_label_range_max_1=1003; \
+ config add mpls_tunnel_term_label_range_min_2=1004; \
+ config add mpls_tunnel_term_label_range_max_2=1005; \
+ if !$?diag_cosq_disable 'config add diag_cosq_disable=0';"
+if !$?tdm && !$?packet_processing "\
+ echo '*** TM ONLY MODE ***'; \
+ config add fap_device_mode=TM; \
+ config add fabric_ftmh_outlif_extension=IF_MC; \
+ if !$?diag_cosq_disable 'config add diag_cosq_disable=0'"
+
+# When more than a single device, set connect mode to FE and modid
+# to the slot id. For a single device, set connect mode to SINGLE_FAP
+# and modid to 0. Note that when using single_fap, all fabric-facing serdes
+# lanes are set in loopback, for fabric multicast to work.
+# All options for fabric_connect_mode are FE/BACK2BACK/MESH/MULTI_STAGE_FE/SINGLE_FAP
+
+if !$?diag_cosq_disable "config add diag_cosq_disable=0"
+if !$?slot || !$?diag_chassis "local slot 0"
+if !$?board_type_GFA_BI "local board_type_GFA_BI 1"
+if !$?board_type_GFA_BI_2 "local board_type_GFA_BI_2 0"
+
+if $?diag_chassis " \
+ local nof_devices 2; \
+ config add fabric_connect_mode=FE" \
+else "\
+ local nof_devices 1; \
+ if !$?fabric_connect_mode 'config add fabric_connect_mode=SINGLE_FAP'"
+
+#Enable all quartets. Can be done per quartet using _N suffix
+config add pb_serdes_qrtt_active=1
+
+local lane_rate_nif 6250000
+local lane_rate_com_a 6250000
+if $board_type_GFA_BI "\
+ local lane_rate_fbr 5000000; \
+ local lane_rate_com_b 3125000; \
+ config add fabric_ref_clock=250000; \
+ config add combo_nif_0=1; \
+ config add combo_nif_1=1" \
+else '\
+ local lane_rate_fbr 6250000; \
+ local lane_rate_com_b 6250000; \
+ config add fabric_ref_clock=312500; \
+ config add combo_nif_0=0; \
+ config add combo_nif_1=0; \
+ for i=32,59 \'config add pb_serdes_lane_tx_phys_media_type_$i=CHIP2CHIP\''
+
+# Nif serdes quartets
+for i=0,2 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_nif'
+for i=4,6 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_nif'
+
+# Nif serdes quartet (combo-a)
+config add pb_serdes_qrtt_max_expected_rate_3=$lane_rate_com_a
+
+# Nif serdes quartet (combo-b)
+config add pb_serdes_qrtt_max_expected_rate_7=$lane_rate_com_b
+
+# Fabric serdes quartets
+for i=8,14 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_fbr'
+
+# set default rate to nif rate. Override fabric lanes.
+config add pb_serdes_lane_rate=$lane_rate_nif
+for i=12,15 'config add pb_serdes_lane_rate_$i=$lane_rate_com_a'
+for i=28,31 'config add pb_serdes_lane_rate_$i=$lane_rate_com_b'
+for i=32,59 'config add pb_serdes_lane_rate_$i=$lane_rate_fbr'
+
+# Board Type configuration.
+
+if $board_type_GFA_BI "\
+ echo Configure GFA_BI Port/Interfcae/Nif/SerDes parameters; \
+ config add ucode_port_1=RXAUI7; \
+ config add ucode_port_2=RXAUI6; \
+ config add ucode_port_3=XAUI7; \
+ config add ucode_port_4=RXAUI0; \
+ config add ucode_port_5=RXAUI2; \
+ config add ucode_port_6=RXAUI4; \
+ config add ucode_port_7=RXAUI12; \
+ config add ucode_port_8=RXAUI10; \
+ config add ucode_port_9=RXAUI8; \
+ config add pb_serdes_lane_swap_polarity_tx_9=1; \
+ config add pb_serdes_lane_swap_polarity_tx_29=1; \
+ config add pb_serdes_lane_swap_polarity_rx_13=1; \
+ config add pb_serdes_lane_swap_polarity_rx_18=1; \
+ config add pb_serdes_lane_swap_polarity_rx_22=1; \
+ config add pb_serdes_lane_swap_polarity_rx_30=1; \
+ config add pb_serdes_lane_swap_polarity_rx_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt=1; \
+ config add pb_serdes_lane_rx_phys_dfelth=20; \
+ config add pb_serdes_lane_rx_phys_tlth=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt=1; \
+ config add pb_serdes_lane_tx_phys_amp_12=30; \
+ config add pb_serdes_lane_tx_phys_main_12=18; \
+ config add pb_serdes_lane_tx_phys_pre_12=3; \
+ config add pb_serdes_lane_tx_phys_post_12=13; \
+ config add pb_serdes_lane_tx_phys_amp_13=30; \
+ config add pb_serdes_lane_tx_phys_main_13=18; \
+ config add pb_serdes_lane_tx_phys_pre_13=3; \
+ config add pb_serdes_lane_tx_phys_post_13=13; \
+ config add pb_serdes_lane_tx_phys_amp_14=30; \
+ config add pb_serdes_lane_tx_phys_main_14=18; \
+ config add pb_serdes_lane_tx_phys_pre_14=3; \
+ config add pb_serdes_lane_tx_phys_post_14=13; \
+ config add pb_serdes_lane_tx_phys_amp_15=30; \
+ config add pb_serdes_lane_tx_phys_main_15=18; \
+ config add pb_serdes_lane_tx_phys_pre_15=3; \
+ config add pb_serdes_lane_tx_phys_post_15=13;"
+
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_3=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_3=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_3=15; \
+ config add pb_serdes_lane_rx_phys_tlth_3=18; \
+ config add pb_serdes_lane_rx_phys_g1cnt_3=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_12=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=1; \
+ config add pb_serdes_lane_rx_phys_tlth_12=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=18; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=0; \
+ config add pb_serdes_lane_rx_phys_tlth_13=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=2; \
+ config add pb_serdes_lane_rx_phys_tlth_14=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=19; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=0; \
+ config add pb_serdes_lane_rx_phys_tlth_15=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=0; \
+ config add pb_serdes_lane_rx_phys_tlth_28=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=0; \
+ config add pb_serdes_lane_rx_phys_tlth_29=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=0; \
+ config add pb_serdes_lane_rx_phys_tlth_30=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=0; \
+ config add pb_serdes_lane_rx_phys_tlth_31=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1;"
+
+# TX params for fabric rate of 5000 mbps (Negev system).
+# Overrides media type configuration.
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_tx_phys_amp_32=31; \
+ config add pb_serdes_lane_tx_phys_main_32=24; \
+ config add pb_serdes_lane_tx_phys_pre_32=0; \
+ config add pb_serdes_lane_tx_phys_post_32=0; \
+ config add pb_serdes_lane_tx_phys_amp_33=31; \
+ config add pb_serdes_lane_tx_phys_main_33=24; \
+ config add pb_serdes_lane_tx_phys_pre_33=0; \
+ config add pb_serdes_lane_tx_phys_post_33=0; \
+ config add pb_serdes_lane_tx_phys_amp_34=31; \
+ config add pb_serdes_lane_tx_phys_main_34=24; \
+ config add pb_serdes_lane_tx_phys_pre_34=0; \
+ config add pb_serdes_lane_tx_phys_post_34=0; \
+ config add pb_serdes_lane_tx_phys_amp_35=31; \
+ config add pb_serdes_lane_tx_phys_main_35=24; \
+ config add pb_serdes_lane_tx_phys_pre_35=0; \
+ config add pb_serdes_lane_tx_phys_post_35=0; \
+ config add pb_serdes_lane_tx_phys_amp_36=31; \
+ config add pb_serdes_lane_tx_phys_main_36=24; \
+ config add pb_serdes_lane_tx_phys_pre_36=0; \
+ config add pb_serdes_lane_tx_phys_post_36=0; \
+ config add pb_serdes_lane_tx_phys_amp_37=31; \
+ config add pb_serdes_lane_tx_phys_main_37=24; \
+ config add pb_serdes_lane_tx_phys_pre_37=0; \
+ config add pb_serdes_lane_tx_phys_post_37=0; \
+ config add pb_serdes_lane_tx_phys_amp_38=31; \
+ config add pb_serdes_lane_tx_phys_main_38=24; \
+ config add pb_serdes_lane_tx_phys_pre_38=0; \
+ config add pb_serdes_lane_tx_phys_post_38=0; \
+ config add pb_serdes_lane_tx_phys_amp_39=31; \
+ config add pb_serdes_lane_tx_phys_main_39=24; \
+ config add pb_serdes_lane_tx_phys_pre_39=0; \
+ config add pb_serdes_lane_tx_phys_post_39=0; \
+ config add pb_serdes_lane_tx_phys_amp_40=31; \
+ config add pb_serdes_lane_tx_phys_main_40=24; \
+ config add pb_serdes_lane_tx_phys_pre_40=0; \
+ config add pb_serdes_lane_tx_phys_post_40=0; \
+ config add pb_serdes_lane_tx_phys_amp_41=31; \
+ config add pb_serdes_lane_tx_phys_main_41=24; \
+ config add pb_serdes_lane_tx_phys_pre_41=0; \
+ config add pb_serdes_lane_tx_phys_post_41=0; \
+ config add pb_serdes_lane_tx_phys_amp_42=31; \
+ config add pb_serdes_lane_tx_phys_main_42=24; \
+ config add pb_serdes_lane_tx_phys_pre_42=0; \
+ config add pb_serdes_lane_tx_phys_post_42=0"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_tx_phys_amp_43=31; \
+ config add pb_serdes_lane_tx_phys_main_43=24; \
+ config add pb_serdes_lane_tx_phys_pre_43=0; \
+ config add pb_serdes_lane_tx_phys_post_43=0; \
+ config add pb_serdes_lane_tx_phys_amp_44=31; \
+ config add pb_serdes_lane_tx_phys_main_44=24; \
+ config add pb_serdes_lane_tx_phys_pre_44=0; \
+ config add pb_serdes_lane_tx_phys_post_44=0; \
+ config add pb_serdes_lane_tx_phys_amp_45=31; \
+ config add pb_serdes_lane_tx_phys_main_45=24; \
+ config add pb_serdes_lane_tx_phys_pre_45=0; \
+ config add pb_serdes_lane_tx_phys_post_45=0; \
+ config add pb_serdes_lane_tx_phys_amp_46=31; \
+ config add pb_serdes_lane_tx_phys_main_46=24; \
+ config add pb_serdes_lane_tx_phys_pre_46=0; \
+ config add pb_serdes_lane_tx_phys_post_46=0; \
+ config add pb_serdes_lane_tx_phys_amp_47=31; \
+ config add pb_serdes_lane_tx_phys_main_47=24; \
+ config add pb_serdes_lane_tx_phys_pre_47=0; \
+ config add pb_serdes_lane_tx_phys_post_47=0; \
+ config add pb_serdes_lane_tx_phys_amp_48=31; \
+ config add pb_serdes_lane_tx_phys_main_48=24; \
+ config add pb_serdes_lane_tx_phys_pre_48=0; \
+ config add pb_serdes_lane_tx_phys_post_48=0; \
+ config add pb_serdes_lane_tx_phys_amp_49=31; \
+ config add pb_serdes_lane_tx_phys_main_49=24; \
+ config add pb_serdes_lane_tx_phys_pre_49=0; \
+ config add pb_serdes_lane_tx_phys_post_49=0; \
+ config add pb_serdes_lane_tx_phys_amp_50=31; \
+ config add pb_serdes_lane_tx_phys_main_50=24; \
+ config add pb_serdes_lane_tx_phys_pre_50=0; \
+ config add pb_serdes_lane_tx_phys_post_50=0; \
+ config add pb_serdes_lane_tx_phys_amp_51=31; \
+ config add pb_serdes_lane_tx_phys_main_51=24; \
+ config add pb_serdes_lane_tx_phys_pre_51=0; \
+ config add pb_serdes_lane_tx_phys_post_51=0; \
+ config add pb_serdes_lane_tx_phys_amp_52=31; \
+ config add pb_serdes_lane_tx_phys_main_52=24; \
+ config add pb_serdes_lane_tx_phys_pre_52=0; \
+ config add pb_serdes_lane_tx_phys_post_52=0; \
+ config add pb_serdes_lane_tx_phys_amp_53=31; \
+ config add pb_serdes_lane_tx_phys_main_53=24; \
+ config add pb_serdes_lane_tx_phys_pre_53=0; \
+ config add pb_serdes_lane_tx_phys_post_53=0; \
+ config add pb_serdes_lane_tx_phys_amp_54=31; \
+ config add pb_serdes_lane_tx_phys_main_54=24; \
+ config add pb_serdes_lane_tx_phys_pre_54=0; \
+ config add pb_serdes_lane_tx_phys_post_54=0; \
+ config add pb_serdes_lane_tx_phys_amp_55=31; \
+ config add pb_serdes_lane_tx_phys_main_55=24; \
+ config add pb_serdes_lane_tx_phys_pre_55=0; \
+ config add pb_serdes_lane_tx_phys_post_55=0; \
+ config add pb_serdes_lane_tx_phys_amp_56=31; \
+ config add pb_serdes_lane_tx_phys_main_56=24; \
+ config add pb_serdes_lane_tx_phys_pre_56=0; \
+ config add pb_serdes_lane_tx_phys_post_56=0; \
+ config add pb_serdes_lane_tx_phys_amp_57=31; \
+ config add pb_serdes_lane_tx_phys_main_57=24; \
+ config add pb_serdes_lane_tx_phys_pre_57=0; \
+ config add pb_serdes_lane_tx_phys_post_57=0; \
+ config add pb_serdes_lane_tx_phys_amp_58=31; \
+ config add pb_serdes_lane_tx_phys_main_58=24; \
+ config add pb_serdes_lane_tx_phys_pre_58=0; \
+ config add pb_serdes_lane_tx_phys_post_58=0; \
+ config add pb_serdes_lane_tx_phys_amp_59=31; \
+ config add pb_serdes_lane_tx_phys_main_59=24; \
+ config add pb_serdes_lane_tx_phys_pre_59=0; \
+ config add pb_serdes_lane_tx_phys_post_59=0;"
+
+# RX params for fabric rate of 5000 mbps (Negev system)
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_32=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=21; \
+ config add pb_serdes_lane_rx_phys_tlth_32=35; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_33=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=28; \
+ config add pb_serdes_lane_rx_phys_tlth_33=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=18; \
+ config add pb_serdes_lane_rx_phys_tlth_34=26; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=23; \
+ config add pb_serdes_lane_rx_phys_tlth_35=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=22; \
+ config add pb_serdes_lane_rx_phys_tlth_36=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=20; \
+ config add pb_serdes_lane_rx_phys_tlth_37=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=23; \
+ config add pb_serdes_lane_rx_phys_tlth_38=29; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=24; \
+ config add pb_serdes_lane_rx_phys_tlth_39=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=21; \
+ config add pb_serdes_lane_rx_phys_tlth_40=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=20; \
+ config add pb_serdes_lane_rx_phys_tlth_41=6; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1;"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=18; \
+ config add pb_serdes_lane_rx_phys_tlth_42=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=26; \
+ config add pb_serdes_lane_rx_phys_tlth_43=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=22; \
+ config add pb_serdes_lane_rx_phys_tlth_44=34; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=21; \
+ config add pb_serdes_lane_rx_phys_tlth_46=28; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=16; \
+ config add pb_serdes_lane_rx_phys_tlth_47=9; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=23; \
+ config add pb_serdes_lane_rx_phys_tlth_48=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=28; \
+ config add pb_serdes_lane_rx_phys_tlth_49=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=24;"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_tlth_50=19; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_51=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=22; \
+ config add pb_serdes_lane_rx_phys_tlth_51=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=24; \
+ config add pb_serdes_lane_rx_phys_tlth_52=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=10; \
+ config add pb_serdes_lane_rx_phys_tlth_53=5; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=29; \
+ config add pb_serdes_lane_rx_phys_tlth_54=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=24; \
+ config add pb_serdes_lane_rx_phys_tlth_55=22; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=22; \
+ config add pb_serdes_lane_rx_phys_tlth_56=31; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=22; \
+ config add pb_serdes_lane_rx_phys_tlth_57=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1;"
+
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_58=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=23; \
+ config add pb_serdes_lane_rx_phys_tlth_58=26; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=21; \
+ config add pb_serdes_lane_rx_phys_tlth_59=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1;"
+
+if $board_type_GFA_BI_2 "\
+ echo Configure GFA_BI_2 Port/Interfcae/Nif/SerDes parameters; \
+ config add ucode_port_1=RXAUI3; \
+ config add ucode_port_2=RXAUI2; \
+ config add ucode_port_3=RXAUI1; \
+ config add ucode_port_4=RXAUI0; \
+ config add ucode_port_5=RXAUI8; \
+ config add ucode_port_6=RXAUI9; \
+ config add ucode_port_7=RXAUI5; \
+ config add ucode_port_8=RXAUI4; \
+ config add ucode_port_9=RXAUI12; \
+ config add ucode_port_10=RXAUI13; \
+ config add ucode_port_11=RXAUI10; \
+ config add ucode_port_12=RXAUI11; \
+ config add lanes_swap_6=1; \
+ config add lanes_swap_10=1; \
+ config add lanes_swap_11=1; \
+ config add lanes_swap_12=1; \
+ config add pb_serdes_lane_swap_polarity_tx_12=1; \
+ config add pb_serdes_lane_swap_polarity_tx_14=1; \
+ config add pb_serdes_lane_swap_polarity_tx_28=1; \
+ config add pb_serdes_lane_swap_polarity_tx_31=1; \
+ config add pb_serdes_lane_swap_polarity_tx_32=1; \
+ config add pb_serdes_lane_swap_polarity_tx_34=1; \
+ config add pb_serdes_lane_swap_polarity_tx_41=1; \
+ config add pb_serdes_lane_swap_polarity_rx_48=1; \
+ config add pb_serdes_lane_swap_polarity_rx_50=1; \
+ config add pb_serdes_lane_swap_polarity_rx_52=1; \
+ config add pb_serdes_lane_swap_polarity_rx_55=1; \
+ config add pb_serdes_lane_swap_polarity_rx_56=1; \
+ config add pb_serdes_lane_swap_polarity_rx_58=1;"
+
+if $board_type_GFA_BI_2 && !$system_is_fe600_in_system "\
+ config add pb_serdes_lane_rx_phys_zcnt=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt=1; \
+ config add pb_serdes_lane_rx_phys_dfelth=1; \
+ config add pb_serdes_lane_rx_phys_tlth=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt=1; \
+ config add pb_serdes_lane_tx_phys_amp=30; \
+ config add pb_serdes_lane_tx_phys_main=18; \
+ config add pb_serdes_lane_tx_phys_pre=3; \
+ config add pb_serdes_lane_tx_phys_post=13;"
+
+#GFA-BI2, with fe600, slot 0
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_12=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=11; \
+ config add pb_serdes_lane_rx_phys_tlth_12=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=17; \
+ config add pb_serdes_lane_rx_phys_tlth_13=7; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=18; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=7; \
+ config add pb_serdes_lane_rx_phys_tlth_14=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=21; \
+ config add pb_serdes_lane_rx_phys_tlth_15=21; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=18; \
+ config add pb_serdes_lane_rx_phys_tlth_28=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=9; \
+ config add pb_serdes_lane_rx_phys_tlth_29=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=18; \
+ config add pb_serdes_lane_rx_phys_tlth_30=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=10; \
+ config add pb_serdes_lane_rx_phys_tlth_31=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_32=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=22; \
+ config add pb_serdes_lane_rx_phys_tlth_32=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_33=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=13; \
+ config add pb_serdes_lane_rx_phys_tlth_33=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=20; \
+ config add pb_serdes_lane_rx_phys_tlth_34=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=11; \
+ config add pb_serdes_lane_rx_phys_tlth_35=5; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=11; \
+ config add pb_serdes_lane_rx_phys_tlth_36=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=10; \
+ config add pb_serdes_lane_rx_phys_tlth_37=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=20; \
+ config add pb_serdes_lane_rx_phys_tlth_38=11; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=9; \
+ config add pb_serdes_lane_rx_phys_tlth_39=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=24; \
+ config add pb_serdes_lane_rx_phys_tlth_40=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=9; \
+ config add pb_serdes_lane_rx_phys_tlth_41=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=10; \
+ config add pb_serdes_lane_rx_phys_tlth_42=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=25; \
+ config add pb_serdes_lane_rx_phys_tlth_43=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=9; \
+ config add pb_serdes_lane_rx_phys_tlth_44=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=9; \
+ config add pb_serdes_lane_rx_phys_tlth_46=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=11; \
+ config add pb_serdes_lane_rx_phys_tlth_47=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=8; \
+ config add pb_serdes_lane_rx_phys_tlth_48=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=15; \
+ config add pb_serdes_lane_rx_phys_tlth_49=13; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=17; \
+ config add pb_serdes_lane_rx_phys_tlth_50=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_51=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=8; \
+ config add pb_serdes_lane_rx_phys_tlth_51=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=6; \
+ config add pb_serdes_lane_rx_phys_tlth_52=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=11; \
+ config add pb_serdes_lane_rx_phys_tlth_53=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=5; \
+ config add pb_serdes_lane_rx_phys_tlth_54=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=14; \
+ config add pb_serdes_lane_rx_phys_tlth_55=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=20; \
+ config add pb_serdes_lane_rx_phys_tlth_56=21; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=14; \
+ config add pb_serdes_lane_rx_phys_tlth_57=7; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_58=19; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=11; \
+ config add pb_serdes_lane_rx_phys_tlth_58=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=12; \
+ config add pb_serdes_lane_rx_phys_tlth_59=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1"
+
+#GFA-BI2, with fe600, slot 1
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_12=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=9; \
+ config add pb_serdes_lane_rx_phys_tlth_12=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=20; \
+ config add pb_serdes_lane_rx_phys_tlth_13=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=9; \
+ config add pb_serdes_lane_rx_phys_tlth_14=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=10; \
+ config add pb_serdes_lane_rx_phys_tlth_15=9; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=14; \
+ config add pb_serdes_lane_rx_phys_tlth_28=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=9; \
+ config add pb_serdes_lane_rx_phys_tlth_29=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=6; \
+ config add pb_serdes_lane_rx_phys_tlth_30=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=14; \
+ config add pb_serdes_lane_rx_phys_tlth_31=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_32=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=19; \
+ config add pb_serdes_lane_rx_phys_tlth_32=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_33=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=11; \
+ config add pb_serdes_lane_rx_phys_tlth_33=10; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=17; \
+ config add pb_serdes_lane_rx_phys_tlth_34=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=12; \
+ config add pb_serdes_lane_rx_phys_tlth_35=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=10; \
+ config add pb_serdes_lane_rx_phys_tlth_36=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=10; \
+ config add pb_serdes_lane_rx_phys_tlth_37=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=20; \
+ config add pb_serdes_lane_rx_phys_tlth_38=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=11; \
+ config add pb_serdes_lane_rx_phys_tlth_39=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=24; \
+ config add pb_serdes_lane_rx_phys_tlth_40=18; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=11; \
+ config add pb_serdes_lane_rx_phys_tlth_41=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=10; \
+ config add pb_serdes_lane_rx_phys_tlth_42=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=22; \
+ config add pb_serdes_lane_rx_phys_tlth_43=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=7; \
+ config add pb_serdes_lane_rx_phys_tlth_44=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=9; \
+ config add pb_serdes_lane_rx_phys_tlth_46=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=9; \
+ config add pb_serdes_lane_rx_phys_tlth_47=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=8; \
+ config add pb_serdes_lane_rx_phys_tlth_48=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=12; \
+ config add pb_serdes_lane_rx_phys_tlth_49=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=18; \
+ config add pb_serdes_lane_rx_phys_tlth_50=11; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_51=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=7; \
+ config add pb_serdes_lane_rx_phys_tlth_51=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=8; \
+ config add pb_serdes_lane_rx_phys_tlth_52=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=12; \
+ config add pb_serdes_lane_rx_phys_tlth_53=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=7; \
+ config add pb_serdes_lane_rx_phys_tlth_54=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=12; \
+ config add pb_serdes_lane_rx_phys_tlth_55=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=21; \
+ config add pb_serdes_lane_rx_phys_tlth_56=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=8; \
+ config add pb_serdes_lane_rx_phys_tlth_57=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_58=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=8; \
+ config add pb_serdes_lane_rx_phys_tlth_58=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=14; \
+ config add pb_serdes_lane_rx_phys_tlth_59=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1"
+
+# DRAM pre-configurations according to config variables which defines
+# the dram type.
+
+#DDR3
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 || \
+ $?dram_type_DDR3_MICRON_MT41J64M16_15E || \
+ $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G "\
+ config add ext_ram_type=DDR3; \
+ config add ext_ram_columns=1024; \
+ config add ext_ram_banks=8"
+if $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G "\
+ config add ext_ram_total_size=3072"
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 || \
+ $?dram_type_DDR3_MICRON_MT41J64M16_15E "\
+ config add ext_ram_total_size=1536"
+
+#GDDR3
+if $?dram_type_GDDR3_SAMSUNG_K4J52324QE \
+ "config add ext_ram_type=GDDR3" \
+ "config add ext_ram_columns=512" \
+ "config add ext_ram_banks=8" \
+ "config add ext_ram_total_size=384"
+
+#DDR2
+if $?dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7 \
+ "config add ext_ram_type=DDR2" \
+ "config add ext_ram_columns=1024" \
+ "config add ext_ram_banks=4" \
+ "config add ext_ram_total_size=768"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=11" \
+ "config add ext_ram_c_wr_latency=8" \
+ "config add ext_ram_t_rc=48750" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=35000" \
+ "config add ext_ram_t_faw=40000" \
+ "config add ext_ram_t_rcd_rd=13750" \
+ "config add ext_ram_t_rcd_wr=13750" \
+ "config add ext_ram_t_rrd=7500" \
+ "config add ext_ram_t_ref=3900" \
+ "config add ext_ram_t_rp=13750" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=8" \
+ "config add ext_ram_t_rc=50000" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=36666" \
+ "config add ext_ram_t_faw=45000" \
+ "config add ext_ram_t_rcd_rd=15000" \
+ "config add ext_ram_t_rcd_wr=15000" \
+ "config add ext_ram_t_rrd=8333" \
+ "config add ext_ram_t_ref=3900" \
+ "config add ext_ram_t_rp=15000" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=8333" \
+ "config add ext_ram_t_rtp=6666"
+
+if $?dram_type_DDR3_MICRON_MT41J64M16_15E || $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=7" \
+ "config add ext_ram_t_rc=49500" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=36000" \
+ "config add ext_ram_t_faw=50000" \
+ "config add ext_ram_t_rcd_rd=13500" \
+ "config add ext_ram_t_rcd_wr=13500" \
+ "config add ext_ram_t_rrd=7500" \
+ "config add ext_ram_t_ref=3900c" \
+ "config add ext_ram_t_rp=13500" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+# Samsung (K4J52324QE)
+# The following parameters correspond to BC-16 dash, and were tested in
+# dune's lab with BC-14 dash dram working in frequency of 533MHz.
+if $?dram_type_GDDR3_SAMSUNG_K4J52324QE \
+ "config add ext_ram_ap_bit_pos=8" \
+ "config add ext_ram_burst_size=16" \
+ "config add ext_ram_gddr3_mrs0_wr1=0x00000312" \
+ "config add ext_ram_gddr3_emr0_wr1=0x0000109d" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=1" \
+ "config add ext_ram_t_rc_clk=24" \
+ "config add ext_ram_t_rfc_clk=29" \
+ "config add ext_ram_t_ras_clk=16" \
+ "config add ext_ram_t_faw_clk=5" \
+ "config add ext_ram_t_rcd_rd_clk=9" \
+ "config add ext_ram_t_rcd_wr_clk=6" \
+ "config add ext_ram_t_rrd_clk=7" \
+ "config add ext_ram_t_ref=1450" \
+ "config add ext_ram_t_rp_clk=8" \
+ "config add ext_ram_t_wr_clk=8" \
+ "config add ext_ram_t_wtr_clk=4" \
+ "config add ext_ram_t_rtp_clk=4"
+
+if $?dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=16" \
+ "config add ext_ram_auto_mode=TRUE" \
+ "config add ext_ram_c_cas_latency=6" \
+ "config add ext_ram_c_wr_latency=5" \
+ "config add ext_ram_t_rc=60000" \
+ "config add ext_ram_t_rfc=105000" \
+ "config add ext_ram_t_ras=45000" \
+ "config add ext_ram_t_faw=45000" \
+ "config add ext_ram_t_rcd_rd=15000" \
+ "config add ext_ram_t_rcd_wr=15000" \
+ "config add ext_ram_t_rrd=10000" \
+ "config add ext_ram_t_ref=3900)" \
+ "config add ext_ram_t_rp=15000" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+
+# If using elk, override relevant parameters:
+if $?pcp_elk "\
+ echo *** OVERRIDING DEFAULT CONFIG WITH ELK CONFIG ***; \
+ config combo_ref_clock=125000; \
+ config pb_serdes_qrtt_max_expected_rate_7=3750000; \
+ config pb_serdes_lane_rate_28=3750000; \
+ config pb_serdes_lane_rate_29=3750000; \
+ config pb_serdes_lane_rate_30=3750000; \
+ config pb_serdes_lane_rate_31=3750000; \
+ config add external_lookup_mal=14; \
+ config add spaui_ipg_dic_mode=MIN; \
+ config add spaui_ipg_size=1; \
+ config add spaui_crc_mode=32b; \
+ config add spaui_preamble_size=0; \
+ config add spaui_preamble_skip_sop=1; \
+ config add spaui_is_double_size_sop_even_only=1; \
+ config add spaui_link_partner_double_size_bus=1"
+
+if $?pcp_elk || $?pcp_oam || $?pcp_dma "\
+ config add streaming_if_multi_port_mode=1; \
+ config add streaming_if_discard_pkt_streaming=0; \
+ config add fabric_ftmh_outlif_extension=IF_MC" \
+else "\
+ config add streaming_if_multi_port_mode=0; \
+ config add streaming_if_discard_pkt_streaming=1;"
+
+# Run sweep pcp on real HW
+if !$?plisim && !$?warmboot " \
+ sweep pcp"
+
+# Set synts according to reference clocks
+expr $nif_ref_clock*1000; local synt_nif $?
+expr $combo_ref_clock*1000; local synt_combo $?
+expr $fabric_ref_clock*1000; local synt_fabric $?
+
+# Real HW: Take petra out of reset
+if !$?plisim && !$?warmboot " \
+ gfa_bi utils petra_reset 1; \
+ echo Configure synthesizers:; \
+ echo Fabric: $synt_fabric; gfa_bi utils synt_set 1 $synt_fabric $synt_over; \
+ echo Combo: $synt_combo; gfa_bi utils synt_set 2 $synt_combo $synt_over; \
+ echo Nif: $synt_nif; gfa_bi utils synt_set 3 $synt_nif $synt_over; \
+ echo Core: $synt_core; gfa_bi utils synt_set 4 $synt_core $synt_over; \
+ echo DDR: $synt_ddr; gfa_bi utils synt_set 5 $synt_ddr $synt_over; \
+ echo Phy: $synt_phy; gfa_bi utils synt_set 10 $synt_phy $synt_over; \
+ gfa_bi utils petra_reset 0"
+
+dbm soc error
+dbm bcm error
+
+echo "$unit:init soc"
+init soc
+echo "$unit:init soc - Done"
+
+echo "$unit:init bcm"
+init bcm
+
+echo "$unit:init bcm - Done"
+
+if $?warmboot "\
+ echo 'Warmboot: init done'; \
+ echo 'dune.soc: Done.'; \
+ exit"
+
+# Real HW + non using sweep: Init phys
+if !$?plisim " \
+ gfa_bi utils phys"
+
+if !$?no_bcm && !$?diag_disable "\
+ init appl_dpp $slot $nof_devices $diag_cosq_disable;" \
+else "\
+ echo 'Skipping diag_init. In order to run traffic, extra configuration must be performed.'"
+
+# If running BCM library:
+# Start linkscan task and set port linkscan mode.
+if !$?no_bcm && !$?pcp_elk "\
+ linkscan 250000; \
+ linkscan spbm=xe"
+
+# If using elk, configure bsp:
+if $?pcp_elk "\
+ echo *** BSP ELK CONFIGURATIONS ***; \
+ gfa_bi elk_init;"
+
+# If using pcp dma then init dma
+if !$?plisim && $?pcp_dma " \
+ echo *** PCP DMA CONFIGURATIONS ***; \
+ gfa_bi dma_init"
+
+#if $?diag_chassis && !$slot "rcload rc/negev_rpc_master.soc.assi" # Master on slot 0
+#if $?diag_chassis && $slot "rcload rc/negev_rpc_slave.soc.assi" # Slave on slot 1
+
+echo "dune.soc: Done."
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/init.sh b/bal_release/3rdparty/bcm-sdk/rc/qax/init.sh
new file mode 100755
index 0000000..f5b62bf
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/init.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+echo "I am here 4"
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/qax.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/qax.soc
new file mode 100755
index 0000000..895ae81
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/qax.soc
@@ -0,0 +1,128 @@
+#
+# $Id: qax.soc,v 1.90 2013/08/14 08:32:00 ninash Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+#der 0x40 4
+#exit
+
+debug info
+debug appl rcload warn
+debug appl symtab warn
+debug bcm rx,tx,link,attach warn
+debug soc tests warn
+debug soc rx,phy,schan,reg,socmem,dma,mem,miim,mii,intr,counter,ddr warn
+debug soc common err
+debug sys verinet warn
+debug soc physim warn
+
+if $?QAX \
+ 'rcload bcm88470_board.soc'
+
+if $?QUX \
+ 'rcload bcm88270_board.soc'
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+set RCError=off
+debug appl shell warn
+if $?QAX \
+ 'rcload /home/negev/bcm88470_dram_tune.soc'
+if $?QUX \
+ 'rcload /home/negev/bcm88270_dram_tune.soc'
+
+debug appl shell =
+set RCError=on
+
+set RCError=off
+rcload combo28_dram.soc
+set RCError=on
+
+#Set fabric connect mode as FE for multi FAP system
+if $?diag_chassis " \
+ config add fabric_connect_mode.BCM88470=FE"
+
+# Set modid:
+# If diag_chassis is enabled (two line cards), and 'slot' is defined (slot is defined only when
+# working without a management card - set modid to be 'slot'
+# Otherwise (single line card, or management card), set modid to be 0 for unit 0, and 1 for unit != 0
+if $?diag_chassis && $?slot "\
+ local modid $slot" \
+else "\
+ local modid $unit"
+expr $modid==1; if $? "local modid 2"
+
+if $?module_id " \
+ local modid $module_id"
+
+echo "$unit: modid=$modid"
+
+# Set base_modid:
+# Id base_module_id is set, then set base_modid to have base_module_id value.
+# Otherwise, set base_modid to be 0.
+if $?base_module_id " \
+ local base_modid $base_module_id" \
+else " \
+ local base_modid 0"
+
+expr $base_modid > 0
+if $? " \
+ echo '$unit: base_modid=$base_modid'"
+
+if $?diag_chassis " \
+ local nof_devices 2" \
+else "\
+ local nof_devices 1"
+
+if $?n_devices " \
+ local nof_devices $n_devices"
+
+expr $nof_devices > 1
+if $? " \
+ echo '$unit: nof_devices=$nof_devices'"
+
+if $?mng_cpu " \
+ echo '$unit:management card - polling is set on'; \
+ config add polled_irq_mode.BCM88675=1; \
+ config add schan_intr_enable.BCM88675=0; \
+ config add tdma_intr_enable.BCM88675=0; \
+ config add tslam_intr_enable.BCM88675=0; \
+ config add miim_intr_enable.BCM88675=0; "
+
+#Counters unavailable in cmodel
+if $?cmodel " \
+ config add counter_engine_sampling_interval=0;"
+
+#default values in a case which these parameters are not exist
+if !$?diag_cosq_disable "\
+ local diag_cosq_disable 0"
+if !$?warmboot "\
+ local warmboot 0"
+if !$?diag_disable "\
+ local diag_disable 0"
+if !$?diag_no_itmh_prog_mode "\
+ local diag_no_itmh_prog_mode 0"
+if !$?l2_mode "\
+ local l2_mode 0"
+
+#Disable interrupts in cmodel
+if $?cmodel "\
+ local no_intr 1" \
+else "\
+ local no_intr 0"
+
+if $?QUX "\
+ local no_elk 1" \
+else "\
+ local no_elk 0"
+
+INIT_DNX ModID=$modid NofDevices=$nof_devices CosqDisable=$diag_cosq_disable NoAppl=$diag_disable Warmboot=$warmboot NoRxLos=1 NoLinkscan=0 NoElkDevice=$no_elk NoElkAppl=0 NoItmhProgMode=$diag_no_itmh_prog_mode L2Mode=$l2_mode NoIntr=$no_intr
+
+#echo "performing force forward to sysport 1"
+#mod IHP_PINFO_LLR 0 256 DEFAULT_CPU_TRAP_CODE=200 DEFAULT_ACTION_PROFILE_FWD=7
+#mod IHB_FWD_ACT_PROFILE 200 1 FWD_ACT_DESTINATION=0x10001 FWD_ACT_DESTINATION_OVERWRITE=1
+#echo "performing credit flush from NIF to EGQ"
+#m NBIH_TX_EGRESS_CREDITS_DEBUG_PM TX_FLUSH_EGRESS_PORT_0_MLF_0_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_1_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_2_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_3_QMLF_N=1
+echo "qax.soc: Done."
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/rc.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/rc.soc
new file mode 100755
index 0000000..e766e99
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/rc.soc
@@ -0,0 +1,1792 @@
+# $Id: rc.soc,v 1.192 2013/07/17 22:13:43 dkelley Exp $
+# $Copyright: (c) 1998-2001 Broadcom Corp.
+# All Rights Reserved.$
+#
+# Initialization RC (run commands) file
+#
+# These are default commands that are read and executed by default
+# when BCM boots up. Typically this file is called rc.soc and resides
+# in the flash filesystem, NVRAM, or disk.
+#
+# Board Configuration Setting
+#
+# This file uses configuration properties to know on which board
+# it is running. Currently one of following settings must be made:
+#
+# BCM95670K8 config add herc8=1
+# BCM95690K24 config add draco_b2b=1
+# BCM95690K24S config add draco_stk=1
+# BCM95690R24 config add galahad=1
+# BCM95690R24S config add merlin=1
+# BCM95690R48S config add lancelot=1
+# BCM95691K12 config add draco_k12=1
+# White Knight config add white_knight=1 (not shipping)
+# Black Knight config add black_knight=1 (not shipping)
+# BCM95673K2S config add twolynx=1
+# BCM95673R8 config add herculynx=1
+# BCM95673R24S config add lynxalittle=1
+# BCM95673R48S config add lynxalot=1
+# BCM95695P24SX_10 config add guenevere=1
+# BCM95650K24 config add magnum=1 (automatic for 5650L)
+# BCM95675 config add herc8_15=1
+# BCM95650R24 config add tuc24_ref=1
+# BCM95695P48LM config add lm48p=1
+# BCM95695P48LM-10 config add lm48p_B=1
+# BCM956504P48LM-10 config add lm48p_C=1
+# BCM956504P48LM-20 config add lm48p_C=1
+# BCM956504P48LM-50 config add lm48p_D=1
+# BCM956504P48POEREF config add fbpoe=1
+# BCM956504P24REF P0 config add fb24=1
+# BCM956504P24 P0 config add fb24=1
+# BCM956102P48 config add felix48=1
+# BCM953300P24REF config add mirage24=1
+# BCM956800K20C config add bradley_1g=1
+# BCM956700K16 config add humv=1
+# BCM956800K20 config add bradley=1
+# BCM956580K16 config add goldwing=1
+# BCM956314P24REF config add bcm56314p24ref=1
+# BCM956024P48REF config add BCM956024P48REF=1
+# BCM956224P48REF config add BCM956224P48REF=1
+# BCM956224R50T config add BCM956224R50T=1
+# BCM956024R50T config add BCM956024R50T=1
+# BCM56820K24XG config add BCM56820K24XG=1
+# BCM953314R24GS config add BCM953314R24GS=1
+# BCM953314K24 config add BCM953314K24=1
+# BCM956820R24XG config add BCM956820R24XG=1
+# BCM956160R config add bcm956160r=1
+
+if $?BCM56146_A0 \
+ 'local BCM56146 1'
+
+if $?BCM56147_A0 \
+ 'local BCM56147 1'
+
+
+if $?1 "echo rc: arguments not supported; exit"
+if !$?unit "echo rc: no current unit; exit"
+
+echo "rc: unit $unit device $devname"
+local quiet no
+local echo echo
+local rcdone \$rc$unit
+if !"expr $rcdone + 0" "local echo noecho; local quiet yes"
+
+# Set convenience local variables
+
+# simulation related
+#if $?plisim \
+# "local no_bcm 1"
+if $?quickturn || $?plisim \
+ "local simulator 1"
+
+if $?simulator \
+ 'echo -n "Chip init starts at: ";date'
+
+# board related
+if $?galahad \
+ "local draco_b2b 1"
+if $?black_knight || $?white_knight || $?merlin \
+ "local draco_herc4 1"
+
+#if $?QUX_A0 \
+# 'echo blablabla;der 0x40 4 ; exit'
+
+if $?FLAIR_A0 \
+ 'echo blablabla;der 0x40 4 ; exit'
+
+if $?BCM88750_A0 || $?BCM88750_B0 || $?BCM88753_A0 || $?BCM88753_B0 || $?BCM88752_A0 || $?BCM88752_B0 || $?BCM88755_B0 || $?BCM88754_A0 || $?BCM88770_A1 || $?BCM88773_A1 || $?BCM88774_A1 || $?BCM88775_A1 || $?BCM88776_A1 || $?BCM88777_A1 || $?BCM88950_A0 || $?BCM88950_A1 || $?BCM88953_A1 || $?BCM88954_A1 || $?BCM88955_A1 || $?BCM88956_A1 || $?BCM88952_A0 || $?BCM88952_A1 || $?BCM88772_A1 \
+ 'rcload dfe.soc ; exit'
+
+if $?BCM88790_A0 \
+ 'rcload dnxf.soc ; exit'
+
+if $?ARAD_A0 || $?ARAD_B0 || $?ARAD_B1 || $?ARADPLUS_A0 || $?BCM88650_A0 || $?BCM88650_B0 || $?BCM88650_B1 || $?BCM88652_A0 || $?BCM88652_B0 || $?BCM88350_B1 || $?BCM88351_B1 || \
+ $?BCM88450_B1 || $?BCM88451_B1 || $?BCM88550_B1 || $?BCM88551_B1 || $?BCM88552_B1 || $?BCM88651_B1 || $?BCM88654_B1 || $?BCM88660_A0 || $?BCM88360_A0 || $?BCM88361_A0 || $?BCM88363_A0 ||\
+ $?BCM88460_A0 || $?BCM88461_A0 || $?BCM88560_A0 || $?BCM88561_A0 || $?BCM88562_A0 || $?BCM88661_A0 || $?BCM88664_A0 \
+ 'rcload arad.soc ; exit'
+
+if $?BCM83207_A0 \
+ 'rcload samar.soc ; exit'
+if $?BCM83208_A0 \
+ 'rcload sinai.soc ; exit'
+
+if $?QAX_A0 || $?BCM88470_A0 || $?BCM88471_A0 || $?BCM88473_A0 || $?BCM88474_A0 || $?BCM88474H_A0 || $?BCM88476_A0 || $?BCM88477_A0 || \
+ $?QAX_B0 || $?BCM88470_B0 || $?BCM88471_B0 || $?BCM88473_B0 || $?BCM88474_B0 || $?BCM88474H_B0 || $?BCM88476_B0 || $?BCM88477_B0 \
+ 'setenv QAX 1'
+
+if $?QUX_A0 || $?BCM88270_A0 \
+ 'setenv QUX 1'
+
+if $?JERICHO_A0 || $?BCM88670_A0 || $?BCM88671_A0 || $?BCM88671M_A0 || $?BCM88672_A0 || $?BCM88673_A0 || $?BCM88674_A0 || $?BCM88675_A0 || $?BCM88675M_A0 || $?BCM88676_A0 || $?BCM88676M_A0 || $?BCM88677_A0 || $?BCM88678_A0 || $?BCM88679_A0 || \
+ $?JERICHO_A1 || $?BCM88670_A1 || $?BCM88671_A1 || $?BCM88671M_A1 || $?BCM88672_A1 || $?BCM88673_A1 || $?BCM88674_A1 || $?BCM88675_A1 || $?BCM88675M_A1 || $?BCM88676_A1 || $?BCM88676M_A1 || $?BCM88677_A1 || $?BCM88678_A1 || $?BCM88679_A1 || \
+ $?QMX_A0 || $?BCM88370_A0 || $?BCM88371_A0 || $?BCM88371M_A0 || $?BCM88375_A0 || $?BCM88376_A0 || $?BCM88376M_A0 || $?BCM88377_A0 || $?BCM88378_A0 || $?BCM88379_A0 || \
+ $?QMX_A1 || $?BCM88370_A1 || $?BCM88371_A1 || $?BCM88371M_A1 || $?BCM88375_A1 || $?BCM88376_A1 || $?BCM88376M_A1 || $?BCM88377_A1 || $?BCM88378_A1 || $?BCM88379_A1 || \
+ $?JERICHO_B0 || $?BCM88670_B0 || $?BCM88671_B0 || $?BCM88671M_B0 || $?BCM88672_B0 || $?BCM88673_B0 || $?BCM88674_B0 || $?BCM88675_B0 || $?BCM88675M_B0 || $?BCM88676_B0 || $?BCM88676M_B0 || $?BCM88677_B0 || $?BCM88678_B0 || $?BCM88679_B0 || $?BCM88680_A0 || \
+ $?QMX_B0 || $?BCM88370_B0 || $?BCM88371_B0 || $?BCM88371M_B0 || $?BCM88375_B0 || $?BCM88376_B0 || $?BCM88376M_B0 || $?BCM88377_B0 || $?BCM88378_B0 || $?BCM88379_B0 || $?BCM88379_A1 || \
+ $?JERPLUS || $?BCM88680_A0 || $?BCM88681_A0 || $?BCM88682_A0 || $?BCM88683_A0 || $?BCM88380_A0 || $?BCM88381_A0 \
+ 'rcload jer.soc ; exit'
+
+if $?BCM88690_A0 \
+ 'rcload dnx.soc ; exit'
+
+if $?QAX || $?QUX\
+ 'rcload qax.soc ; rcload rpc.soc ; exit'
+
+
+if $?BCM88202_A0 || $?ARDON_A0 || $?BCM88202_A1 || $?ARDON_A1 || $?BCM88202_A2 || $?ARDON_A2\
+ 'rcload atmf.soc ; exit'
+
+if $?ACP \
+ 'exit'
+
+if $?BCM88690_A0\
+ 'exit'
+
+if !"expr $pcidev + 0 == 0x5650" \
+ "local magnum 1"
+if $?drac || $?drac15 \
+ "local drac_any 1"
+if $?lynx || $?lynx15 \
+ "local lynx_any 1"
+if $?tucana || $?magnum \
+ "local tucana_any 1"
+if $?herc || $?herc15 \
+ "local herc_any 1"
+if $?firebolt || $?firebolt2 || $?helix || \
+ $?felix || $?helix15 || $?felix15 || $?raptor || $?raven || $?hawkeye\
+ "local firebolt_any 1"
+if !"expr $pcidev + 0 == 0xb501" \
+ "local firebolt_10x4 1"
+if $?easyrider \
+ "local easyrider_any 1"
+if !"expr $pcidev + 0 == 0xb602" \
+ "local easyrider_1x1 1"
+if $?bradley || $?humv || $?goldwing \
+ "local bradley_any 1"
+if $?drac_any || $?lynx_any || $?tucana_any \
+ "local xgs12_switch 1"
+if $?firebolt_any || $?easyrider_any || $?bradley_any \
+ "local xgs3_switch 1"
+if $?xgs12_switch || $?xgs3_switch \
+ "local xgs_switch 1"
+if $?herc_any \
+ "local xgs_fabric 1"
+if $?xgs_fabric || $?xgs_switch \
+ "local xgs 1"
+if !$?xgs \
+ "local strata 1"
+if $?strata && !$?gsl \
+ "local PBMP_ALL 0x0bffffff"
+if $?strata && $?gsl \
+ "local PBMP_ALL 0x080000ff"
+if $?BCM56214_A0 || $?BCM56014_A0 || $?BCM56215_A0 || \
+ $?BCM56214_A1 || $?BCM56014_A1 || $?BCM56215_A1 && \
+ !$?BCM956024P48REF \
+ "local rap24_ref 1"
+
+if $?BCM5655_A0 || $?BCM5655_B0 \
+ "local tucana_nohg 1"
+
+if $?BCM956024P48REF || $?BCM956224P48REF || $?BCM956024R50T || \
+ $?BCM956224R50T \
+ "local raven_eb_48p 1"
+
+if $?BCM953314R24GS \
+ "local hawkeye_p24 1"
+
+if $?BCM953314K24 \
+ "local hawkeye_k24 1"
+
+if $?firebolt_any && $?lm48p || $?lm48p_D \
+ "config add lmfb48=1"
+
+# Set software's wait for S-Channel response to 3 seconds for QuickTurn
+# (Recommend at least 10 seconds if the ARL is 100% busy with inserts.)
+if $?quickturn "stimeout 3000000"
+if $?plisim "stimeout 60000000"
+
+# Direct phy led programming: 5464 activity led becomes link/activity
+if $?drac_any && $?lancelot || $?lynxalot || $?guenevere \
+ "config add phy_led_ctrl=0x18"
+
+# Shutdown threads if system is already running
+if $?triumph3 \
+ "ibodSync off"
+counter off
+linkscan off
+if $?feature_arl_hashed && !$?simulator \
+ "l2mode off"
+if $?feature_ces && $?BCM56440_A0 \
+ "ces off"
+
+# Test on-chip memory before initializing
+#if !$?simulator "init soc; bist l3 arl cbp"
+init soc
+
+# Initialize miscellaneous chip registers
+init misc
+
+# Initialize external TCAM if necessary
+# NOTE : tcam is initialized during "init misc" unless
+# tcam_reset_toggle = 1 is configured
+if "expr $rcdone + 0" && !"expr $tcam_reset_toggle + 0" \
+ "dispatch attach 0 esw 0"
+if !"expr $tcam_reset_toggle + 0" "muxsel 0; muxsel 0x80"
+if !"expr $tcam_reset_toggle + 0" "init tcam; $echo rc: TCAM initialized"
+
+# Initialize the StrataSwitch MMU registers
+init mmu
+if $?katana2 \
+ kt2config.soc
+
+
+# Uncomment to turn off Single-Bit Error reporting on 5670
+#if $?herc "m mmu_intcntl pp_sbe_en=0"
+
+# Initialize Cell Free Address Pool
+# NOTE: this should NOT be done unless chip is known to have bad CFAP
+# memory entries that need to be mapped out.
+if $?cfap_tests "$echo rc: Initializing CFAP; cfapinit"
+
+$echo rc: MMU initialized
+
+#
+# Load uKernel
+#
+
+# Pick default FW names if not set already by config
+if !$?fw_core_0 \
+ 'local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec; \
+ if $?greyhound || $?hurricane2 || $?hurricane3 "local fw_core_0 ${fw_prefix}_0_ptpfull.srec"; \
+ if $?caladan3 "local fw_core_0 ${fw_prefix}_0.srec"; \
+ if $?helix4 && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?helix4 && $?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec"; \
+ if $?tomahawk && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?tomahawk_plus && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?trident2plus && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ '
+
+if !$?fw_core_1 \
+ 'local fw_core_1 ${fw_prefix}_1_ptpfull.srec; \
+ if $?caladan3 "local fw_core_1 ${fw_prefix}_1_bs.srec"; \
+ '
+
+if !$?fw_core_2 \
+ "local fw_core_2 ${fw_prefix}_2_eth_lmdm.srec"
+
+# Load the firmwares
+if $?feature_cmicm && !$?rcpu_only && !$ihost_mode && !$?feature_iproc \
+ "mcsload 0 ${fw_core_0} InitMCS=true; \
+ mcsload 1 ${fw_core_1};"
+
+if $?hurricane2 \
+ "mcsload 0 ${fw_core_0} InitMCS=true;"
+
+if $?feature_iproc && !$?hurricane2 && !$?hurricane3 && !$?rcpu_only && !$?feature_uc_mhost && !$ihost_mode\
+ "mcsload 0 ${fw_core_0} InitMCS=true TwoStage=true TwoStageAddr=0x60000000;\
+ mcsload 1 ${fw_core_1} TwoStage=true TwoStageAddr=0x6002c000;"
+
+if $?feature_iproc && !$?rcpu_only && $?feature_uc_mhost && $?num_ucs\
+ 'if !"expr $num_ucs > 0" "mcsload 0 ${fw_core_0} InitMCS=true"; \
+ if !"expr $num_ucs > 1" "mcsload 1 ${fw_core_1}"; \
+ if !"expr $num_ucs > 2" "mcsload 2 ${fw_core_2}";'
+
+#
+# Init CLI and BCM API
+#
+# This must be done after the raw register writes to avoid having state
+# clobbered. NOTE: Tables are cleared by "init bcm" below. If
+# table modifications are required, put them after "init bcm". Some
+# registers might also be affected.
+#
+
+if !$?no_bcm \
+ "init bcm; \
+ $echo rc: BCM driver initialized"
+
+if $?no_bcm \
+ "$echo rc: *** NOT initializing BCM driver ***"
+
+if $?no_bcm && $?strata \
+ 'write vtable 0 1 VLAN_TAG=0,PORT_BITMAP=0,UT_PORT_BITMAP=0; \
+ insert vtable VLAN_TAG=1,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ local pv \
+ VLAN_TAG=1,SP_ST=3,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ write ptable 0 32 PTYPE=0; \
+ if !$?gsl "write ptable 0 24 $pv,PTYPE=1"; \
+ if !$?gsl "write ptable 24 2 $pv,PTYPE=2"; \
+ if $?gsl "write ptable 0 8 $pv,PTYPE=2"; \
+ write ptable 27 1 $pv,PTYPE=3; \
+ local pv'
+
+# Turn on mirroring of hardware ARL operations into software ARL table.
+if $?feature_arl_sorted \
+ "arlmode intr_dma; \
+ $echo rc: ARL DMA shadowing enabled"
+
+if $?feature_arl_hashed && !$?simulator && !$?rcpu_only \
+ "l2mode interval=3000000; \
+ $echo rc: L2 Table shadowing enabled"
+
+# If running BCM library, start linkscan task and set port modes
+
+if !$?no_bcm && !$?rcpu_only \
+ "linkscan 250000; \
+ port fe,ge linkscan=on autoneg=on \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port st linkscan=on txpause=false rxpause=false; \
+ port xe,ce linkscan=on autoneg=off \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port hg linkscan=on fullduplex=true txpause=false rxpause=false; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?rcpu_only \
+ "linkscan 250000; \
+ port e linkscan=on; \
+ port st linkscan=on; \
+ port xe linkscan=on; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?shadow \
+ "port il linkscan=on; \
+ $echo rc: Interlaken Port mode initialized"
+
+# Selectively re-enable Auto Negotiation based on config port_force_an_list.
+#if $?port_force_an_list \
+# "port $port_force_an_list autoneg=on"
+
+# No spanning tree is running, so put ports all in the forwarding state
+# stp support not available for shadow device.
+
+if !$?no_bcm && !$?shadow \
+ "stg stp 1 all forward"
+
+# Start counter task unless already started by "init bcm" above.
+if $?plisim "local dma false"
+if !$?plisim "local dma true"
+if $?device_eb_vli "local dma false"
+if $?no_bcm && !$?rcpu_only\
+ "counter Interval=1000 Pbm=all Dma=$dma; \
+ $echo rc: Counter collection enabled"
+if $?rcpu_only \
+ "counter Interval=2000000 Pbm=all Dma=false; \
+ $echo rc: Counter collection enabled"
+
+# Resynchronize the saved values kept by the 'show counter' command.
+if !$?simulator \
+ "counter sync"
+
+# By default, dump data of packets that go to CPU.
+if !$?testinit \
+ "pw report +raw"
+
+# Default LED processor program for various SDKs and reference designs.
+# Source code can be found in $SDK/led/examples.
+
+if !$?p48 "local ledcode '\
+ E0 28 60 7F 67 2F 67 6B 06 7F 80 D2 1A 74 01 12 \
+ 7E 85 05 D2 0F 71 19 52 00 12 7D 85 05 D2 1F 71 \
+ 23 52 00 12 7C 85 05 D2 05 71 2D 52 00 3A 68 32 \
+ 00 97 75 3B 12 A0 FE 7F 02 0A 50 32 01 97 75 47 \
+ 12 BA FE 7F 02 0A 50 12 BA FE 7F 95 75 59 85 12 \
+ A0 FE 7F 95 75 A8 85 77 9A 12 A0 FE 7F 95 75 63 \
+ 85 77 A1 16 7C DA 02 71 A1 77 A8 32 05 97 71 76 \
+ 06 7D D2 01 71 9A 06 7F 67 93 75 9A 32 02 97 71 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 7E D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5605.hex
+
+if $?p48 "local ledcode '\
+ E0 28 60 7F 67 43 67 3C 67 35 67 2F 06 7F 80 D2 \
+ 18 74 01 28 60 7F 67 9B 67 89 67 BF 67 83 67 3C \
+ 67 73 67 68 67 5D 06 7F 80 D2 1A 74 13 3A 70 67 \
+ AD 71 C3 77 BF 32 03 97 71 C3 77 BF 32 05 97 71 \
+ C3 77 BF 12 BA FE 7F 32 01 97 75 4F 02 06 50 32 \
+ 00 97 75 57 02 06 50 95 75 C3 85 77 BF 67 AD 75 \
+ BF 32 04 97 71 C3 77 BF 67 AD 75 BF 32 03 97 71 \
+ C3 77 BF 67 AD 75 BF 32 03 97 71 BF 32 04 97 71 \
+ BF 77 C3 67 B6 71 C3 77 BF 12 A0 FE 7F 32 00 97 \
+ 75 95 02 06 50 95 75 C3 85 77 BF 12 BA FE 7F 32 \
+ 01 97 75 A7 02 06 50 95 75 C3 85 77 BF 06 7F 12 \
+ 80 F8 15 1A 00 57 06 7F 12 80 F8 15 1A 07 57 32 \
+ 0F 87 57 32 0E 87 57'" # p48.hex
+
+if $?herc && !$?black_knight "local ledcode '\
+ 02 01 67 36 29 32 08 D7 87 32 07 D7 87 32 01 D7 \
+ 87 32 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 \
+ 74 24 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 \
+ 87 91 74 2D 3A 28 10 DA 07 75 3E FA 02 57 EA 06 \
+ 57'" # sdk5670.hex
+
+if $?herc && $?black_knight "local ledcode '\
+ 2A 03 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 00 \
+ D7 87 2A 06 32 08 D7 87 32 07 D7 87 32 01 D7 87 \
+ 32 00 D7 87 3A 08'" # knigget.hex
+
+if $?drac_any "local ledcode '\
+ E0 28 60 C3 67 4E 67 8A 06 C3 80 D2 0C 74 01 28 \
+ 60 C3 32 00 D7 87 32 01 D7 87 32 07 D7 87 32 08 \
+ D7 87 32 0F 87 32 0F 87 32 0F 87 32 0F 87 12 C2 \
+ 85 05 D2 0F 71 38 52 00 12 C1 85 05 D2 1F 71 42 \
+ 52 00 12 C0 85 05 D2 05 71 4C 52 00 3A 38 32 00 \
+ 97 75 5A 12 A0 FE C3 02 0A 50 32 01 97 75 66 12 \
+ AD FE C3 02 0A 50 12 AD FE C3 95 75 78 85 12 A0 \
+ FE C3 95 75 C0 85 77 B9 12 A0 FE C3 95 75 82 85 \
+ 77 C7 16 C0 DA 02 71 C7 77 C0 32 05 97 71 9A 32 \
+ 02 97 71 B9 06 C1 D2 01 71 B9 06 C3 67 B2 75 B9 \
+ 32 03 97 71 C0 32 04 97 75 C7 06 C2 D2 07 71 C7 \
+ 77 C0 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5690.hex
+
+if $?draco_k12 "local ledcode '\
+ 02 0B A2 01 28 A2 01 60 C3 67 32 67 6E 06 C3 90 \
+ 75 02 12 C2 85 05 D2 0F 71 1C 52 00 12 C1 85 05 \
+ D2 1F 71 26 52 00 12 C0 85 05 D2 05 71 30 52 00 \
+ 3A 30 32 00 97 75 3E 12 A0 FE C3 02 0A 50 32 01 \
+ 97 75 4A 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 \
+ 5C 85 12 A0 FE C3 95 75 A6 85 77 9F 12 A0 FE C3 \
+ 95 75 66 85 77 AD 16 C0 DA 02 71 AD 77 A6 32 05 \
+ 97 71 7E 32 02 97 71 9F 06 C1 D2 01 71 9F 06 C3 \
+ 67 96 75 9F 32 03 97 71 A6 32 04 97 75 AD 06 C2 \
+ D2 07 71 AD 77 A6 12 80 A2 01 F8 15 1A 00 57 32 \
+ 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 \
+ 32 0E 87 57'" # k12-5690.hex
+
+if $?herc && $?white_knight "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 07 \
+ D7 87 32 01 D7 87 32 00 D7 87 57'" # wk5670.hex
+
+if $?herc && $?merlin "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # merlin5670.hex
+
+if $?herc && $?lancelot "local ledcode '\
+ 2A 05 67 12 2A 06 67 12 2A 03 67 12 2A 04 67 12 \
+ 3A 10 32 08 D7 87 32 00 D7 87 32 01 D7 87 32 07 \
+ D7 87 57'" # lancelot.hex
+
+if $?xgs_fabric && $?guenevere "local ledcode '\
+ 2A 04 67 0A 2A 05 67 0A 3A 04 32 07 D7 87 32 00 \
+ 32 01 B7 D7 87 57'" # guenevere5670.hex
+
+if $?drac_any && $?white_knight "local ledcode '\
+ E0 28 60 C3 67 2f 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # wk5690.hex
+
+if $?drac_any && $?merlin "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # merlin5690.hex
+
+if $?drac_any && $?galahad "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # galahad.hex
+
+if $?drac_any && $?lm "local ledcode '\
+E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+32 0F 87 57 32 0F 87 32 0E 87 57'" # lm5690.hex
+
+if $?twolynx "local ledcode '\
+ 2A 01 67 0A 2A 00 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # twolynx.hex
+
+if $?lynx_any && $?herculynx || $?lynxalot || $?lm || $?guenevere \
+ "local ledcode '\
+12 C0 85 05 D2 03 71 0A 52 00 2A 00 67 10 3A 04 \
+32 08 D7 87 06 C0 D2 01 71 22 32 0F 87 32 0F 87 \
+77 2A 32 00 D7 87 32 01 D7 87 32 07 D7 87 57'" # herculynx.hex
+
+if $?tucana && !$?magnum "local ledcode '\
+ E0 67 23 D2 18 74 01 02 20 67 23 D2 38 74 09 02 \
+ 18 67 23 D2 1C 74 11 E9 02 80 45 80 81 DA 0D 74 \
+ 1A 3A 68 28 60 E3 67 4A 67 36 06 E4 30 87 06 E5 \
+ 30 87 06 E3 80 57 32 00 97 71 45 32 01 97 71 45 \
+ 02 0F 60 E5 57 02 0E 60 E5 57 06 E3 12 A0 F8 15 \
+ 1A 00 75 59 02 0E 60 E4 57 02 0F 60 E4 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC 67 5A 67 9C 06 FA 67 DA 06 FB 67 DA \
+ 06 FC 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0E 74 51 3A 70 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 D7 85 77 D1 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 D4 16 FF DA 02 02 FA 71 D4 77 D7 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 D1 06 FC 67 CA 02 FB 75 \
+ D1 32 02 97 71 D1 32 03 97 71 D7 32 04 97 75 D4 \
+ 06 FD D2 07 02 FB 71 D4 77 D7 12 A0 F8 15 1A 00 \
+ 57 42 00 57 42 01 57 42 02 57 D2 02 74 E3 32 0F \
+ 87 77 E6 32 0E 87 D2 01 74 EE 32 0F 87 57 32 0E \
+ 87 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 75 09 A2 01 60 FC 28 67 37 67 73 \
+ 06 FB 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 3A 70 32 00 97 75 43 12 C0 FE FC \
+ 02 0A 50 32 01 97 75 4F 12 DC FE FC 02 0A 50 12 \
+ DC FE FC 95 75 61 85 12 C0 FE FC 95 75 B0 85 77 \
+ A2 12 C0 FE FC 95 75 6B 85 77 A9 16 FF DA 02 71 \
+ A9 77 B0 32 05 97 71 7E 06 FE D2 01 71 A2 06 FC \
+ 67 9B 75 A2 32 02 97 71 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 FD D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0F 87 32 0F 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57'" # magnum_sdk.hex
+
+if $?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 71 10 60 FC 28 67 D0 67 C0 77 19 \
+ A2 01 60 FC 28 67 40 67 7C 06 FB 80 D2 1C 74 01 \
+ 12 FD 85 05 D2 0F 71 2A 52 00 12 FE 85 05 D2 1F \
+ 71 34 52 00 12 FF 85 05 D2 05 71 3E 52 00 3A 68 \
+ 32 00 97 75 4C 12 C0 FE FC 02 0A 50 32 01 97 75 \
+ 58 12 DC FE FC 02 0A 50 12 DC FE FC 95 75 6A 85 \
+ 12 C0 FE FC 95 75 B9 85 77 AB 12 C0 FE FC 95 75 \
+ 74 85 77 B2 16 FF DA 02 71 B2 77 B9 32 05 97 71 \
+ 87 06 FE D2 01 71 AB 06 FC 67 A4 75 AB 32 02 97 \
+ 71 AB 32 03 97 71 B9 32 04 97 75 B2 06 FD D2 07 \
+ 71 B2 77 B9 12 A0 F8 15 1A 00 57 32 0F 87 32 0F \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 \
+ 02 0E 32 00 97 71 CD 32 01 97 71 CD 80 30 87 57 \
+ 06 FC 12 A0 F8 15 1A 00 02 0F 75 DD 90 30 87 57'" # magnum.hex
+
+if $?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC D2 18 71 0E 67 E9 67 D9 77 1A 67 5A \
+ 67 9C 06 FA 67 D0 06 FB 67 D0 06 FC 80 D2 1C 74 \
+ 01 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0D 74 51 3A 68 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 CD 85 77 C7 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 CA 16 FF DA 02 02 FA 71 CA 77 CD 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 C7 06 FC 67 C0 02 FB 75 \
+ C7 32 02 97 71 C7 32 03 97 71 CD 32 04 97 75 CA \
+ 12 A0 F8 15 1A 00 57 42 FF 57 42 FE 57 42 EF 57 \
+ 30 87 98 98 98 98 30 87 57 02 0E 32 00 97 71 E6 \
+ 32 01 97 71 E6 80 30 87 57 06 FC 12 A0 F8 15 1A \
+ 00 02 0F 75 F6 90 30 87 57'" # tuc24_ref.hex
+
+if $?herc8_15 "local ledcode '\
+ 02 01 28 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 \
+ 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 74 22 \
+ 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 87 91 \
+ 74 2B 3A 28'" # sdk5675.hex
+
+if $?drac_any && $?lm "local ledcode '\
+ E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+ 00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+ 75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+ C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+ A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+ C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+ 71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+ 71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57 00 00 00 00 00'" # lm5690.hex
+
+if $?drac_any && $?lm48p "local ledcode '\
+ E0 28 60 C3 67 7C 06 C3 80 28 60 C3 67 7C 67 40 \
+ 06 C3 90 28 60 C3 67 40 06 C3 80 80 D2 0C 74 01 \
+ 12 C2 85 05 D2 0F 71 2A 52 00 12 C1 85 05 D2 1F \
+ 71 34 52 00 12 C0 85 05 D2 05 71 3E 52 00 3A 30 \
+ 32 00 97 75 4C 12 A0 FE C3 02 0A 50 32 01 97 75 \
+ 58 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 6A 85 \
+ 12 A0 FE C3 95 75 B9 85 77 AB 12 A0 FE C3 95 75 \
+ 74 85 77 B2 16 C0 DA 02 71 B2 77 B9 32 05 97 71 \
+ 8C 32 02 97 71 AB 06 C1 D2 01 71 AB 06 C3 67 A4 \
+ 75 AB 32 03 97 71 B9 32 04 97 75 B2 06 C2 D2 07 \
+ 71 B2 77 B9 12 80 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695.hex
+
+if $?drac_any && $?lm48p_B "local ledcode '\
+ E0 28 60 C3 67 79 06 C3 67 3D 06 C3 80 28 60 C3 \
+ 67 3D 06 C3 67 79 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 27 52 00 12 C1 85 05 D2 1F 71 31 52 \
+ 00 12 C0 85 05 D2 05 71 3B 52 00 3A 30 32 00 97 \
+ 75 49 12 A0 FE C3 02 0A 50 32 01 97 75 55 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 67 85 12 A0 FE \
+ C3 95 75 B6 85 77 A8 12 A0 FE C3 95 75 71 85 77 \
+ AF 16 C0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 C1 D2 01 71 A8 06 C3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 C2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695_10.hex
+
+if $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 55 67 91 06 E3 80 28 60 E3 67 91 \
+ 67 55 06 E3 80 D2 18 74 01 28 60 E3 67 B9 75 26 \
+ 67 CE 67 55 77 2E 32 0E 87 32 08 87 67 C0 06 E3 \
+ 80 D2 1C 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 3A 70 32 00 97 75 61 12 A0 FE E3 02 0A \
+ 50 32 01 97 75 6D 12 BC FE E3 02 0A 50 12 BC FE \
+ E3 95 75 7F 85 12 A0 FE E3 95 75 CE 85 77 C0 12 \
+ A0 FE E3 95 75 89 85 77 C7 16 E0 DA 02 71 C7 77 \
+ CE 32 05 97 71 A1 32 02 97 71 C0 06 E1 D2 01 71 \
+ C0 06 E3 67 B9 75 C0 32 03 97 71 CE 32 04 97 75 \
+ C7 06 E2 D2 07 71 C7 77 CE 12 80 F8 15 1A 00 57 \
+ 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F \
+ 87 32 0E 87 57'" # sdk56504.hex
+
+#Led program for new rev of FB SDK and Ref design
+if $?firebolt_any && !$?fb24 "local ledcode '\
+ E0 28 60 E3 67 4B 67 87 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AF 75 1C 67 C4 67 4B 77 24 32 0E 87 32 \
+ 08 87 67 B6 06 E3 80 D2 1C 74 0F 12 E2 85 05 D2 \
+ 0F 71 35 52 00 12 E1 85 05 D2 1F 71 3F 52 00 12 \
+ E0 85 05 D2 05 71 49 52 00 3A 70 32 00 97 75 57 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 63 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 75 85 12 A0 FE E3 95 \
+ 75 C4 85 77 B6 12 A0 FE E3 95 75 7F 85 77 BD 16 \
+ E0 DA 02 71 BD 77 C4 32 05 97 71 97 32 02 97 71 \
+ B6 06 E1 D2 01 71 B6 06 E3 67 AF 75 B6 32 03 97 \
+ 71 C4 32 04 97 75 BD 06 E2 D2 07 71 BD 77 C4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56504ref.hex
+
+#Override Default Firebolt LED program for Line Module
+if $?lm && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 79 06 E3 67 3D 06 E3 80 28 60 E3 \
+ 67 3D 06 E3 67 79 06 E3 80 D2 18 74 01 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 60 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B6 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AF 16 E0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 E2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p56504.hex
+
+#Override Default Firebolt LED program for Line Module -50 version
+if $?lm && $?lm48p_D && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 6D 06 E3 67 31 06 E3 80 D2 18 74 \
+ 01 12 E2 85 05 D2 0F 71 1B 52 00 12 E1 85 05 D2 \
+ 1F 71 25 52 00 12 E0 85 05 D2 05 71 2F 52 00 3A \
+ 60 32 00 97 75 3D 12 A0 FE E3 02 0A 50 32 01 97 \
+ 75 49 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 5B \
+ 85 12 A0 FE E3 95 75 AA 85 77 9C 12 A0 FE E3 95 \
+ 75 65 85 77 A3 16 E0 DA 02 71 A3 77 AA 32 05 97 \
+ 71 7D 32 02 97 71 9C 06 E1 D2 01 71 9C 06 E3 67 \
+ 95 75 9C 32 03 97 71 AA 32 04 97 75 A3 06 E2 D2 \
+ 07 71 A3 77 AA 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # lm48p56504_50.hex
+
+if $?lm && $?firebolt_10x4 "local ledcode '\
+ 02 18 28 32 07 67 1E 75 0A D7 87 32 01 D7 87 32 \
+ 00 D7 87 32 08 D7 87 80 D2 1C 74 02 3A 0C 12 80 \
+ F8 15 1A 00 57 '" # lm12pcx456501.hex
+
+if $?fbpoe && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 85 67 49 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AD 75 1A 67 C2 77 20 32 0E 87 32 08 87 \
+ 67 49 06 E3 80 D2 1A 74 0F 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 32 00 97 75 55 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 61 12 BA FE E3 02 0A \
+ 50 12 BA FE E3 95 75 73 85 12 A0 FE E3 95 75 C2 \
+ 85 77 B4 12 A0 FE E3 95 75 7D 85 77 BB 16 E0 DA \
+ 02 71 BB 77 C2 32 05 97 71 95 32 02 97 71 B4 06 \
+ E1 D2 01 71 B4 06 E3 67 AD 75 B4 32 03 97 71 C2 \
+ 32 04 97 75 BB 06 E2 D2 07 71 BB 77 C2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # poe48p56504.hex
+
+#Override Default Firebolt LED program for felix
+if $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0E 87 32 0F 87 57'" # sdk56102.hex
+
+#Override Default Felix LED program for felix48
+if $?felix48 && $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # felix48.hex
+
+if $?easyrider_any "local ledcode '\
+ E0 28 60 E3 67 59 67 95 06 E3 80 28 60 E3 67 95 \
+ 67 59 06 E3 80 D2 0C 74 01 28 60 E3 67 BD 75 26 \
+ 67 D2 67 59 77 2E 32 0E 87 32 08 87 67 C4 06 E3 \
+ 80 D2 0D 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 67 C4 67 C4 3A 38 32 00 97 75 65 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 71 12 AD FE E3 02 0A \
+ 50 12 AD FE E3 95 75 83 85 12 A0 FE E3 95 75 D2 \
+ 85 77 C4 12 A0 FE E3 95 75 8D 85 77 CB 16 E0 DA \
+ 02 71 CB 77 D2 32 05 97 71 A5 32 02 97 71 C4 06 \
+ E1 D2 01 71 C4 06 E3 67 BD 75 C4 32 03 97 71 D2 \
+ 32 04 97 75 CB 06 E2 D2 07 71 CB 77 D2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # sdk56601.hex
+
+#Override Default Easyrider LED program for 56602
+if $?easyrider_1x1 "local ledcode '\
+ E0 60 E1 67 7C 67 7C 06 E1 80 D2 0C 74 01 02 0C \
+ 28 60 E1 67 75 75 1D 67 8A 67 39 77 25 32 0E 87 \
+ 32 08 87 67 7C 06 E1 D2 00 02 00 74 10 12 E0 85 \
+ 05 D2 05 71 37 52 00 3A 38 32 00 97 75 45 12 A0 \
+ FE E1 02 0A 50 32 01 97 75 51 12 AD FE E1 02 0A \
+ 50 12 AD FE E1 95 75 63 85 12 A0 FE E1 95 75 8A \
+ 85 77 7C 12 A0 FE E1 95 75 6D 85 77 83 16 E0 DA \
+ 02 71 83 77 8A 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # sdk56602.hex
+
+#Override Default LED program for 53300
+if $?mirage24 "local ledcode '\
+ E0 28 60 E3 67 6B 67 2F 06 E3 80 D2 18 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A2 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 9E 16 E0 DA 02 71 9E 77 A2 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A2 32 04 97 75 9E 06 E2 D2 07 71 \
+ 9E 77 A2 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E \
+ 87 57 32 0E 87 57'" # sdk53300.hex
+
+#Override Default LED program for 56314
+if $?bcm56314p24ref "local ledcode '\
+ E0 28 60 E3 67 79 67 3D 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 79 67 A8 06 E3 80 D2 1C 74 0F 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 38 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B0 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AC 16 E0 DA 02 71 AC 77 B0 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B0 32 04 97 75 AC 06 E2 D2 07 71 AC 77 \
+ B0 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ 32 0E 87 57'" # bcm956314p24ref.hex
+
+if $?bradley "local ledcode '\
+ E0 28 60 F2 67 1B 06 F2 80 D2 14 74 01 86 F3 12 \
+ F0 85 05 D2 05 71 19 52 00 3A 28 32 00 97 75 27 \
+ 12 A8 FE F2 02 0A 50 32 01 97 75 33 12 BC FE F2 \
+ 02 0A 50 12 BC FE F2 95 75 45 85 12 A8 FE F2 95 \
+ 75 91 85 77 57 12 A8 FE F2 95 75 4F 85 77 8A 16 \
+ F0 DA 02 71 8A 77 91 06 F2 12 94 F8 15 02 02 C1 \
+ 74 6E 02 04 C1 74 6E 02 08 C1 74 6E 77 74 C6 F3 \
+ 74 91 77 8A 06 F2 67 7C 75 83 77 91 12 80 F8 15 \
+ 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 \
+ 57 32 0F 87 32 0E 87 57'" # sdk56800.hex
+
+if $?humv "local ledcode '\
+ E0 28 60 F2 67 21 06 F2 80 D2 08 74 0F F2 02 D2 \
+ 12 74 01 86 F3 12 F0 85 05 D2 05 71 1F 52 00 3A \
+ 20 32 00 97 75 2D 12 A8 FE F2 02 0A 50 32 01 97 \
+ 75 39 12 BA FE F2 02 0A 50 12 BA FE F2 95 75 4B \
+ 85 12 A8 FE F2 95 75 97 85 77 5D 12 A8 FE F2 95 \
+ 75 55 85 77 90 16 F0 DA 02 71 90 77 97 06 F2 12 \
+ 94 F8 15 02 02 C1 74 74 02 04 C1 74 74 02 08 C1 \
+ 74 74 77 7A C6 F3 74 97 77 90 06 F2 67 82 75 89 \
+ 77 97 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56700.hex
+
+if $?bradley_1g "local ledcode '\
+ E0 28 60 E3 67 2F 67 6B 06 E3 80 D2 14 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 50 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 B4 FE E3 02 0A 50 12 B4 FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A8 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 A1 16 E0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 E2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 '" # sdk56800c.hex
+
+if $?goldwing "local ledcode '\
+ E0 28 60 F3 D2 10 75 0E 67 3B 67 94 77 12 67 94 \
+ 67 3B 06 F3 80 D2 14 74 01 86 F4 12 F2 85 05 D2 \
+ 0F 71 25 52 00 12 F1 85 05 D2 1F 71 2F 52 00 12 \
+ F0 85 05 D2 05 71 39 52 00 3A 50 32 00 97 75 47 \
+ 12 A8 FE F3 02 0A 50 32 01 97 75 53 12 BC FE F3 \
+ 02 0A 50 12 BC FE F3 95 75 65 85 12 A8 FE F3 95 \
+ 75 C0 85 77 77 12 A8 FE F3 95 75 6F 85 77 B9 16 \
+ F0 DA 02 71 B9 77 C0 06 F3 12 94 F8 15 02 02 C1 \
+ 74 8E 02 04 C1 74 8E 02 08 C1 74 8E 77 B2 C6 F4 \
+ 74 C0 77 B9 06 F3 67 AB 75 B2 32 04 75 B2 32 03 \
+ 97 71 C0 06 F2 D2 07 71 B9 77 C0 12 80 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 '" # sdk56580.hex
+
+if $?humv && $?lm "local ledcode '\
+ 02 04 28 D2 08 74 0A F2 02 28 32 07 67 29 75 11 \
+ D7 87 60 E4 67 30 06 E4 60 E4 67 4C 06 E4 32 08 \
+ D7 87 80 D2 12 74 02 3A 30 12 80 F8 15 1A 00 57 \
+ 06 E4 12 94 F8 15 02 10 C1 70 42 12 D2 FE E4 02 \
+ 0A 50 12 D2 FE E4 95 75 6D 85 77 68 06 E4 12 94 \
+ F8 15 02 20 C1 70 5E 12 C0 FE E4 02 0A 50 12 C0 \
+ FE E4 95 75 6D 85 77 68 32 0E D7 87 57 32 0F D7 \
+ 87 57 '" # lm12p56802.hex
+
+
+if $?raptor "local ledcode '\
+ 02 06 28 60 FF 67 64 67 93 06 FF 80 D2 36 74 02 \
+ 02 04 28 60 FF 67 BB 75 1E 32 0E 87 77 21 32 0F \
+ 87 67 7D 06 FF 80 D2 06 74 12 02 01 28 60 FF 67 \
+ BB 75 38 32 0E 87 77 3B 32 0F 87 67 7D 06 FF 80 \
+ D2 03 74 2C 12 FE 85 05 D2 0F 71 4E 52 00 12 FD \
+ 85 05 D2 1F 71 58 52 00 12 FC 85 05 D2 05 71 62 \
+ 52 00 3A C8 32 01 97 75 76 32 00 97 75 C9 16 FC \
+ DA 02 71 C9 77 D0 32 00 97 75 C2 77 D0 32 00 97 \
+ 75 86 32 0E 87 57 32 01 97 75 8F 32 0E 87 57 32 \
+ 0F 87 57 32 05 97 71 A3 32 02 97 71 C2 06 FD D2 \
+ 01 71 C2 06 FF 67 BB 75 C2 32 03 97 71 D0 32 04 \
+ 97 75 C9 06 FE D2 07 71 C9 77 D0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" # sdk56018.hex
+
+if $?raptor && $?rap24_ref "local ledcode '\
+ 02 06 60 E1 67 48 67 31 06 E1 80 D2 1E 71 02 02 \
+ 05 60 E1 67 48 67 31 06 E1 90 D2 03 74 11 02 02 \
+ 60 E1 67 48 67 31 06 E1 90 D2 00 74 20 86 E0 3A \
+ 38 06 E1 67 50 75 57 28 32 00 32 01 B7 97 75 57 \
+ 16 E0 CA 05 74 5B 77 57 06 E1 67 50 75 57 77 5B \
+ 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00'" # sdk56214.hex
+
+if $?raven_eb_48p "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 71 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024p48ref.hex
+
+if $?BCM956024R50T "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 75 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024r50t.hex
+
+if $?scorpion || $?conqueror "local ledcode '\
+ 02 18 28 60 E1 67 12 06 E1 90 D2 00 74 02 86 E0 \
+ 3A 18 67 2D 75 34 28 32 00 32 01 B7 97 75 38 16 \
+ E0 CA 05 74 38 77 34 67 2D 75 34 77 38 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 \
+ 00 00 00'" #sdk56820.hex
+
+if $?scorpion && $?BCM956820R24XG "local ledcode '\
+ 02 01 28 67 D0 02 02 28 67 D6 67 D0 02 01 28 67 \
+ D6 02 04 28 67 D0 02 03 28 67 D6 67 D0 02 04 28 \
+ 67 D6 02 05 28 67 D0 02 06 28 67 D6 67 D0 02 05 \
+ 28 67 D6 02 07 28 67 D0 02 08 28 67 D6 67 D0 02 \
+ 07 28 67 D6 02 09 28 67 D0 02 0A 28 67 D6 67 D0 \
+ 02 09 28 67 D6 02 0C 28 67 D0 02 0B 28 67 D6 67 \
+ D0 02 0C 28 67 D6 02 0D 28 67 D0 02 0E 28 67 D6 \
+ 67 D0 02 0D 28 67 D6 02 0F 28 67 D0 02 10 28 67 \
+ D6 67 D0 02 0F 28 67 D6 02 11 28 67 D0 02 12 28 \
+ 67 D6 67 D0 02 11 28 67 D6 02 14 28 67 D0 02 13 \
+ 28 67 D6 67 D0 02 14 28 67 D6 02 15 28 67 D0 02 \
+ 16 28 67 D6 67 D0 02 15 28 67 D6 02 17 28 67 D0 \
+ 02 18 28 67 D6 67 D0 02 17 28 67 D6 86 E0 3A 30 \
+ 67 F1 75 F8 77 FC 67 F1 75 F8 28 32 00 32 01 B7 \
+ 97 75 F8 16 E0 CA 05 74 FC 77 F8 67 F1 75 F8 77 \
+ FC 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ '" #bcm956820r24xg.hex
+
+if $?valkyrie "local ledcode '\
+ 02 02 67 A9 67 94 02 03 67 A9 67 94 02 05 67 A9 \
+ 67 94 02 04 67 A9 67 94 02 06 67 A9 67 94 02 07 \
+ 67 A9 67 94 02 12 67 A9 67 94 02 13 67 A9 67 94 \
+ 02 0E 67 A9 67 94 02 0F 67 A9 67 94 02 11 67 A9 \
+ 67 94 02 10 67 A9 67 94 02 1A 67 A9 67 94 02 20 \
+ 67 A9 67 94 02 21 67 A9 67 94 02 22 67 A9 67 94 \
+ 02 23 67 A9 67 94 02 24 67 A9 67 94 02 2F 67 A9 \
+ 67 94 02 2E 67 A9 67 94 02 1B 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56680.hex
+
+if $?valkyrie2 "local ledcode '\
+ 02 1E 67 A9 67 94 02 1F 67 A9 67 94 02 21 67 A9 \
+ 67 94 02 20 67 A9 67 94 02 22 67 A9 67 94 02 23 \
+ 67 A9 67 94 02 24 67 A9 67 94 02 25 67 A9 67 94 \
+ 02 26 67 A9 67 94 02 27 67 A9 67 94 02 29 67 A9 \
+ 67 94 02 28 67 A9 67 94 02 2A 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 02 2E 67 A9 67 94 02 2F 67 A9 67 94 02 31 67 A9 \
+ 67 94 02 30 67 A9 67 94 02 32 67 A9 67 94 02 33 \
+ 67 A9 67 94 02 34 67 A9 67 94 02 35 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56685.hex
+
+if $?hawkeye_p24 "local ledcode '\
+ 02 01 28 60 E3 67 43 67 1C 06 E3 80 D2 19 74 02 \
+ 12 E0 85 05 D2 03 71 1A 52 00 3A 60 32 00 32 01 \
+ B7 97 75 2B 12 E4 FE E3 02 01 50 12 E4 FE E3 95 \
+ 75 3B 85 06 E3 67 55 75 6A 77 5C 16 E0 DA 01 71 \
+ 6A 77 5C 06 E3 67 55 75 6A 32 03 97 71 5C 32 04 \
+ 97 75 6A 77 63 12 A0 F8 15 1A 00 57 32 0E 87 32 \
+ 0F 87 57 32 0F 87 32 0E 87 57 32 0F 87 32 0F 87 \
+ 57'" #bcm953314p24ref.hex
+
+if $?hawkeye_k24 "local ledcode '\
+ 02 01 28 60 E1 67 3D 67 1C 06 E1 80 D2 19 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 30 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 50 16 E0 DA 02 71 4C 77 50 06 E1 67 \
+ 45 75 50 77 4C 12 A0 F8 15 1A 00 57 32 0E 87 57 \
+ 32 0F 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #bcm953314k24.hex
+
+if !"expr $pcidev + 0 == 0xb624" "local ledcode '\
+ 02 1C 28 67 18 02 1D 28 67 18 02 1E 28 67 18 02 \
+ 1F 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56624.hex
+
+if !"expr $pcidev + 0 == 0xb626" "local ledcode '\
+ 02 1A 28 67 22 02 1B 28 67 22 02 1C 28 67 22 02 \
+ 1D 28 67 22 02 1E 28 67 22 02 1F 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56626.hex
+
+if !"expr $pcidev + 0 == 0xb628" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56628.hex
+
+if !"expr $pcidev + 0 == 0xb629" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56629.hex
+
+if !"expr $pcidev + 0 == 0xb634" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb630" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb636" "local ledcode '\
+ 02 2A 28 67 22 02 32 28 67 22 02 1A 28 67 22 02 \
+ 1B 28 67 22 02 1C 28 67 22 02 1D 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56636.hex
+
+if !"expr $pcidev + 0 == 0xb638" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56638.hex
+
+if !"expr $pcidev + 0 == 0xb639" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56639.hex
+
+if !"expr $pcidev + 0 == 0xb334" "local ledcode '\
+ 02 02 28 60 E1 67 3D 67 1C 06 E1 80 D2 1E 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 38 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 4C 16 E0 DA 02 71 50 77 4C 06 E1 67 \
+ 45 75 4C 77 50 12 A0 F8 15 1A 00 57 32 0F 87 57 \
+ 32 0E 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #sdk56334.hex
+
+if $?apollo "local ledcode '\
+ 02 1E 28 60 E0 67 58 67 73 06 E0 80 28 60 E0 67 \
+ 73 67 58 06 E0 80 D2 36 74 02 02 1A 28 60 E0 67 \
+ 9B 75 29 67 B0 67 58 77 31 32 0E 87 32 08 87 67 \
+ A2 06 E0 80 D2 1E 74 1C 12 E2 85 05 D2 0F 71 42 \
+ 52 00 12 E1 85 05 D2 1F 71 4C 52 00 12 E3 85 05 \
+ D2 05 71 56 52 00 3A 70 32 00 97 75 64 32 01 97 \
+ 71 6B 77 B0 32 01 97 71 A9 77 A2 16 E3 DA 02 71 \
+ A9 77 B0 32 05 97 75 83 32 02 97 71 A2 06 E1 D2 \
+ 01 71 A2 06 E0 67 9B 75 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 E2 D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" #sdk56524.hex
+
+if $?tomahawk || $?tomahawk_plus "local ledcode '\
+ 02 00 28 60 E1 67 25 67 14 06 E1 80 D2 40 74 02 \
+ 86 E0 3A FC 28 32 00 32 01 B7 97 75 37 16 E0 CA \
+ 05 74 3E 77 37 67 2B 75 37 77 45 12 A0 F8 15 1A \
+ 00 57 28 32 07 97 57 32 0E 87 32 0E 87 57 32 0F \
+ 87 32 0E 87 57 32 0E 87 32 0F 87 57 00 00 00 00'" #sdk56960.hex
+
+if $?trident2plus "local ledcode '\
+ 02 01 28 60 E1 67 31 67 20 06 E1 80 D2 31 74 02 \
+ 86 E0 3A C0 67 37 75 1C 67 51 77 20 67 43 77 43 \
+ 28 32 00 32 01 B7 97 75 43 16 E0 CA 05 74 4A 77 \
+ 43 67 37 75 43 77 51 12 A0 F8 15 1A 00 57 28 32 \
+ 07 97 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00'" #sdk56860.hex
+
+if $?apache "local ledcode '\
+ 02 00 67 24 67 0F 80 D2 24 74 02 86 E0 3A F8 67 \
+ 34 75 16 77 1D 57 67 3C 75 62 77 44 57 67 3C 75 \
+ 4E 77 58 57 67 2C 75 62 77 70 07 57 07 12 A0 F8 \
+ 15 1A 00 57 07 12 A0 F8 15 1A 04 57 07 12 A0 F8 \
+ 15 1A 05 57 16 E0 CA 1E 74 69 77 62 07 57 16 E0 \
+ CA 1E 74 70 77 62 07 57 16 E0 CA 1E 74 69 77 70 \
+ 07 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00 00'" #sdk56560.hex
+
+if $?generic8led "local ledcode '\
+ 06 E1 D2 40 71 11 E0 60 E1 16 E3 DA 01 71 15 60 \
+ E3 67 5D 75 2B 12 01 61 E3 67 71 28 67 32 86 E0 \
+ 16 E2 81 61 E2 DA 1E 75 2B 3A 08 E9 61 E2 86 E1 \
+ 77 00 67 5D 75 38 77 3C 67 64 77 64 67 41 67 4F \
+ 57 28 32 01 97 75 64 16 E0 CA 05 74 68 77 64 28 \
+ 32 00 97 75 64 16 E0 CA 05 74 68 77 64 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 09 75 64 77 \
+ 68 12 05 67 6C 12 04 67 6C 12 03 67 6C 12 02 67 \
+ 6C 12 01 67 6C 12 00 67 6C 57 00 00 00 00 00 00'" #generic8led.hex
+
+# Download LED code into LED processor and enable (if applicable).
+
+if $?feature_led_proc && $?ledcode && !$?simulator \
+ "led prog $ledcode; \
+ led auto on; led start"
+
+# Setup Greyhound LED processor
+if $?greyhound \
+ "rcload gh_ledup.soc"
+
+# Setup Hurricane3 LED processor
+if $?hurricane3 \
+ "rcload hr3_led.soc"
+
+# Setup Tomahawk LED processor
+if $?tomahawk && !$?simulator \
+ "led 1 prog $ledcode; \
+ led 1 auto on; led 1 start; \
+ led 2 prog $ledcode; \
+ led 2 auto on; led 2 start"
+
+# Setup Tomahawk+ LED processor
+if $?tomahawk_plus && !$?simulator \
+ "led 1 prog $ledcode; \
+ led 1 auto on; led 1 start; \
+ led 2 prog $ledcode; \
+ led 2 auto on; led 2 start"
+
+# If loading multiple rc.soc, upon loading the last unit, restart
+# all LED processors so any common blinking is in sync.
+
+if !"expr $?feature_led_proc && !$?simulator && $unit == $units - 1" \
+ "*:led stop; *:led start"
+
+# Run counter DMA task 4 times per second to achieve better
+# ctr_xaui_activity.
+if $?bradley_any \
+ "ctr interval=250000"
+
+# Initialize Hercules UC modid 0 entry to point to the CPU
+if $?herc_any \
+ "w uc 0 1 1"
+
+# Additional configuration for 48-port in Stacking mode.
+# On the 48-port platform, rc.soc is run twice; once on unit 0 and
+# then once on unit 1. The turbo port on unit N is geN.
+# All turbo port traffic must be tagged; see vlan add below.
+# See $SDK/doc/48-port.txt for more information including how
+# to configure IPG values for line rate operation.
+
+if $?p48 && $?unit0 \
+ "local turbo_port 0; local my_modid 1;"
+
+if $?p48 && $?unit1 \
+ "local turbo_port 1; local my_modid 2;"
+
+if $?p48 \
+ "m config st_is_mirr=0 st_module=1 st_mcnt=1 st_simplex=0 st_link=0; \
+ m config.g$turbo_port st_link=1; \
+ m gmacc2.ge$turbo_port ipgt=8 mclkfq=1; \
+ m fe_maxf maxfr=1560; \
+ m maxfr maxfr=1568; \
+ m config2 my_modid=$my_modid; \
+ port ge$turbo_port speed=2500; \
+ vlan add 1 pbm=ge$turbo_port ubm=none"
+
+if !$?no_bcm && $?drac_any \
+ "m modport_7_0 port_for_mod1=0xc"
+if !$?no_bcm && $?lynx_any \
+ "m modport_7_0 port_for_mod1=0x1"
+if !$?no_bcm && $?tucana \
+ "stkmode modid=0;"
+if !$?no_bcm && $?tucana && !$?magnum && !$?tucana_nohg \
+ "m modport_7_0 port_for_mod2=0x38; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=0 port_for_mod2=0x38; \
+ stkmode modid=0"
+if !$?no_bcm && $?xgs_switch && !$?rcpu_only\
+ "stkmode modid=0; \
+ s CMIC_COS_CTRL_RX CH0_COS_BMP=0,CH1_COS_BMP=0xff, \
+ CH2_COS_BMP=0,CH3_COS_BMP=0"
+
+# Back-to-back Draco setup.
+
+# Draco chips must run at 127MHz. Some older versions
+# are not set to this frequency.
+
+if $?draco_stk && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+# Applies to SDK Baseboard with either internal or external Higigs,
+# as well as the Galahad reference design.
+
+if $?draco_b2b && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if !$?simulator && $?draco_b2b && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_b2b && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Merlin, White Knight, Black Knight setup.
+# Draco unit 1 is on Herc port 8
+# Draco unit 2 is on Herc port 1
+
+if $?draco_herc4 && $?unit0 \
+ "w uc.hpic7 0 1 0x0; \
+ w uc.hpic7 1 1 0x2; \
+ w uc.hpic0 0 1 0x100; \
+ w uc.hpic0 1 1 0x0"
+
+if !$?simulator && $?draco_herc4 && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_herc4 && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if $?draco_herc4 && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Lancelot setup
+# (enabled by adding the property "lancelot=1")
+# Notes:
+# Draco unit 1 is on Herc port 7
+# Draco unit 2 is on Herc port 8
+# Draco unit 3 is on Herc port 1
+# Draco unit 4 is on Herc port 2
+
+if $?lancelot && $?unit0 \
+ "w uc.hpic6 0 1 0x0; \
+ w uc.hpic6 1 1 0x100; \
+ w uc.hpic6 2 1 0x2; \
+ w uc.hpic6 3 1 0x4; \
+ w uc.hpic7 0 1 0x80; \
+ w uc.hpic7 1 1 0x0; \
+ w uc.hpic7 2 1 0x2; \
+ w uc.hpic7 3 1 0x4; \
+ w uc.hpic0 0 1 0x80; \
+ w uc.hpic0 1 1 0x100; \
+ w uc.hpic0 2 1 0x0; \
+ w uc.hpic0 3 1 0x4; \
+ w uc.hpic1 0 1 0x80; \
+ w uc.hpic1 1 1 0x100; \
+ w uc.hpic1 2 1 0x2; \
+ w uc.hpic1 3 1 0x0"
+
+if !$?simulator && $?lancelot && $?unit0 \
+ "i2c probe quiet; bb clock Draco_Core 127"
+
+if $?lancelot && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit3 \
+ "stkmode modid=2; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12"
+
+if $?lancelot && $?unit4 \
+ "stkmode modid=3; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0"
+
+# Lynx SDK (TwoLynx) setup
+# (enabled by adding the property "twolynx=1")
+
+if $?twolynx && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ "
+
+if $?twolynx && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ "
+# HercuLynx setup
+# (enabled by adding the property "herculynx=1")
+# Notes:
+# Lynx unit 1 is on Herc port 1
+# Lynx unit 2 is on Herc port 2
+# Lynx unit 3 is on Herc port 3
+# Lynx unit 4 is on Herc port 4
+# Lynx unit 5 is on Herc port 5
+# Lynx unit 6 is on Herc port 6
+# Lynx unit 7 is on Herc port 7
+# Lynx unit 8 is on Herc port 8
+
+if $?herculynx && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x008; \
+ w uc.hpic0 3 1 0x010; \
+ w uc.hpic0 4 1 0x020; \
+ w uc.hpic0 5 1 0x040; \
+ w uc.hpic0 6 1 0x080; \
+ w uc.hpic0 7 1 0x100; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x008; \
+ w uc.hpic1 3 1 0x010; \
+ w uc.hpic1 4 1 0x020; \
+ w uc.hpic1 5 1 0x040; \
+ w uc.hpic1 6 1 0x080; \
+ w uc.hpic1 7 1 0x100; \
+ ; \
+ w uc.hpic2 0 1 0x002; \
+ w uc.hpic2 1 1 0x004; \
+ w uc.hpic2 2 1 0x008; \
+ w uc.hpic2 3 1 0x010; \
+ w uc.hpic2 4 1 0x020; \
+ w uc.hpic2 5 1 0x040; \
+ w uc.hpic2 6 1 0x080; \
+ w uc.hpic2 7 1 0x100; \
+ ; \
+ w uc.hpic3 0 1 0x002; \
+ w uc.hpic3 1 1 0x004; \
+ w uc.hpic3 2 1 0x008; \
+ w uc.hpic3 3 1 0x010; \
+ w uc.hpic3 4 1 0x020; \
+ w uc.hpic3 5 1 0x040; \
+ w uc.hpic3 6 1 0x080; \
+ w uc.hpic3 7 1 0x100; \
+ ; \
+ w uc.hpic4 0 1 0x002; \
+ w uc.hpic4 1 1 0x004; \
+ w uc.hpic4 2 1 0x008; \
+ w uc.hpic4 3 1 0x010; \
+ w uc.hpic4 4 1 0x020; \
+ w uc.hpic4 5 1 0x040; \
+ w uc.hpic4 6 1 0x080; \
+ w uc.hpic4 7 1 0x100; \
+ ; \
+ w uc.hpic5 0 1 0x002; \
+ w uc.hpic5 1 1 0x004; \
+ w uc.hpic5 2 1 0x008; \
+ w uc.hpic5 3 1 0x010; \
+ w uc.hpic5 4 1 0x020; \
+ w uc.hpic5 5 1 0x040; \
+ w uc.hpic5 6 1 0x080; \
+ w uc.hpic5 7 1 0x100; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x008; \
+ w uc.hpic6 3 1 0x010; \
+ w uc.hpic6 4 1 0x020; \
+ w uc.hpic6 5 1 0x040; \
+ w uc.hpic6 6 1 0x080; \
+ w uc.hpic6 7 1 0x100; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x008; \
+ w uc.hpic7 3 1 0x010; \
+ w uc.hpic7 4 1 0x020; \
+ w uc.hpic7 5 1 0x040; \
+ w uc.hpic7 6 1 0x080; \
+ w uc.hpic7 7 1 0x100; \
+ ; \
+ "
+
+if $?herculynx && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?herculynx && $?unit1 \
+ "stkmode modid=0"
+
+if $?herculynx && $?unit2 \
+ "stkmode modid=1"
+
+if $?herculynx && $?unit3 \
+ "stkmode modid=2"
+
+if $?herculynx && $?unit4 \
+ "stkmode modid=3"
+
+if $?herculynx && $?unit5 \
+ "stkmode modid=4"
+
+if $?herculynx && $?unit6 \
+ "stkmode modid=5"
+
+if $?herculynx && $?unit7 \
+ "stkmode modid=6"
+
+if $?herculynx && $?unit8 \
+ "stkmode modid=7"
+
+# LynxaLot setup
+# (enabled by adding the property "lynxalot=1")
+# Notes:
+# Lynx unit 0 is on Herc port 3 (hg2/hpic2) (mod 0)
+# Lynx unit 1 is on Herc port 4 (hg3/hpic3) (mod 1)
+# Higig conn 0 is on Herc port 5 (hg4/hpic4)
+# Higig conn 1 is on Herc port 6 (hg5/hpic5)
+# Draco unit 3 is on Herc port 7 (hg6/hpic6) (mod 2)
+# Draco unit 4 is on Herc port 8 (hg7/hpic7) (mod 3)
+# Draco unit 5 is on Herc port 1 (hg0/hpic0) (mod 4)
+# Draco unit 6 is on Herc port 2 (hg1/hpic1) (mod 5)
+
+if $?lynxalot && $?unit2 \
+ " \
+ w uc.hpic0 0 1 0x008; \
+ w uc.hpic0 1 1 0x010; \
+ w uc.hpic0 2 1 0x080; \
+ w uc.hpic0 3 1 0x100; \
+ w uc.hpic0 4 1 0x002; \
+ w uc.hpic0 5 1 0x004; \
+ ; \
+ w uc.hpic1 0 1 0x008; \
+ w uc.hpic1 1 1 0x010; \
+ w uc.hpic1 2 1 0x080; \
+ w uc.hpic1 3 1 0x100; \
+ w uc.hpic1 4 1 0x002; \
+ w uc.hpic1 5 1 0x004; \
+ ; \
+ w uc.hpic2 0 1 0x008; \
+ w uc.hpic2 1 1 0x010; \
+ w uc.hpic2 2 1 0x080; \
+ w uc.hpic2 3 1 0x100; \
+ w uc.hpic2 4 1 0x002; \
+ w uc.hpic2 5 1 0x004; \
+ ; \
+ w uc.hpic3 0 1 0x008; \
+ w uc.hpic3 1 1 0x010; \
+ w uc.hpic3 2 1 0x080; \
+ w uc.hpic3 3 1 0x100; \
+ w uc.hpic3 4 1 0x002; \
+ w uc.hpic3 5 1 0x004; \
+ ; \
+ w uc.hpic6 0 1 0x008; \
+ w uc.hpic6 1 1 0x010; \
+ w uc.hpic6 2 1 0x080; \
+ w uc.hpic6 3 1 0x100; \
+ w uc.hpic6 4 1 0x002; \
+ w uc.hpic6 5 1 0x004; \
+ ; \
+ w uc.hpic7 0 1 0x008; \
+ w uc.hpic7 1 1 0x010; \
+ w uc.hpic7 2 1 0x080; \
+ w uc.hpic7 3 1 0x100; \
+ w uc.hpic7 4 1 0x002; \
+ w uc.hpic7 5 1 0x004; \
+ ; \
+ "
+
+if $?lynxalot && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?lynxalot && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?lynxalot && $?unit0 \
+ "stkmode modid=0"
+
+if $?lynxalot && $?unit1 \
+ "stkmode modid=1"
+
+if $?lynxalot && $?unit3 \
+ "stkmode modid=2"
+
+if $?lynxalot && $?unit4 \
+ "stkmode modid=3"
+
+if $?lynxalot && $?unit5 \
+ "stkmode modid=4"
+
+if $?lynxalot && $?unit6 \
+ "stkmode modid=5"
+
+# guenevere setup
+# (enabled by adding the property "guenevere=1")
+# Notes:
+# hgX mapping based on pbmp_valid.0=0x1b7
+# Draco unit 1 is on Herc port 1 (hg0/hpic0) (mod 0)
+# Draco unit 2 is on Herc port 2 (hg1/hpic1) (mod 1)
+# Lynx unit 3 is on Herc port 8 (hg5/hpic7) (mod 2)
+# Lynx unit 4 is on Herc port 7 (hg4/hpic6) (mod 3)
+# Higig conn 0 is on Herc port 4 (hg2/hpic3)
+# Higig conn 1 is on Herc port 5 (hg3/hpic4)
+# Herc port 3 - Unused (hpic2)
+# Herc port 6 - Unused (hpic5)
+if $?guenevere && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x100; \
+ w uc.hpic0 3 1 0x080; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x100; \
+ w uc.hpic1 3 1 0x080; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x100; \
+ w uc.hpic7 3 1 0x080; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x100; \
+ w uc.hpic6 3 1 0x080; \
+ ; \
+ "
+
+if $?guenevere && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?guenevere && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?guenevere && $?unit1 \
+ "stkmode modid=0"
+
+if $?guenevere && $?unit2 \
+ "stkmode modid=1"
+
+if $?guenevere && $?unit3 \
+ "stkmode modid=2"
+
+if $?guenevere && $?unit4 \
+ "stkmode modid=3"
+
+# felix48 setup
+# (enabled by adding the property "felix48=1")
+# Notes:
+# BCM56102 unit-0 higig port (port 26) is connected
+# to BCM56102 Unit-1 higig port (port 26)
+#
+
+if $?felix48 && $?unit0 \
+ "stkmode modid=0 ; \
+ m IEGR_PORT MY_MODID=0; \
+ m XPORT_CONFIG MY_MODID=0; \
+ w MODPORT_MAP 1 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+
+if $?felix48 && $?unit1 \
+ "stkmode modid=1 ; \
+ m IEGR_PORT MY_MODID=1; \
+ m XPORT_CONFIG MY_MODID=1; \
+ w MODPORT_MAP 0 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+# fbpoe setup
+# (enabled by adding the property "fbpoe=1")
+# Notes:
+# BCM56504 unit-0 higig port (port 27,28) is connected
+# to BCM56504 Unit-1 higig port (port 27,28)
+#
+
+if $?unit0 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+if $?unit1 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+# Dual Raptor/Raven boards
+if $?raven_eb_48p || $?rap24_ref \
+ "local rcpu_system 1"
+if $?unit0 && $?rcpu_system \
+ "stkmode modid=0"
+if $?unit1 && $?rcpu_system \
+ "stkmode modid=1"
+
+# LM fb48 platform setup
+# (enabled by adding the property "lm48p=1")
+#
+if $?unit0 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=0"
+
+if $?unit1 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=1"
+
+# Set Firebolt POE power level 170(total) - 110(switch) = 60
+if $?fbpoe \
+ "local poepower 60"
+
+# Set Draco15 POE power level 170(total) - 80(switch) = 90
+if $?drac15\
+ "local poepower 90"
+
+# Hurricane3 BCM956160R setup
+# Notes:
+# BCM56160 unit-0 higig port (port 29,30) is connected
+# to BCM56160 Unit-1 higig port (port 26,27)
+#
+
+if $?bcm956160r && $?unit0 \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x60000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+if $?bcm956160r && $?unit1 \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0xc000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+# if enable_poe is set, then enable the POE processor for
+# either Firebolt or Draco15 platform
+if $?unit0 && $?enable_poe && $?fbpoe || $?drac15 \
+ "$echo rc: Enabling POE ...; \
+ poesel reset; \
+ i2c probe quiet; \
+ xpoe verbose off; \
+ xpoe power $poepower; \
+ xpoe verbose on; \
+ poesel enable"
+
+# mark this unit so that subsequent rc runs are quiet
+setenv rc$unit 1
+
+if $?macsec '\
+ macsec sync; \
+ $echo "rc: MACSEC CLI Enabled"'
+
+# cache a copy of rc.soc in memory
+rccache addq rc.soc
+
+# setup chassis if requested
+if !"expr $?autochassis2 && $unit == $units - 1" \
+ "setenv chassis2_no_rc 1; \
+ rcload c2switch.soc; \
+ setenv chassis2_no_rc; \
+ "
+
+# start stacking if requested
+if !"expr $?autostack && $unit == $units - 1" \
+ "rcload stk.soc"
+
+if !"expr $?aedev + 0" && !"expr $unit == $units - 1" \
+ "aedev init"
+
+# hurricane 48p FE platform LED setup for 56146_A0 and 56147_A0 board
+# (enabled by adding the property "fe_hu_48p=1")
+#
+if $?fe_hu_48p && $?BCM56146 || $?BCM56147 \
+ "phy fe0 0x1f 0x008b; \
+ phy fe0 0x1a 0x3f09;\
+ phy fe8 0x1f 0x008b; \
+ phy fe8 0x1a 0x3f09; \
+ phy fe16 0x1f 0x008b; \
+ phy fe16 0x1a 0x3f09"
+
+# enable LED matrix mode for PHY54292 on BCM953411K/R
+if $?bcm953411 \
+ "rcload gh_bcm953411x.soc"
+
+if $?simulator \
+ 'echo -n "Chip init finishes at: ";date'
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/readme.txt b/bal_release/3rdparty/bcm-sdk/rc/qax/readme.txt
new file mode 100644
index 0000000..93b40db
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/readme.txt
@@ -0,0 +1,19 @@
+This directory contains bcm files that are needed in the QAX svk file system to bring up
+the BCM Diag Shell.
+User should also copy the bcm.user linux-kernel-bde.ko and linux-user-bde.ko
+from the Jenkins BAL WRX build or private bcm_sdk build to the same QAX svk file system.
+!!!
+ Do not forget to change the IP in rpc.soc to point it to the BAL_CORE
+!!!
+The currently supported bcm_sdk version is 6.5.4
+.
+|-- bcm88470_board.soc
+|-- combo28_dram.soc
+|-- config.bcm
+|-- init.sh
+|-- qax.soc
+|-- rc.soc
+`-- rpc.soc
+
+
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/reload.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/reload.soc
new file mode 100644
index 0000000..f48a50e
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/reload.soc
@@ -0,0 +1,8 @@
+#
+# $Id: reload-dune.soc,v 1.1 2011/12/13 15:37:13 assaf Exp $
+#
+# $Copyright: (c) 2006 Broadcom Corp.
+# All Rights Reserved.$
+
+setenv warmboot 1
+rcload rc.soc
diff --git a/bal_release/3rdparty/bcm-sdk/rc/qax/rpc.soc b/bal_release/3rdparty/bcm-sdk/rc/qax/rpc.soc
new file mode 100644
index 0000000..b20b75c
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/qax/rpc.soc
@@ -0,0 +1,35 @@
+cpudb newdb
+
+cpudb add key=0x1
+
+cpudb add key=0x2 local=t
+
+cts atp trans sock server start
+
+cts atp cos=0 vlan=1
+
+cte reg mode=atp
+
+# NOTE: You must un-comment the line below and replace the IP address (10.10.10.10) with
+# the value that matches your system. The IP address must be the address of the linux
+# instance where you run your bcm_bal or bcm_sdn_agent
+#
+#cts atp trans sock inst dk=0x1 dip=10.10.10.10
+
+rpc nonexthop
+
+rpc start
+
+# NOTE: To enable CPU packet send and receive (i.e. PacketOut and PacketIn for SDN),
+# you must un-comment the lines below and replace the IP address (10.10.10.10) and port with
+# the values that match your system. The IP address must be the address of the linux
+# instance where you run your bcm_bal or bcm_sdn_agent, and the port must match the values used
+# in your bal_config.ini file
+# (i.e. The trap_target port number here must match trap_udp_port in bal_config.ini, and the
+# trap_receive port here must match pkt_send_svr_listen_port in bal_config.ini)
+
+#
+#bal trap_target 10.10.10.10:50001
+
+#bal trap_receive 10.10.10.10:50002
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/bcm88470_board.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/bcm88470_board.soc
new file mode 100644
index 0000000..b944270
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/bcm88470_board.soc
@@ -0,0 +1,211 @@
+# $Id:
+# $Copyright: (c) 1998-2001 Broadcom Corp.
+# All Rights Reserved.$
+#
+
+# Dram dq swaps for BCM88470
+
+#Dram HW properties
+
+#RX polarity
+config add phy_rx_polarity_flip.BCM88470=0
+
+
+#TX polarity
+config add phy_tx_polarity_flip.BCM88470=0
+
+#rx lane swap
+config add phy_rx_lane_map.BCM88470=0x3210
+config add phy_rx_lane_map_quad0.BCM88470=0x3210
+config add phy_rx_lane_map_quad1.BCM88470=0x3210
+config add phy_rx_lane_map_quad2.BCM88470=0x3210
+config add phy_rx_lane_map_quad3.BCM88470=0x3210
+config add phy_rx_lane_map_quad4.BCM88470=0x3210
+config add phy_rx_lane_map_quad5.BCM88470=0x3210
+config add phy_rx_lane_map_quad6.BCM88470=0x3210
+config add phy_rx_lane_map_quad7.BCM88470=0x3210
+config add phy_rx_lane_map_quad8.BCM88470=0x3210
+config add phy_rx_lane_map_quad9.BCM88470=0x3210
+config add phy_rx_lane_map_quad10.BCM88470=0x3120
+config add phy_rx_lane_map_quad11.BCM88470=0x3210
+
+
+#tx lane swap
+config add phy_tx_lane_map.BCM88470=0x3210
+config add phy_tx_lane_map_quad0.BCM88470=0x3210
+config add phy_tx_lane_map_quad1.BCM88470=0x3210
+config add phy_tx_lane_map_quad2.BCM88470=0x3210
+config add phy_tx_lane_map_quad3.BCM88470=0x3210
+config add phy_tx_lane_map_quad4.BCM88470=0x3210
+config add phy_tx_lane_map_quad5.BCM88470=0x3210
+config add phy_tx_lane_map_quad6.BCM88470=0x3210
+config add phy_tx_lane_map_quad7.BCM88470=0x3210
+config add phy_tx_lane_map_quad8.BCM88470=0x3210
+config add phy_tx_lane_map_quad9.BCM88470=0x3210
+config add phy_tx_lane_map_quad10.BCM88470=0x3120
+config add phy_tx_lane_map_quad11.BCM88470=0x3210
+
+# Dram dq swaps for BCM88470
+config add ext_ram_dq_swap_dram0_byte0_bit0.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte0_bit1.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte0_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte0_bit3.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte0_bit4.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte0_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte0_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte0_bit7.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte1_bit0.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte1_bit1.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte1_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte1_bit3.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte1_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte1_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte1_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte1_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte2_bit0.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte2_bit1.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte2_bit2.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte2_bit3.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte2_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte2_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte2_bit6.BCM88470=0
+config add ext_ram_dq_swap_dram0_byte2_bit7.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte3_bit0.BCM88470=3
+config add ext_ram_dq_swap_dram0_byte3_bit1.BCM88470=2
+config add ext_ram_dq_swap_dram0_byte3_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram0_byte3_bit3.BCM88470=7
+config add ext_ram_dq_swap_dram0_byte3_bit4.BCM88470=6
+config add ext_ram_dq_swap_dram0_byte3_bit5.BCM88470=1
+config add ext_ram_dq_swap_dram0_byte3_bit6.BCM88470=4
+config add ext_ram_dq_swap_dram0_byte3_bit7.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte0_bit0.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte0_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte0_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte0_bit3.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte0_bit4.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte0_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte0_bit6.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte0_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte1_bit0.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte1_bit1.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte1_bit2.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte1_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte1_bit4.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte1_bit5.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte1_bit6.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte1_bit7.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte2_bit0.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte2_bit1.BCM88470=3
+config add ext_ram_dq_swap_dram1_byte2_bit2.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte2_bit3.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte2_bit4.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte2_bit5.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte2_bit6.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte2_bit7.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte3_bit0.BCM88470=2
+config add ext_ram_dq_swap_dram1_byte3_bit1.BCM88470=6
+config add ext_ram_dq_swap_dram1_byte3_bit2.BCM88470=1
+config add ext_ram_dq_swap_dram1_byte3_bit3.BCM88470=7
+config add ext_ram_dq_swap_dram1_byte3_bit4.BCM88470=4
+config add ext_ram_dq_swap_dram1_byte3_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram1_byte3_bit6.BCM88470=5
+config add ext_ram_dq_swap_dram1_byte3_bit7.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte0_bit0.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte0_bit1.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte0_bit2.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte0_bit3.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte0_bit4.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte0_bit5.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte0_bit6.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte0_bit7.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte1_bit0.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte1_bit1.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte1_bit2.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte1_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte1_bit4.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte1_bit5.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte1_bit6.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte1_bit7.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte2_bit0.BCM88470=1
+config add ext_ram_dq_swap_dram2_byte2_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte2_bit2.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte2_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte2_bit4.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte2_bit5.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte2_bit6.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte2_bit7.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte3_bit0.BCM88470=0
+config add ext_ram_dq_swap_dram2_byte3_bit1.BCM88470=7
+config add ext_ram_dq_swap_dram2_byte3_bit2.BCM88470=4
+config add ext_ram_dq_swap_dram2_byte3_bit3.BCM88470=6
+config add ext_ram_dq_swap_dram2_byte3_bit4.BCM88470=2
+config add ext_ram_dq_swap_dram2_byte3_bit5.BCM88470=5
+config add ext_ram_dq_swap_dram2_byte3_bit6.BCM88470=3
+config add ext_ram_dq_swap_dram2_byte3_bit7.BCM88470=1
+
+# Dram bank addr swaps for BCM88470
+config add ext_ram_addr_bank_swap_dram0_bit7.BCM88470=4
+config add ext_ram_addr_bank_swap_dram0_bit11.BCM88470=5
+config add ext_ram_addr_bank_swap_dram0_bit13.BCM88470=15
+config add ext_ram_addr_bank_swap_dram0_bit14.BCM88470=17
+config add ext_ram_addr_bank_swap_dram0_bit5.BCM88470=6
+config add ext_ram_addr_bank_swap_dram0_bit0.BCM88470=7
+config add ext_ram_addr_bank_swap_dram0_bit8.BCM88470=8
+config add ext_ram_addr_bank_swap_dram0_bit1.BCM88470=9
+config add ext_ram_addr_bank_swap_dram0_bit4.BCM88470=10
+config add ext_ram_addr_bank_swap_dram0_bit16.BCM88470=11
+config add ext_ram_addr_bank_swap_dram0_bit15.BCM88470=12
+config add ext_ram_addr_bank_swap_dram0_bit12.BCM88470=13
+config add ext_ram_addr_bank_swap_dram0_bit6.BCM88470=0
+config add ext_ram_addr_bank_swap_dram0_bit2.BCM88470=1
+config add ext_ram_addr_bank_swap_dram0_bit9.BCM88470=2
+config add ext_ram_addr_bank_swap_dram0_bit10.BCM88470=14
+config add ext_ram_addr_bank_swap_dram0_bit17.BCM88470=16
+config add ext_ram_addr_bank_swap_dram1_bit10.BCM88470=4
+config add ext_ram_addr_bank_swap_dram1_bit14.BCM88470=5
+config add ext_ram_addr_bank_swap_dram1_bit7.BCM88470=15
+config add ext_ram_addr_bank_swap_dram1_bit12.BCM88470=17
+config add ext_ram_addr_bank_swap_dram1_bit4.BCM88470=6
+config add ext_ram_addr_bank_swap_dram1_bit6.BCM88470=7
+config add ext_ram_addr_bank_swap_dram1_bit9.BCM88470=8
+config add ext_ram_addr_bank_swap_dram1_bit1.BCM88470=9
+config add ext_ram_addr_bank_swap_dram1_bit5.BCM88470=10
+config add ext_ram_addr_bank_swap_dram1_bit11.BCM88470=11
+config add ext_ram_addr_bank_swap_dram1_bit8.BCM88470=12
+config add ext_ram_addr_bank_swap_dram1_bit13.BCM88470=13
+config add ext_ram_addr_bank_swap_dram1_bit0.BCM88470=0
+config add ext_ram_addr_bank_swap_dram1_bit15.BCM88470=1
+config add ext_ram_addr_bank_swap_dram1_bit2.BCM88470=2
+config add ext_ram_addr_bank_swap_dram1_bit17.BCM88470=14
+config add ext_ram_addr_bank_swap_dram1_bit16.BCM88470=16
+config add ext_ram_addr_bank_swap_dram2_bit15.BCM88470=4
+config add ext_ram_addr_bank_swap_dram2_bit5.BCM88470=5
+config add ext_ram_addr_bank_swap_dram2_bit11.BCM88470=15
+config add ext_ram_addr_bank_swap_dram2_bit7.BCM88470=17
+config add ext_ram_addr_bank_swap_dram2_bit17.BCM88470=6
+config add ext_ram_addr_bank_swap_dram2_bit0.BCM88470=7
+config add ext_ram_addr_bank_swap_dram2_bit16.BCM88470=8
+config add ext_ram_addr_bank_swap_dram2_bit2.BCM88470=9
+config add ext_ram_addr_bank_swap_dram2_bit13.BCM88470=10
+config add ext_ram_addr_bank_swap_dram2_bit9.BCM88470=11
+config add ext_ram_addr_bank_swap_dram2_bit12.BCM88470=12
+config add ext_ram_addr_bank_swap_dram2_bit6.BCM88470=13
+config add ext_ram_addr_bank_swap_dram2_bit14.BCM88470=0
+config add ext_ram_addr_bank_swap_dram2_bit8.BCM88470=1
+config add ext_ram_addr_bank_swap_dram2_bit1.BCM88470=2
+config add ext_ram_addr_bank_swap_dram2_bit4.BCM88470=14
+config add ext_ram_addr_bank_swap_dram2_bit10.BCM88470=16
+
+##Dram HW properties
+config add ext_ram_present.BCM88470=3
+config add dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT=1
+config add ext_ram_freq.BCM88470=1600
+config add ext_ram_abi.BCM88470=0
+config add ext_ram_write_dbi.BCM88470=0
+config add ext_ram_read_dbi.BCM88470=0
+config add ext_ram_write_crc.BCM88470=0
+config add ext_ram_read_crc.BCM88470=0
+config add ext_ram_cmd_par_latency.BCM88470=6
+config add ext_ram_type.BCM88470=DDR4
+config add ext_ram_total_size.BCM88470=3000
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/combo28_dram.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/combo28_dram.soc
new file mode 100644
index 0000000..d47c1f5
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/combo28_dram.soc
@@ -0,0 +1,560 @@
+#
+# $Id: combo28_dram.soc,v 1.0 2014/04/28 15:50:00 nhefetz Exp $
+#
+# $Copyright: (c) 2014 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+#################### General Notes ########################
+# Our controller support both DDR4 and GDDR5, we need to "modify" ext_ram_columns in the following way:
+# For DDR4, need to use column number as in DRAM Data Sheet, meaning 1024 in drams supported.
+# For GDDR5, need to multiply number in Data Sheet by 8 (representing the 3 address bits, which are constant 000 in DDR4.), meaning 512 in drams supported.
+
+
+if $?dram_type_DDR4_SAMSUNG_K4A4G165WD_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\\
+ config add ext_ram_t_ccd_l=6c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=17c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_MICRON_EDY4016AABG_DRFR_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\\
+ config add ext_ram_t_ccd_l=6c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_DDR4_MICRON_MT40A256M16HA_083EA_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=12c;\\
+ config add ext_ram_t_ccd_l=8c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=18c;\
+ config add ext_ram_c_cas_latency=24c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_DDR4_MICRON_MT40A512M16_8GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=350000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_c_cas_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=65536; \
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_HYNIX_H5AN4G6NMFR_VJC_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=45320;\
+ config add ext_ram_t_rcd_wr=13320;\
+ config add ext_ram_t_rcd_rd=13320;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=4c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=13320;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=7500;\
+ config add ext_ram_t_rtp_l=7500;\
+ config add ext_ram_t_wtr_s=2500;\
+ config add ext_ram_t_wtr_l=7500;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_crc_wr_latency=12c;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT "\
+ config add ext_ram_type=DDR4; \
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\\
+ config add ext_ram_t_wtr_l=12c;\\
+ config add ext_ram_t_ccd_l=8c;\\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_c_cas_latency=24c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024; \
+ config add ext_ram_rows=32768; \
+ config add ext_ram_banks=8;"
+
+if $?dram_type_GDDR5_SAMSUNG_K4G20325FD_2GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=78000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=8192; \
+ config add ext_ram_banks=16;"
+
+########################################################################
+# Note: Not for new design not recommended to be used and not supported
+########################################################################
+if $?dram_type_GDDR5_SAMSUNG_K4G41325FC_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_c_cas_latency=20c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+#if $?dram_type_GDDR5_HYNIX_H5GQ2H24AFR_R0C_2GBIT "\
+# config add ext_ram_type=GDDR5; \
+# config add ext_ram_t_rfc=120000;\
+# config add ext_ram_t_rc=48000;\
+# config add ext_ram_t_rcd_wr=14000;\
+# config add ext_ram_t_rcd_rd=18000;\
+# config add ext_ram_t_rrd_l=9c;\
+# config add ext_ram_t_rrd_s=9c;\
+# config add ext_ram_t_ras=32000;\
+# config add ext_ram_t_rp=16000;\
+# config add ext_ram_t_wr=16000;\
+# config add ext_ram_t_faw=30000;\
+# config add ext_ram_t_32aw=245000;\
+# config add ext_ram_t_rtp_s=2c;\
+# config add ext_ram_t_rtp_l=2c;\
+# config add ext_ram_t_wtr_s=8c;\
+# config add ext_ram_t_wtr_l=8c;\
+# config add ext_ram_t_ccd_l=3c;\
+# config add ext_ram_t_ccd_s=2c;\
+# config add ext_ram_t_ref=3900000;\
+# config add ext_ram_c_wr_latency=3c;\
+# config add ext_ram_c_cas_latency=16c;\
+# config add ext_ram_t_crc_rd_latency=2c;\
+# config add ext_ram_t_crc_wr_latency=11c;\
+# config add ext_ram_t_rst=200000000;\
+# config add ext_ram_t_al=1c;\
+# config add ext_ram_columns=512; \
+# config add ext_ram_rows=8192; \
+# config add ext_ram_banks=16;"
+#
+
+###################################################
+# ELPIDA GDDR5
+###################################################
+if $?dram_type_GDDR5_MICRON_EDW4032CABG_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=90000;\
+ config add ext_ram_t_rc=44000;\
+ config add ext_ram_t_rcd_wr=13000;\
+ config add ext_ram_t_rcd_rd=17000;\
+ config add ext_ram_t_rrd_l=5000;\
+ config add ext_ram_t_rrd_s=5000;\
+ config add ext_ram_t_ras=27000;\
+ config add ext_ram_t_rp=17000;\
+ config add ext_ram_t_wr=18000;\
+ config add ext_ram_t_faw=20000;\
+ config add ext_ram_t_32aw=160000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=7c;\
+ config add ext_ram_t_wtr_l=7c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_c_cas_latency=18c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=11c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=2c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+if $?dram_type_GDDR5_HYNIX_H5GC4H24MFR_T2C_4GBIT "\
+ config add ext_ram_type=GDDR5; \
+ config add ext_ram_t_rfc=120000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=14000;\
+ config add ext_ram_t_rcd_rd=18000;\
+ config add ext_ram_t_rrd_l=9c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=16000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_32aw=245000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=8c;\
+ config add ext_ram_t_wtr_l=8c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_c_cas_latency=18c;\
+ config add ext_ram_t_crc_rd_latency=2c;\
+ config add ext_ram_t_crc_wr_latency=13c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512; \
+ config add ext_ram_rows=16384; \
+ config add ext_ram_banks=16;"
+
+###############################################################################################
+# Note: For extended devices for example Micron dram_type_DDR4_MICRON_MT40A256M16HA_083E
+# please use none extended parameters for example dram_type_DDR4_MICRON_MT40A256M16HA_083
+###############################################################################################
+if $?dram_type_DDR4_MICRON_MT40A256M16HA_083_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A256M16HA_083_4GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_DDR4_MICRON_MT40A512M16HA_083_8GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=350000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=65536;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A512M16HA_083_8GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_DDR4_MICRON_MT40A256M16GE_062_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1600;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=47000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=15000;\
+ config add ext_ram_t_rrd_l=11c;\
+ config add ext_ram_t_rrd_s=9c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=15000;\
+ config add ext_ram_t_wr=14900;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=12c;\
+ config add ext_ram_t_rtp_l=12c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=12c;\
+ config add ext_ram_t_ccd_l=8c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=170c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=16c;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=8;\
+ config add ext_ram_c_cas_latency=24c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_MICRON_MT40A256M16GE_062_4GBIT "\
+ config add ext_ram_c_cas_latency=28c;"
+
+if $?dram_type_DDR4_SAMSUNG_K4A4G165WE_4GBIT "\
+ config add ext_ram_type=DDR4;\
+ config add ext_ram_freq=1200;\
+ config add ext_ram_t_rfc=260000;\
+ config add ext_ram_t_rc=46160;\
+ config add ext_ram_t_rcd_wr=14160;\
+ config add ext_ram_t_rcd_rd=14160;\
+ config add ext_ram_t_rrd_l=8c;\
+ config add ext_ram_t_rrd_s=7c;\
+ config add ext_ram_t_ras=32000;\
+ config add ext_ram_t_rp=14160;\
+ config add ext_ram_t_wr=15000;\
+ config add ext_ram_t_faw=30000;\
+ config add ext_ram_t_rtp_s=10c;\
+ config add ext_ram_t_rtp_l=10c;\
+ config add ext_ram_t_wtr_s=4c;\
+ config add ext_ram_t_wtr_l=10c;\
+ config add ext_ram_t_ccd_l=6c;\
+ config add ext_ram_t_ccd_s=4c;\
+ config add ext_ram_t_zqcs=128c;\
+ config add ext_ram_t_crc_alert=13000;\
+ config add ext_ram_t_rst=500000000;\
+ config add ext_ram_t_ref=3900000;\
+ config add ext_ram_c_wr_latency=12c ;\
+ config add ext_ram_t_al=0;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=32768;\
+ config add ext_ram_banks=8;\
+ config delete ext_ram_cmd_par_latency*;\
+ config add ext_ram_cmd_par_latency=5;\
+ config add ext_ram_c_cas_latency=17c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_DDR4_SAMSUNG_K4A4G165WE_4GBIT "\
+ config add ext_ram_c_cas_latency=20c;"
+
+if $?dram_type_GDDR5_MICRON_MT51K256M32HF_50_8GBIT "\
+ config add ext_ram_type=GDDR5;\
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=44000;\
+ config add ext_ram_t_rcd_wr=12000;\
+ config add ext_ram_t_rcd_rd=17000;\
+ config add ext_ram_t_rrd_l=5000;\
+ config add ext_ram_t_rrd_s=5000;\
+ config add ext_ram_t_ras=27000;\
+ config add ext_ram_t_rp=17000;\
+ config add ext_ram_t_wr=18000;\
+ config add ext_ram_t_faw=20000;\
+ config add ext_ram_t_32aw=160000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=2c;\
+ config add ext_ram_t_wtr_s=6c;\
+ config add ext_ram_t_wtr_l=6c;\
+ config add ext_ram_t_ccd_l=2c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=4c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=11c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=2c;\
+ config add ext_ram_columns=1024;\
+ config add ext_ram_rows=16384;\
+ config add ext_ram_banks=16;\
+ config add ext_ram_c_cas_latency=16c;"
+expr $ext_ram_write_dbi==1
+if $? && $?dram_type_GDDR5_MICRON_MT51K256M32HF_50_8GBIT "\
+ config add ext_ram_c_cas_latency=16c;"
+
+if $?dram_type_GDDR5_SAMSUNG_K4G41325FE_HC28_4GBIT "\
+ config add ext_ram_type=GDDR5;\
+ config add ext_ram_t_rfc=110000;\
+ config add ext_ram_t_rc=48000;\
+ config add ext_ram_t_rcd_wr=15000;\
+ config add ext_ram_t_rcd_rd=16000;\
+ config add ext_ram_t_rrd_l=6000;\
+ config add ext_ram_t_rrd_s=6000;\
+ config add ext_ram_t_ras=34000;\
+ config add ext_ram_t_rp=14000;\
+ config add ext_ram_t_wr=16000;\
+ config add ext_ram_t_faw=24000;\
+ config add ext_ram_t_32aw=192000;\
+ config add ext_ram_t_rtp_s=2c;\
+ config add ext_ram_t_rtp_l=4c;\
+ config add ext_ram_t_wtr_s=3c;\
+ config add ext_ram_t_wtr_l=8c;\
+ config add ext_ram_t_ccd_l=3c;\
+ config add ext_ram_t_ccd_s=2c;\
+ config add ext_ram_t_ref=1900000;\
+ config add ext_ram_c_wr_latency=3c;\
+ config add ext_ram_t_crc_rd_latency=3c;\
+ config add ext_ram_t_crc_wr_latency=14c;\
+ config add ext_ram_t_rst=200000000;\
+ config add ext_ram_t_al=1c;\
+ config add ext_ram_columns=512;\
+ config add ext_ram_rows=16384;\
+ config add ext_ram_banks=16;\
+ config add ext_ram_c_cas_latency=18c;"
+expr $ext_ram_write_dbi+0 == 1
+if $? && $?dram_type_GDDR5_SAMSUNG_K4G41325FE_HC28_4GBIT "\
+ config add ext_ram_c_cas_latency=19c;"
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/config.bcm b/bal_release/3rdparty/bcm-sdk/rc/svk4/config.bcm
new file mode 100644
index 0000000..4878c2d
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/config.bcm
@@ -0,0 +1,2912 @@
+#
+# $Id: config-sand.bcm,v 1.140 2013/09/22 14:29:47 tomerma Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+
+#pci_override_dev.0=0x8375
+
+# Note: comment size is restricted to 128 charecters per line.
+
+#########################################
+##cfg for BCM88640 (PetraB), BCM88650 (Arad) and BCM88202 (Ardon)
+#########################################
+
+## temporary suppressing unknown soc properties warnings - till adding them unknown to property.h/propgen
+## (need to be the first soc property in the file).
+suppress_unknown_prop_warnings=1
+
+
+## Multi device system (Negev): 2 devices, fabric mode is FE, mod id is slot id
+## (Top line card is 0, button is 1).
+#diag_chassis=1
+
+## Disable diag init application. Should be used if one wants to run his own
+## application instead of the diag init example
+#diag_disable=1
+
+## Skip cosq configuration in diag_init
+#diag_cosq_disable=1
+#
+
+stack_enable.BCM88680=1
+tdma_timeout_usec.BCM88680=3000000
+tslam_timeout_usec.BCM88680=3000000
+diag_emulator_partial_init.BCM88680=0
+phy_simul.BCM88680=0
+
+
+## Skip l2 configuration in diag_init
+#diag_l2_disable=1
+
+## L2 mode to load 0=DEFAULT, 1=INGRESS_DIST, 2=INGRESS_CENT, 3=EGRESS_DIST, 4=EGRESS_CENT, 5=EGRESS_INDEPENDENT
+# 6=(INGRESS_CENT + LEARN_CPU), 7=(EGRESS_CENT + LEARN_CPU)
+#l2_mode=0
+
+## Skip stk configuration in diag_init
+#diag_no_appl_stk=1
+
+## Skip itmh programmable mode configuration in diag_init
+#diag_no_itmh_prog_mode=1
+
+# Ingress PMF key allocation optimization
+field_key_allocation_msb_balance_enable=1
+
+## Set modid value. Should be used when running multi-fap system.
+## Each fap should have it's unique modid value. Default is described in diag_chassis.
+#module_id=<modid>
+
+## Set base_modid value. Default is 0.
+#base_module_id=<base_modid>
+
+## Set nof_devices value. Should be set when working on multi-faps system.
+## Default is 1 when diag_chassis is not enabled, or 2 when diag_chassis is enabled.
+#n_devices=<nof_devices>
+
+#########################################
+##cfg for BCM88650 - Arad
+#########################################
+
+### Device configuration ###
+
+## Activate Emulation partial init. Values: 0 - Normal, 1 - Emulation .Default: 0x0.
+diag_emulator_partial_init.BCM88650=0
+#diag_emulator_partial_init.BCM88270=1
+#diag_emulator_partial_init.BCM88680=1
+#diag_emulator_partial_init.BCM88675=2
+
+#real phy isn't connected - remove on silicon arrival
+#phy_simul.BCM88675=1
+
+## General
+# Set the FAP Device mode
+# Options: PP / TM / TDM_OPTIMIZED / TDM_STANDARD
+fap_device_mode.BCM88650=PP
+#
+# FIXME: SDK-91833
+# PP Fixed Followed SDK-91662
+#
+
+# Options: SYMMETRIC / ASYMMETRIC / SINGLE_CORE
+# For faster emulation, use SINGLE_CORE
+device_core_mode.BCM88675=SYMMETRIC
+device_core_mode.BCM88680=SYMMETRIC
+## Credit worth size (Bytes)
+credit_size.BCM88650=1024
+
+## KBP recovery - allow for recovery sequence to run during init and soft reset (only if necessary)
+custom_feature_kbp_recovery_enable=0
+
+## Clock configurations
+# Core clock speed (MHz). Default- BCM88650: 600 MHz, BCM88675: 720 MHz
+core_clock_speed_khz.BCM88650=600000
+core_clock_speed_khz.BCM88675=720000
+core_clock_speed_khz.BCM88470=600000
+core_clock_speed_khz.BCM88680=837500
+core_clock_speed_khz.BCM88270=250000
+
+# System reference clock (MHz). Default- BCM88650: 600 MHz, BCM88675: 800 MHz
+system_ref_core_clock_khz.BCM88650=1200000
+
+#fabric pcp
+fabric_pcp_enable.BCM88675=1
+
+#Using Tcam instead of the KAPS for the IPv4 MC and IPV6 MC
+# 0 - Don't use TACM
+# 1 - Use TCAM for IPV4/6 MC
+# 2 - Use TACM for IPV4/6 MC but don't use the VRF field as a qualifier for IPV4 MC entries
+#custom_feature_l3_mc_use_tcam=0
+
+#for IPv6UC: use Tcam instead of KAPS
+#Note that if this property is enabled the IPV6-UC RPF will be disabled
+#custom_feature_l3_ipv6_uc_use_tcam=0
+
+
+#ams pll override value (only for Jericho A0/A1)- possible values: 0x19, 0x1e, 0x1f. Default value 0x1f
+#custom_feature_ams_pll_override.BCM88675=0x1f
+
+### Network Interface configuration ###
+## Use of the ucode_port_<Local-Port-Id>=<Interface-type>[<Interface-Id>][.<Channel-Id>]
+## Local port range: 0 - 255.
+## Interface types: XAUI/RXAUI/SGMII/ILKN/10GBase-R/XLGE/CGE/CPU/IGNORE
+
+# Map bcm local port to CPU[.channel] interfaces
+ucode_port_0.BCM88650=CPU.0
+
+# Map bcm local port to Network-Interface[.channel] interfaces - TBD
+ucode_port_128.BCM88650=10GBase-R36
+ucode_port_129.BCM88650=10GBase-R37
+ucode_port_130.BCM88650=10GBase-R32
+ucode_port_131.BCM88650=10GBase-R33
+ucode_port_132.BCM88650=10GBase-R34
+ucode_port_133.BCM88650=10GBase-R35
+ucode_port_134.BCM88650=10GBase-R16
+ucode_port_135.BCM88650=10GBase-R17
+ucode_port_136.BCM88650=10GBase-R18
+ucode_port_137.BCM88650=10GBase-R19
+
+ucode_port_1.BCM88650=10GBase-R22
+ucode_port_2.BCM88650=10GBase-R21
+ucode_port_3.BCM88650=10GBase-R42
+ucode_port_4.BCM88650=10GBase-R41
+
+custom_feature_nif_recovery_enable.BCM88650=1
+custom_feature_nif_recovery_iter.BCM88650=7
+custom_feature_skip_before_traffic_validation.BCM88675=0
+#custom_feature_mac_fifo_start_tx_thrs.BCM88675=9
+
+#redirect packets that are destined to invalid queues
+invalid_queue_redirect=0
+
+#CLP0
+#ucode_port_1.BCM88675=XE0:core_0.1
+#ucode_port_2.BCM88675=XE1:core_0.2
+#ucode_port_3.BCM88675=XE2:core_0.3
+#ucode_port_4.BCM88675=XE3:core_0.4
+#CLP1
+#ucode_port_5.BCM88675=XE4:core_0.5
+#ucode_port_6.BCM88675=XE5:core_0.6
+#ucode_port_7.BCM88675=XE6:core_0.7
+#ucode_port_8.BCM88675=XE7:core_0.8
+#CLP2
+#ucode_port_9.BCM88675=XE8:core_0.9
+#ucode_port_10.BCM88675=XE9:core_0.10
+#ucode_port_11.BCM88675=XE10:core_0.11
+#ucode_port_12.BCM88675=XE11:core_0.12
+#CLP3
+#ucode_port_13.BCM88675=XE12:core_0.13
+#ucode_port_14.BCM88675=XE13:core_0.14
+#ucode_port_15.BCM88675=XE14:core_0.15
+#ucode_port_16.BCM88675=XE15:core_0.16
+#CLP4
+#ucode_port_17.BCM88675=XE16:core_0.17
+#ucode_port_18.BCM88675=XE17:core_0.18
+#ucode_port_19.BCM88675=XE18:core_0.19
+#ucode_port_20.BCM88675=XE19:core_0.20
+#CLP5
+#ucode_port_21.BCM88675=XE20:core_0.21
+#ucode_port_22.BCM88675=XE21:core_0.22
+#ucode_port_23.BCM88675=XE22:core_0.23
+#ucode_port_24.BCM88675=XE23:core_0.24
+#XLP0
+#ucode_port_25.BCM88675=XE24:core_0.25
+#ucode_port_26.BCM88675=XE25:core_0.26
+#ucode_port_27.BCM88675=XE26:core_0.27
+#ucode_port_28.BCM88675=XE27:core_0.28
+#XLP1
+#ucode_port_29.BCM88675=XE28:core_0.29
+#ucode_port_30.BCM88675=XE29:core_0.30
+#ucode_port_31.BCM88675=XE30:core_0.31
+#ucode_port_32.BCM88675=XE31:core_0.32
+#XLP2
+#ucode_port_33.BCM88675=XE32:core_0.33
+#ucode_port_34.BCM88675=XE33:core_0.34
+#ucode_port_35.BCM88675=XE34:core_0.35
+#ucode_port_36.BCM88675=XE35:core_0.36
+#XLP3
+#ucode_port_37.BCM88675=XE36:core_0.37
+#ucode_port_38.BCM88675=XE37:core_0.38
+#ucode_port_39.BCM88675=XE38:core_0.39
+#ucode_port_40.BCM88675=XE39:core_0.40
+#XLP4 (not as PMQ0)
+#ucode_port_41.BCM88675=XE40:core_0.41
+#ucode_port_42.BCM88675=XE41:core_0.42
+#ucode_port_43.BCM88675=XE42:core_0.43
+#ucode_port_44.BCM88675=XE43:core_0.44
+#XLP5 (not as PMQ1)
+#ucode_port_45.BCM88675=XE44:core_0.45
+#ucode_port_46.BCM88675=XE45:core_0.46
+#ucode_port_47.BCM88675=XE46:core_0.47
+#ucode_port_48.BCM88675=XE47:core_0.48
+#XLP9
+#ucode_port_49.BCM88675=XE60:core_0.49
+#ucode_port_50.BCM88675=XE61:core_0.50
+#ucode_port_51.BCM88675=XE62:core_0.51
+#ucode_port_52.BCM88675=XE63:core_0.52
+#XLP10
+#ucode_port_53.BCM88675=XE64:core_0.53
+#ucode_port_54.BCM88675=XE65:core_0.54
+#ucode_port_55.BCM88675=XE66:core_0.55
+#ucode_port_56.BCM88675=XE67:core_0.56
+#XLP11 (not as PMQ3)
+#ucode_port_57.BCM88675=XE68:core_0.57
+#ucode_port_58.BCM88675=XE69:core_0.58
+#ucode_port_59.BCM88675=XE70:core_0.59
+#ucode_port_60.BCM88675=XE71:core_0.60
+
+
+ucode_port_0.BCM88675=CPU.0:core_0.0
+ucode_port_0.BCM88680=CPU.0:core_0.0
+ucode_port_200.BCM88675=CPU.8:core_1.200
+ucode_port_200.BCM88680=CPU.8:core_1.200
+ucode_port_201.BCM88675=CPU.16:core_0.201
+ucode_port_201.BCM88680=CPU.16:core_0.201
+ucode_port_202.BCM88675=CPU.24:core_1.202
+ucode_port_202.BCM88680=CPU.24:core_1.202
+ucode_port_203.BCM88675=CPU.32:core_0.203
+ucode_port_203.BCM88680=CPU.32:core_0.203
+
+#default ports for Jericho and QMX
+ucode_port_1.BCM88675=CGE0:core_0.1
+ucode_port_2.BCM88675=ILKN1:core_0.2
+ilkn_lanes_1.BCM88675=0xfff000
+ucode_port_3.BCM88675=ILKN2:core_0.3
+ilkn_lanes_2.BCM88675=0xfff
+ucode_port_17.BCM88675=CGE1:core_1.17
+
+#default ports for Jericho
+ucode_port_13.BCM88675=10GBase-R64:core_0.13
+ucode_port_14.BCM88675=10GBase-R65:core_0.14
+ucode_port_15.BCM88675=10GBase-R68:core_1.15
+ucode_port_16.BCM88675=10GBase-R69:core_1.16
+
+#default ports for Jericho Plus
+ucode_port_13.BCM88680=10GBase-R40:core_0.13
+ucode_port_14.BCM88680=10GBase-R43:core_0.14
+ucode_port_15.BCM88680=10GBase-R44:core_1.15
+ucode_port_16.BCM88680=10GBase-R46:core_1.16
+
+#default ports for QMX
+ucode_port_13.BCM88375_A0=10GBase-R64:core_0.13
+ucode_port_14.BCM88375_A0=10GBase-R66:core_0.14
+ucode_port_15.BCM88375_A0=10GBase-R69:core_1.15
+ucode_port_16.BCM88375_A0=10GBase-R71:core_1.16
+
+
+ucode_port_13.BCM88375_B0=10GBase-R64:core_0.13
+ucode_port_14.BCM88375_B0=10GBase-R66:core_0.14
+ucode_port_15.BCM88375_B0=10GBase-R69:core_1.15
+ucode_port_16.BCM88375_B0=10GBase-R71:core_1.16
+
+
+#default ports for QAX
+ucode_port_0.BCM88470=CPU.0:core_0.0
+
+ucode_port_200.BCM88470=CPU.8:core_0.200
+
+ucode_port_201.BCM88470=CPU.16:core_0.201
+
+ucode_port_202.BCM88470=CPU.24:core_0.202
+
+ucode_port_203.BCM88470=CPU.32:core_0.203
+
+tm_port_header_type_in_0.BCM88470=INJECTED_2_PP
+tm_port_header_type_out_0.BCM88470=CPU
+
+ucode_port_1.BCM88470=XE22:core_0.1
+ucode_port_2.BCM88470=XE21:core_0.2
+ucode_port_3.BCM88470=XE41:core_0.3
+ucode_port_4.BCM88470=XE42:core_0.4
+
+pon_application_support_enabled_1.BCM88470=TRUE
+pon_application_support_enabled_2.BCM88470=TRUE
+pon_application_support_enabled_3.BCM88470=TRUE
+pon_application_support_enabled_4.BCM88470=TRUE
+
+ucode_port_128.BCM88470=XE36:core_0.128
+ucode_port_129.BCM88470=XE37:core_0.129
+ucode_port_130.BCM88470=XE32:core_0.130
+ucode_port_131.BCM88470=XE33:core_0.131
+ucode_port_132.BCM88470=XE34:core_0.132
+ucode_port_133.BCM88470=XE35:core_0.133
+ucode_port_134.BCM88470=XE16:core_0.134
+ucode_port_135.BCM88470=XE17:core_0.135
+ucode_port_136.BCM88470=XE18:core_0.136
+ucode_port_137.BCM88470=XE19:core_0.137
+
+bcm886xx_rx_use_hw_trap_id.BCM88470=0
+
+stable_filename.BCM88270=/tmp/warmboot_data
+fap_device_mode.BCM88270=PP
+#default ports for QUX
+ucode_port_0.BCM88270=CPU.0:core_0.0
+ucode_port_200.BCM88270=CPU.8:core_0.100
+ucode_port_201.BCM88270=CPU.16:core_0.101
+ucode_port_202.BCM88270=CPU.24:core_0.102
+ucode_port_203.BCM88270=CPU.32:core_0.103
+ucode_port_1.BCM88270=XE0:core_0.1
+ucode_port_2.BCM88270=XE1:core_0.2
+ucode_port_3.BCM88270=XE2:core_0.3
+ucode_port_13.BCM88270=GE12:core_0.13
+ucode_port_14.BCM88270=GE13:core_0.14
+ucode_port_15.BCM88270=GE14:core_0.15
+ucode_port_16.BCM88270=GE15:core_0.16
+ucode_port_17.BCM88270=GE16:core_0.17
+
+
+#Firmware mode:
+#(Documantation relevant for BCM886xx and BCM887xx)
+# 0=DEFAULT
+# 1=SFP_OPT_SR4 - optical short range
+# 2=SFP_DAC - direct attach copper
+# 3=XLAUI - 40G XLAUI mode
+# 4=FORCE_OSDFE - force over sample digital feedback equalization
+# 5=FORCE_BRDFE - force baud rate digital feedback equalization
+# 6=SW_CL72 - software cl72 with AN on
+# 7=CL72_WITHOUT_AN - cl72 without AN
+#For Negev2 chassis enable DFE is recommended
+serdes_firmware_mode.BCM88650=2
+serdes_firmware_mode_il.BCM88650=4
+serdes_firmware_mode_sfi.BCM88650=0
+serdes_firmware_mode_sfi.BCM88675=4
+serdes_firmware_mode_sfi.BCM88470=4
+serdes_firmware_mode_sfi.BCM88270=4
+serdes_firmware_mode_sfi.BCM88680=4
+
+
+#ucode_port_1.BCM88650=10GBase-R0
+#ucode_port_2.BCM88650=10GBase-R1
+#ucode_port_3.BCM88650=10GBase-R2
+#ucode_port_4.BCM88650=10GBase-R3
+#ucode_port_5.BCM88650=10GBase-R4
+#ucode_port_6.BCM88650=10GBase-R5
+#ucode_port_7.BCM88650=10GBase-R6
+#ucode_port_8.BCM88650=10GBase-R7
+#ucode_port_9.BCM88650=10GBase-R8
+#ucode_port_10.BCM88650=10GBase-R9
+#ucode_port_11.BCM88650=10GBase-R10
+#ucode_port_12.BCM88650=10GBase-R11
+#ucode_port_13.BCM88650=10GBase-R12
+#ucode_port_14.BCM88650=10GBase-R13
+#ucode_port_15.BCM88650=10GBase-R14
+#ucode_port_16.BCM88650=10GBase-R15
+#ucode_port_17.BCM88650=10GBase-R16
+#ucode_port_18.BCM88650=10GBase-R17
+#ucode_port_19.BCM88650=10GBase-R18
+#ucode_port_20.BCM88650=10GBase-R19
+ucode_port_200.BCM88650=CPU.8
+ucode_port_201.BCM88650=CPU.16
+ucode_port_202.BCM88650=CPU.24
+ucode_port_203.BCM88650=CPU.32
+
+#40G
+#ucode_port_1.BCM88650=XLGE0
+#ucode_port_2.BCM88650=XLGE1
+#ucode_port_3.BCM88650=XLGE2
+#ucode_port_4.BCM88650=XLGE3
+#ucode_port_5.BCM88650=XLGE4
+#ucode_port_6.BCM88650=XLGE5
+#ucode_port_7.BCM88650=XLGE6
+
+#ILKN configuration - basic config
+#ucode_port_31.BCM88650=ILKN0
+#ucode_port_32.BCM88650=ILKN1
+#ucode_port_32.BCM88675=ILKN1:core_0.32
+#ilkn_num_lanes_0.BCM88650=12
+#ilkn_num_lanes_1.BCM88650=12
+#port_init_speed_il.BCM88650=10312
+
+
+#ILKN per port channel stat
+#ilkn_counters_mode.BCM88650=PACKET_PER_CHANNEL
+
+#ILKN configuration - advanced
+#ilkn_metaframe_sync_period=2048
+#ILKN burst configuration - ILKN max burst suppored values: 128, 256
+#ILKN burst short should be lesser or equal to burst max /2
+#ilkn_burst_max.BCM88675=256
+#ilkn_burst_min.BCM88675=32
+# Enable\Disable ILKN status message sent through an out-of-band interface.
+# ilkn_interface_status_oob_ignore.BCM88650=1
+
+# ilkn_is_burst_interleaving<ilkn_id>
+# 1 - The channelized interface functions in burst interleaving mode (default). 0 - in full packet mode.
+#ilkn_is_burst_interleaving_1.BCM88675=0
+
+##ILKN retransmit
+#ilkn_retransmit_enable_rx.BCM88650=1
+#ilkn_retransmit_enable_tx.BCM88650=1
+#ilkn_retransmit_buffer_size.BCM88650=250
+#ilkn_retransmit_num_requests_resent.BCM88650=15
+#ilkn_retransmit_num_sn_repetitions_tx.BCM88650=1
+#ilkn_retransmit_num_sn_repetitions_rx.BCM88650=1
+#ilkn_retransmit_rx_timeout_words.BCM88650=3800
+#ilkn_retransmit_rx_timeout_sn.BCM88650=250
+#ilkn_retransmit_rx_ignore.BCM88650=80
+#ilkn_retransmit_rx_reset_when_error_enable.BCM88650=1
+#ilkn_retransmit_rx_watchdog.BCM88650=0
+#ilkn_retransmit_rx_reset_when_alligned_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_retry_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_after_disc_error_enable.BCM88650=1
+#ilkn_retransmit_rx_reset_when_wrap_before_disc_error_enable.BCM88650=0
+#ilkn_retransmit_rx_reset_when_timout_error_enable.BCM88650=0
+#ilkn_retransmit_tx_wait_for_seq_num_change_enable.BCM88650=1
+#ilkn_retransmit_tx_ignore_requests_when_fifo_almost_empty.BCM88650=1
+
+#ucode_port_40.BCM88650=RCY.0
+#ucode_port_41.BCM88650=RCY.1
+#ucode_port_42.BCM88650=RCY.2
+
+## CAUI Configuration
+#ucode_port_41.BCM88650=CGE0
+#ucode_port_42.BCM88650=CGE1
+caui_num_lanes_0.BCM88650=10
+caui_num_lanes_1.BCM88650=10
+#Required for working IXIA 100G port:
+mld_lane_swap_lane20_ce.BCM88650=0
+mld_lane_swap_lane21_ce.BCM88650=1
+mld_lane_swap_lane0_ce.BCM88650=20
+mld_lane_swap_lane1_ce.BCM88650=21
+
+# This configures the lane polarity
+pb_serdes_lane_swap_polarity_tx_phy1.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy2.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy3.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy4.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy5.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy6.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy7.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy8.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy10.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy13.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy14.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy17.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy18.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy19.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy20.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy21.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy22.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy23.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy24.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy25.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_tx_phy27.BCM88650=1
+pb_serdes_lane_swap_polarity_tx_phy28.BCM88650=1
+
+pb_serdes_lane_swap_polarity_rx_phy1.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy2.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy3.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy4.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy5.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy6.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy7.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy8.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy9.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy10.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy11.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy12.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy13.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy14.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy15.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy16.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy17.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy18.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy19.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy20.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy21.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy22.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy23.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy24.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy25.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy26.BCM88650=0
+pb_serdes_lane_swap_polarity_rx_phy27.BCM88650=1
+pb_serdes_lane_swap_polarity_rx_phy28.BCM88650=1
+
+xgxs_tx_lane_map_quad0.BCM88650=0x1032
+xgxs_tx_lane_map_quad1.BCM88650=0x2310
+xgxs_tx_lane_map_quad2.BCM88650=0x3210
+xgxs_tx_lane_map_quad3.BCM88650=0x3210
+xgxs_tx_lane_map_quad4.BCM88650=0x1230
+xgxs_tx_lane_map_quad5.BCM88650=0x3201
+xgxs_tx_lane_map_quad6.BCM88650=0x2103
+xgxs_tx_lane_map_quad7.BCM88650=0x0123
+
+xgxs_rx_lane_map_quad0.BCM88650=0x3012
+xgxs_rx_lane_map_quad1.BCM88650=0x0132
+xgxs_rx_lane_map_quad2.BCM88650=0x1230
+xgxs_rx_lane_map_quad3.BCM88650=0x0123
+xgxs_rx_lane_map_quad4.BCM88650=0x3012
+xgxs_rx_lane_map_quad5.BCM88650=0x2013
+xgxs_rx_lane_map_quad6.BCM88650=0x2103
+
+
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88650=1
+
+#Port init mode
+#port_init_duplex=0
+#port_init_adv=0
+#port_init_autoneg=0
+
+
+# This disables serdes initialization
+# phy_null.BCM88650=1
+
+## Number of Internal ports
+# Enable the ERP port. Values: 0 / 1.
+num_erp_tm_ports.BCM88650=1
+# Enable the OLP port. Values: 0 / 1.
+num_olp_tm_ports.BCM88650=1
+
+## Firmware Load Method
+load_firmware.BCM88650=0x102
+load_firmware.BCM88675=0x102
+load_firmware_fabric.BCM88675=0x102
+load_firmware_fabric.BCM88680=0x102
+
+### Headers configuration ###
+
+## Use of the tm_port_header_type_<Local-Port-Id>=<Header-type>
+## Default header type is derived from fap_device_mode: If fap_device_mode is
+## PP, default header type is ETH. Otherwise, defualt header type is TM.
+## Header type per port can be overriden.
+## All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/UDH_ETH
+## Injected header types: if PTCH, INJECTED (local Port of type TM) or INJECTED_PP (PP)
+## if PTCH-2, INJECTED_2 (local Port of type TM) or INJECTED_2_PP (PP)
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88650=TM
+
+tm_port_header_type_in_0.BCM88650=INJECTED_2
+tm_port_header_type_out_0.BCM88650=TM
+
+tm_port_header_type_in_200.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_200.BCM88650=ETH
+tm_port_header_type_in_201.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_201.BCM88650=ETH
+tm_port_header_type_in_202.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_202.BCM88650=ETH
+tm_port_header_type_in_203.BCM88650=INJECTED_2_PP
+tm_port_header_type_out_203.BCM88650=ETH
+
+
+### Parser Configuration ###
+# Parser has 4 custom macros that are allocated dynamically and
+# configured according to the following features and soc properties:
+# Trill (1 macro) - trill_mode
+# FCoE (2 macros) - bcm886xx_fcoe_switch_mode
+# VxLAN (1 macro) - bcm886xx_vxlan_enable
+# IPv6-Extension-header (2 macros) - bcm886xx_ipv6_ext_hdr_enable
+# UDP (1 macro) - UDP parsing is enabled by default, and can be
+# disabled with soc property custom_feature_udp_parse_disable
+# When disabling UDP parsing VxLAN and 1588oUDP are affected
+
+
+# In FCoE NPV switch, if set to 1,
+# packets that ingress from the N_PORT are treated as bridge
+# and packets that ingress from the NP_PORT are treated as router
+#fcoe_npv_bridge_mode=1
+# Enable IPv6 Extension Header, 0 - disable (default), 1 - enable
+#bcm886xx_ipv6_ext_hdr_enable=1
+
+# Disable UDP parsing, 0 - enable (default), 1 - disable
+#custom_feature_udp_parse_disable=1
+
+#OAMP/SAT port
+#tm_port_header_type_out_232.BCM88650=CPU
+tm_port_header_type_out_232.BCM88675=CPU
+
+### SAT
+## Enable SAT Interface. 0 - Disable, 1 - Enable (Default)
+sat_enable=1
+
+# Set the recycling port processing to be raw (static forwarding)
+tm_port_header_type_rcy.BCM88650=RAW
+
+### RCPU
+# Valid CPU local ports on which RCPU packets can be received by slave device.
+#rcpu_rx_pbmp=0xf00000000000000000000000000000000000000000000000001
+
+#tm_port_header_type_514.BCM88650=RAW
+
+## Header extensions
+# Set if an FTMH Out-LIF extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS
+fabric_ftmh_outlif_extension.BCM88650=IF_MC
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88660: ENABLED, FULL_HASH
+# Options for 88650: ENABLED
+# Options for 88640 compatible: DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY
+# / 16B_STACKING_ROUTE_HISTORY / STANDBY_MC_LB (available only for AradPlus)
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88650=DISABLED
+
+# Set if an OTMH Out-LIF (CUD) Extension is present to Unicast and Multicast packets
+# Options: NEVER / IF_MC (only Multicast packets) / ALWAYS / DOUBLE_TAG (two hop scheduling) / EXTENDED: Extended 24 bit CUD
+# Default: NEVER
+# tm_port_otmh_outlif_ext_mode_13.BCM88650=NEVER
+
+# Set if an OTMH Source-System-Port Extension is present.
+# Option: 0/1
+# Default: 0
+# tm_port_otmh_src_ext_enable_13.BCM88650=0
+
+#Trunk hash format, relevant only for AradPlus. Possible values: NORMAL (default) / INVERTED / DUPLICATED.
+#trunk_hash_format=NORMAL
+
+## Stacking Application
+#stacking_enable.BCM88650=1
+
+## Determine if FTMH Destination System Port Extension is added to all Ethernet packets.
+#ftmh_dsp_extension_add=1
+
+## Determine if FTMH Destination System Port Extension of mirrored/snooped packets is stamped with the original destination.
+#mirror_stamp_sys_on_dsp_ext=1
+
+## System RED
+# Set System-Red functionality.
+#system_red_enable.BCM88650=1
+
+# Indicate the size (Bytes) of a first header to skip
+# before the major header at ingress (e.g. Ethernet, ITMH)
+# It can be set per port also
+first_header_size.BCM88650=0
+
+# Indicate the size (Bytes) of the PMF Extension Headers
+# to remove for TM header type ports (expecting ITMH)
+# Set per port
+#post_headers_size_0.BCM88650=4
+
+# Indicate the size (Bytes) of the User-Headers: configurable
+# headers located in the fabric between internal headers and
+# Ethernet. Their values are set by Ingress FP, and can be used
+# by Egress FP or Egress Editor.
+# units: bits. 4 values can be set:
+# 0 - size of the 1st User-Header, for the Egress PMF. 0b / 8b / 16b
+# 1 - size of the 2nd User-Header, for the Egress PMF. 0b / 8b / 16b
+# The sum of these 2 values should be under 16b
+# 2, 3 - size of the 1st/2nd User-Header, for the Egress Editor.
+# 0b / 8b / 16b / 24b / 32b
+# Each of the global User-Header size must be under 32 bits, but not 24 bits.
+# The Egress FP field is always at the MSB of the User-Header
+# Not available for 88650-A0.
+#field_class_id_size_0.BCM88650=8
+#field_class_id_size_1.BCM88650=0
+#field_class_id_size_2.BCM88650=24
+#field_class_id_size_3.BCM88650=0
+
+
+### Trunk - LAG configuration ###
+# Set the number of LAGs: 1024, 512, 256, 128 or 64
+number_of_trunks.BCM88650=256
+# Using the lb-key's MSB in trunk resolutions.
+# 0 = use LSB (default)
+# 1 = use MSB
+trunk_resolve_use_lb_key_msb_stack = 0
+trunk_resolve_use_lb_key_msb_smooth_division = 0
+
+### SYNCE configuration ###
+## Synchronous Ethernet Signal Mode.
+## Options: TWO_DIFF_CLK, TWO_CLK_AND_VALID. Default: TWO_CLK_AND_VALID
+#sync_eth_mode.BCM88650=TWO_CLK_AND_VALID
+
+## Clock Source (single SerDes) lane in the specified NIF port.
+## Usage: sync_eth_clk_to_nif_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_nif_id_clk_0.BCM88650=1
+#sync_eth_clk_to_nif_id_clk_1.BCM88650=1
+
+## Clock Divider for the selected recovered clock. Valid values: 1/2/4. Default: 1.
+## Usage: sync_eth_clk_divider_clk_<clk_number>=<1/2/4>
+#sync_eth_clk_divider_clk_0.BCM88650=1
+#sync_eth_clk_divider_clk_1.BCM88650=1
+
+## Usage: sync_eth_clk_to_port_id_clk_<clk_number>=<serdes_number>
+#sync_eth_clk_to_port_id_clk_0.BCM88675=13
+#sync_eth_clk_to_port_id_clk_1.BCM88675=13
+
+## Clock frequency selector for the selected recovered clock. Valid values: <125MHz-0/156.25MHz-1/25MHz-2>. Default: 1.
+## Usage: sync_eth_clk_divider_clk<clk_id>=<0-125MHz/1-156.25MHz/2-25MHz>
+#sync_eth_clk_divider_clk0.BCM88675=1
+#sync_eth_clk_divider_clk1.BCM88675=1
+
+## Enable the automatic squelch function for the recovered clock. Valid values: 0/1. Default: 0.
+## Usage: sync_eth_clk_squelch_enable_clk_<clk_number>=<0/1>
+#sync_eth_clk_squelch_enable_clk_0.BCM88650=0
+#sync_eth_clk_squelch_enable_clk_1.BCM88650=0
+
+### ELK configuration ###
+## External lookup (TCAM) Device type select, Indicate the External lookup Device type.
+# Value Options: NONE/NL88650. Default: NONE.
+#ext_tcam_dev_type=NL88650
+
+
+##External lookup (elk) ILKN lanes swap. If set, reverse the lanes numbering order on elk device side. DNX system default is 1.
+#ext_ilkn_reverse=0
+
+## Set ELK FWD table Size.
+# format: ext_xxx_fwd_table_size.
+# where xxx replaced by FWD options: ip4_uc_rpf/ip4_mc/ip6_uc_rpf/ip6/ip6_mc/trill_uc/trill_mc/mpls/coup_mpls
+# Value Options: (0) - External table disabled, >0: number of entries. Default: 0.
+#ext_ip4_uc_rpf_fwd_table_size=8192
+#ext_ip4_mc_fwd_table_size=8192
+
+#External TCAM result size, allows to modify each external tcam result size.
+#The total size of the external result for NL12K = 120bit .
+#The size of each segment updates the corresponding qualifier bcmFieldQualifyExternalValue.
+#Default values according to the device property.
+#in-case of double capacity use the following values: 48,48,24,24 and ext_tcam_result_size_segment_pad_3=24
+
+#ext_tcam_result_size_segment_0=48
+#ext_tcam_result_size_segment_1=32
+#ext_tcam_result_size_segment_2=24
+#ext_tcam_result_size_segment_3=16
+#ext_tcam_result_size_segment_4=32
+#ext_tcam_result_size_segment_5=32
+
+## Set ELK IP FWD use NetRoute ALG.
+# Value Options: ALG_LPM_LPM/ALG_LPM_NETROUTE/ALG_LPM_TCAM. Default: ALG_LPM_TCAM.
+#ext_fwd_algorithm_lpm=ALG_LPM_TCAM
+
+## Set ELK interface mode.
+# Change ELK interface configuration to support CAUI port.
+# Value Options: 0/1. 0 - Normal mode, 1 2 CAUI port + ELK mode. Default: 0.
+#ext_interface_mode=0
+
+### Configure MDIO interface
+# External MDIO clock rate divisor . Default: 0x24.
+#rate_ext_mdio_divisor=0x36
+# External MDIO clock rate divisor. Default: 0x1.
+#rate_ext_mdio_dividend=1
+
+### TDM - OTN configuration ###
+# Options: 0 / TDM_OPTIMIZED / TDM_STANDARD
+fap_tdm_bypass.BCM88650=0
+
+### TDM - RAW/PACKET configuration ###
+# if fap_tdm_packet config to be true, enable specific ports on the device to configure for tdm packet mode traffic.
+fap_tdm_packet.BCM88650=0
+
+# Indicate if a Petra-B device is connected to the actual device
+# For TDM/OTN applications,
+# system_is_petra_b_in_system.BCM88650=0
+##Indicate if TDM can arrive throgh primary pipe.
+#Should be 1 for a System with PetraB that connected to fabric over primary pipe.
+fabric_tdm_over_primary_pipe.BCM88650=0
+
+### Fabric configuration ###
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88650=2
+#Possible values - KR_FEC, 64_66, RS_FEC, LL_RS_FEC
+backplane_serdes_encoding.BCM88675=RS_FEC
+backplane_serdes_encoding.BCM88470=RS_FEC
+backplane_serdes_encoding.BCM88270=RS_FEC
+backplane_serdes_encoding.BCM88680=RS_FEC
+
+#SFI speed rate
+port_init_speed_sfi.BCM88650=10312
+port_init_speed_sfi.BCM88675=25000
+port_init_speed_sfi.BCM88470=25000
+port_init_speed_sfi.BCM88270=25000
+port_init_speed_sfi.BCM88680=25000
+
+#CL72
+port_init_cl72_sfi.BCM88650=1
+port_init_cl72_sfi.BCM88675=1
+fabric_segmentation_enable.BCM88650=1
+
+## Fabric transmission mode
+# Set the Connect mode to the Fabric
+# Options: FE - presence of a Fabric device (single stage) / MULT_STAGE_FE - Multi-stage /
+# SINGLE_FAP - stand-alone device / MESH - mesh / BACK2BACK - 2 devices in Mesh
+#fabric_connect_mode.BCM88650=SINGLE_FAP
+fabric_connect_mode.BCM88650=FE
+# The Jericho configuration below will be overriden in jer.soc for multi device configurations
+fabric_connect_mode.BCM88675=SINGLE_FAP
+fabric_connect_mode.BCM88470=SINGLE_FAP
+fabric_connect_mode.BCM88270=SINGLE_FAP
+fabric_connect_mode.BCM88680=SINGLE_FAP
+
+
+## Cell format configuration
+# Indicate if the traffic can be sent in dual pipe
+is_dual_mode.BCM88650=0
+# Indicate on the existance of dual pipe device mode in system
+system_is_dual_mode_in_system.BCM88650=0
+
+# Indicate the format of the cell:
+# A VCS128 cell is used if system_is_vcs_128_in_system or system_is_fe600_in_system is TRUE
+system_is_vcs_128_in_system.BCM88650=0
+system_is_fe600_in_system.BCM88650=0
+
+### WRED ###
+
+# Set the maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88650=0
+
+### OCB (On-Chip Buffer) configuration ###
+# Enable the OCB
+# Enable MODES:
+# 0/FALSE --> OCB_DISABLED --> No OCB use
+# 1/TRUE --> OCB_ENABLED --> Like in Arad-A0/B0. Some packets may use both DRAM and OCB resources
+# ONE_WAY_BYPASS --> Depends on number of present drams (available only for AradPlus):
+# 0 drams: - OCB_ONLY
+# 1 drams: - OCB_ONLY_1_DRAM --> : OCB-only with 1 DRAM for the free pointers
+# 2-8 drams: - OCB_DRAM_SEPARATE --> : OCB and DRAM coexist separately
+# Default: TRUE.
+bcm886xx_ocb_enable.BCM88650=1
+
+## OCB (On-Chip Buffer) configuration
+# OCB modes:
+# 0 - Disabled
+# 1 - Enabled (Default).
+bcm886xx_ocb_enable.BCM88675=1
+
+# OCB Data Buffer size. Possible values: 128/256/512/1024. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88650=256
+# OCB Data Buffer size. Jericho allowed values: 256/512. Default: 256.
+bcm886xx_ocb_databuffer_size.BCM88675=256
+# Repartition between Unicast and Full Multicast buffers.
+# 0: 80% Unicast and 20% Multicast, 1: Unicast-Only
+bcm886xx_ocb_repartition.BCM88650=0
+
+
+### PDM configuration ###
+# Set the PDM Mode.
+# 0: simple (default), 1: extended (mandatory for LLFC-VSQ, PFC-VSQ, or ST-VSQ)
+bcm886xx_pdm_mode.BCM88650=0
+
+### Multicast Number of DBuff mode ###
+# Set IQM FMC buffers-replication sizes
+# Options for 88650: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE/ARAD_INIT_FMC_64_REP_128K_DBUFF_MODE
+# Default: ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88650=ARAD_INIT_FMC_4K_REP_64K_DBUFF_MODE
+
+### Multicast Number of DBuff mode ###
+# Set FMC buffers-replication sizes
+# Options for 88675:
+# JERICHO_INIT_FMC_64_REP_512K_DBUFF_MODE
+# JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE (Default)
+# JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88675=JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88470=JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88270=JERICHO_INIT_FMC_NO_REP_DBUFF_MODE
+multicast_nbr_full_dbuff.BCM88680=JERICHO_INIT_FMC_4K_REP_256K_DBUFF_MODE
+
+
+### Multicast configuration ###
+# Multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_max.BCM88650=4095
+
+#### Jericho configuration of the number of ingress/egress multicast groups
+# Ingress max MCID can be up to 131070, Egress max MCID in Mesh or single FAP modes is up to 65535,
+# or otherwise is up to 131071.
+#multicast_ingress_group_id_range_max.BCM88675=32768
+#multicast_egress_group_id_range_max.BCM88675=60000
+
+### VOQ - Flow configuration ###
+
+# Set the VOQ mapping mode:
+# DIRECT: More than 4K System Ports are supported. System-level WRED is not supported.
+# INDIRECT: similar to Petra-B. Up to 4K System Ports.
+voq_mapping_mode.BCM88650=INDIRECT
+
+#Enable/disable HQOS support - mapping of many system ports to single modport
+hqos_mapping_enable.BCM88650=0
+
+# Set the Base Queue to be added to the packet flow-id
+# when the Flow-Id is set explicitely either by the ITMH
+# or by the Destination resolution in the Packet processing
+flow_mapping_queue_base.BCM88650=0
+
+
+# The allocation of the total per core resources between source and
+# queue based reservation depends on one of two guarantee modes: strict and loose.
+#ingress_congestion_management_guarantee_mode={STRICT,LOOSE} default: STRICT
+ingress_congestion_management_guarantee_mode=LOOSE
+# Each DP has its own thresholds for source based (dynamic) and for queue based (pools 0,1 and headroom).
+# ingress_congestion_management_{source,queue,all}_threshold_percentage_color_[0-3]=[0-100] default: 100,85,75,0
+# ingress_congestion_management_{ocb_only,dram_mix}_{pool_{0,1},headroom}=size default: 0
+# ingress_congestion_management_min_resource_percentage_dynamic=[0-80] default: 20
+
+# Configure maximum IDs of ST-VSQs, maximum IDs of TM-ports, and enabling/disabling header compensation.
+ingress_congestion_management_stag_max_id.BCM88675=0
+ingress_congestion_management_tm_port_max_id.BCM88675=255
+ingress_congestion_management_pkt_header_compensation_enable.BCM88675=0
+
+# The number of packet buffers used for the allocation of DMA memory at BCM RX task
+# The pool size determined by nof_pkts (256) * 16K.
+#rx_pool_nof_pkts.BCM88675=256
+
+
+# Set the number of priorities supported at egress per Port
+# Options: 1 / 2 / 8
+port_priorities.BCM88650=8
+port_priorities.BCM88675=2
+port_priorities.BCM88470=2
+port_priorities.BCM88270=2
+port_priorities.BCM88680=2
+
+
+# Set the shared multicast resource mode: Strict / Discrete
+egress_shared_resources_mode.BCM88650=Strict
+
+# Define outgoing port rate mode in data rate or packet rate.
+# Options: DATA / PACKET
+otm_port_packet_rate.BCM88650=DATA
+
+# Set Port egress recycling scheduler configuration.
+# 0: Strict Priority Scheduler, 1: Round Robin Scheduler
+port_egress_recycling_scheduler_configuration.BCM88650=0
+
+# Set statically the region mode per region id
+# 0: queue connectors only (InterDigitated = FALSE, OddEven = TRUE)
+# 1: queue connectors, SE (InterDigitated =TRUE, OddEven = TRUE)
+# 2: queue connectors, SE (InterDigitated =TRUE, OddEven = FALSE)
+dtm_flow_mapping_mode_region_65.BCM88650=0
+dtm_flow_mapping_mode_region_66.BCM88650=0
+dtm_flow_mapping_mode_region_67.BCM88650=0
+dtm_flow_mapping_mode_region_68.BCM88650=0
+dtm_flow_mapping_mode_region_69.BCM88650=0
+dtm_flow_mapping_mode_region_70.BCM88650=0
+dtm_flow_mapping_mode_region_71.BCM88650=0
+dtm_flow_mapping_mode_region_72.BCM88650=0
+dtm_flow_mapping_mode_region_73.BCM88650=0
+dtm_flow_mapping_mode_region_74.BCM88650=0
+dtm_flow_mapping_mode_region_75.BCM88650=0
+dtm_flow_mapping_mode_region_76.BCM88650=0
+dtm_flow_mapping_mode_region_77.BCM88650=0
+dtm_flow_mapping_mode_region_78.BCM88650=0
+dtm_flow_mapping_mode_region_79.BCM88650=0
+dtm_flow_mapping_mode_region_80.BCM88650=0
+dtm_flow_mapping_mode_region_81.BCM88650=1
+dtm_flow_mapping_mode_region_82.BCM88650=1
+dtm_flow_mapping_mode_region_83.BCM88650=1
+dtm_flow_mapping_mode_region_84.BCM88650=1
+dtm_flow_mapping_mode_region_85.BCM88650=1
+dtm_flow_mapping_mode_region_86.BCM88650=1
+dtm_flow_mapping_mode_region_87.BCM88650=1
+dtm_flow_mapping_mode_region_88.BCM88650=1
+dtm_flow_mapping_mode_region_89.BCM88650=1
+dtm_flow_mapping_mode_region_90.BCM88650=1
+dtm_flow_mapping_mode_region_91.BCM88650=1
+dtm_flow_mapping_mode_region_92.BCM88650=1
+dtm_flow_mapping_mode_region_93.BCM88650=1
+dtm_flow_mapping_mode_region_94.BCM88650=1
+dtm_flow_mapping_mode_region_95.BCM88650=1
+dtm_flow_mapping_mode_region_96.BCM88650=1
+dtm_flow_mapping_mode_region_97.BCM88650=1
+dtm_flow_mapping_mode_region_98.BCM88650=1
+dtm_flow_mapping_mode_region_99.BCM88650=2
+dtm_flow_mapping_mode_region_100.BCM88650=2
+dtm_flow_mapping_mode_region_101.BCM88650=2
+dtm_flow_mapping_mode_region_102.BCM88650=2
+dtm_flow_mapping_mode_region_103.BCM88650=2
+dtm_flow_mapping_mode_region_104.BCM88650=2
+dtm_flow_mapping_mode_region_105.BCM88650=2
+dtm_flow_mapping_mode_region_106.BCM88650=2
+dtm_flow_mapping_mode_region_107.BCM88650=2
+dtm_flow_mapping_mode_region_108.BCM88650=2
+dtm_flow_mapping_mode_region_109.BCM88650=2
+dtm_flow_mapping_mode_region_110.BCM88650=2
+dtm_flow_mapping_mode_region_111.BCM88650=2
+dtm_flow_mapping_mode_region_112.BCM88650=2
+dtm_flow_mapping_mode_region_113.BCM88650=2
+dtm_flow_mapping_mode_region_114.BCM88650=2
+dtm_flow_mapping_mode_region_115.BCM88650=2
+dtm_flow_mapping_mode_region_116.BCM88650=2
+dtm_flow_mapping_mode_region_117.BCM88650=2
+dtm_flow_mapping_mode_region_118.BCM88650=2
+dtm_flow_mapping_mode_region_119.BCM88650=2
+dtm_flow_mapping_mode_region_120.BCM88650=2
+dtm_flow_mapping_mode_region_121.BCM88650=2
+dtm_flow_mapping_mode_region_122.BCM88650=2
+dtm_flow_mapping_mode_region_123.BCM88650=2
+dtm_flow_mapping_mode_region_124.BCM88650=2
+dtm_flow_mapping_mode_region_125.BCM88650=2
+dtm_flow_mapping_mode_region_126.BCM88650=2
+dtm_flow_mapping_mode_region_127.BCM88650=2
+dtm_flow_mapping_mode_region_128.BCM88650=2
+
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88650=2
+dtm_flow_nof_remote_cores_region_2.BCM88650=2
+dtm_flow_nof_remote_cores_region_3.BCM88650=2
+dtm_flow_nof_remote_cores_region_4.BCM88650=2
+dtm_flow_nof_remote_cores_region_5.BCM88650=2
+dtm_flow_nof_remote_cores_region_6.BCM88650=2
+dtm_flow_nof_remote_cores_region_7.BCM88650=2
+dtm_flow_nof_remote_cores_region_8.BCM88650=2
+dtm_flow_nof_remote_cores_region_9.BCM88650=2
+dtm_flow_nof_remote_cores_region_10.BCM88650=2
+dtm_flow_nof_remote_cores_region_11.BCM88650=2
+dtm_flow_nof_remote_cores_region_12.BCM88650=2
+dtm_flow_nof_remote_cores_region_13.BCM88650=2
+dtm_flow_nof_remote_cores_region_14.BCM88650=2
+dtm_flow_nof_remote_cores_region_15.BCM88650=2
+dtm_flow_nof_remote_cores_region_16.BCM88650=2
+dtm_flow_nof_remote_cores_region_17.BCM88650=2
+dtm_flow_nof_remote_cores_region_18.BCM88650=2
+dtm_flow_nof_remote_cores_region_19.BCM88650=2
+dtm_flow_nof_remote_cores_region_20.BCM88650=2
+dtm_flow_nof_remote_cores_region_21.BCM88650=2
+dtm_flow_nof_remote_cores_region_22.BCM88650=2
+dtm_flow_nof_remote_cores_region_23.BCM88650=2
+dtm_flow_nof_remote_cores_region_24.BCM88650=2
+dtm_flow_nof_remote_cores_region_25.BCM88650=2
+dtm_flow_nof_remote_cores_region_26.BCM88650=2
+dtm_flow_nof_remote_cores_region_27.BCM88650=2
+dtm_flow_nof_remote_cores_region_28.BCM88650=2
+dtm_flow_nof_remote_cores_region_29.BCM88650=2
+dtm_flow_nof_remote_cores_region_30.BCM88650=2
+dtm_flow_nof_remote_cores_region_31.BCM88650=2
+dtm_flow_nof_remote_cores_region_32.BCM88650=2
+dtm_flow_nof_remote_cores_region_33.BCM88650=2
+dtm_flow_nof_remote_cores_region_34.BCM88650=2
+dtm_flow_nof_remote_cores_region_35.BCM88650=2
+dtm_flow_nof_remote_cores_region_36.BCM88650=2
+dtm_flow_nof_remote_cores_region_37.BCM88650=2
+dtm_flow_nof_remote_cores_region_38.BCM88650=2
+dtm_flow_nof_remote_cores_region_39.BCM88650=2
+dtm_flow_nof_remote_cores_region_40.BCM88650=2
+dtm_flow_nof_remote_cores_region_41.BCM88650=2
+dtm_flow_nof_remote_cores_region_42.BCM88650=2
+dtm_flow_nof_remote_cores_region_43.BCM88650=2
+dtm_flow_nof_remote_cores_region_44.BCM88650=2
+dtm_flow_nof_remote_cores_region_45.BCM88650=2
+dtm_flow_nof_remote_cores_region_46.BCM88650=2
+dtm_flow_nof_remote_cores_region_47.BCM88650=2
+dtm_flow_nof_remote_cores_region_48.BCM88650=2
+dtm_flow_nof_remote_cores_region_49.BCM88650=2
+dtm_flow_nof_remote_cores_region_50.BCM88650=2
+dtm_flow_nof_remote_cores_region_51.BCM88650=2
+dtm_flow_nof_remote_cores_region_52.BCM88650=2
+dtm_flow_nof_remote_cores_region_53.BCM88650=2
+dtm_flow_nof_remote_cores_region_54.BCM88650=2
+dtm_flow_nof_remote_cores_region_55.BCM88650=2
+dtm_flow_nof_remote_cores_region_56.BCM88650=2
+dtm_flow_nof_remote_cores_region_57.BCM88650=2
+dtm_flow_nof_remote_cores_region_58.BCM88650=2
+dtm_flow_nof_remote_cores_region_59.BCM88650=2
+dtm_flow_nof_remote_cores_region_60.BCM88650=2
+#dtm_flow_nof_remote_cores_region_core0_2.BCM88675=2
+
+
+# Configure number of symmetric cores each region supports ##
+#device_core_mode.BCM88470=SINGLE_CORE
+# IL region has offset of 63, i.e. region_1 here will show as region 64 in code
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88470=2
+dtm_flow_nof_remote_cores_region_2.BCM88470=2
+dtm_flow_nof_remote_cores_region_3.BCM88470=1
+dtm_flow_nof_remote_cores_region_4.BCM88470=1
+dtm_flow_nof_remote_cores_region_5.BCM88470=2
+dtm_flow_nof_remote_cores_region_6.BCM88470=1
+dtm_flow_nof_remote_cores_region_7.BCM88470=2
+dtm_flow_nof_remote_cores_region_8.BCM88470=2
+dtm_flow_nof_remote_cores_region_9.BCM88470=1
+dtm_flow_nof_remote_cores_region_10.BCM88470=1
+dtm_flow_nof_remote_cores_region_11.BCM88470=1
+dtm_flow_nof_remote_cores_region_12.BCM88470=1
+dtm_flow_nof_remote_cores_region_13.BCM88470=1
+dtm_flow_nof_remote_cores_region_14.BCM88470=1
+dtm_flow_nof_remote_cores_region_15.BCM88470=1
+dtm_flow_nof_remote_cores_region_16.BCM88470=1
+dtm_flow_nof_remote_cores_region_17.BCM88470=1
+dtm_flow_nof_remote_cores_region_18.BCM88470=2
+dtm_flow_nof_remote_cores_region_19.BCM88470=1
+dtm_flow_nof_remote_cores_region_20.BCM88470=1
+dtm_flow_nof_remote_cores_region_21.BCM88470=1
+dtm_flow_nof_remote_cores_region_22.BCM88470=1
+dtm_flow_nof_remote_cores_region_23.BCM88470=1
+dtm_flow_nof_remote_cores_region_24.BCM88470=1
+dtm_flow_nof_remote_cores_region_25.BCM88470=1
+dtm_flow_nof_remote_cores_region_26.BCM88470=1
+dtm_flow_nof_remote_cores_region_27.BCM88470=1
+dtm_flow_nof_remote_cores_region_28.BCM88470=1
+dtm_flow_nof_remote_cores_region_29.BCM88470=1
+dtm_flow_nof_remote_cores_region_30.BCM88470=1
+dtm_flow_nof_remote_cores_region_31.BCM88470=1
+dtm_flow_nof_remote_cores_region_32.BCM88470=1
+dtm_flow_nof_remote_cores_region_33.BCM88470=1
+dtm_flow_nof_remote_cores_region_34.BCM88470=1
+dtm_flow_nof_remote_cores_region_35.BCM88470=1
+dtm_flow_nof_remote_cores_region_36.BCM88470=1
+
+dtm_flow_nof_remote_cores_region_37.BCM88470=1
+dtm_flow_nof_remote_cores_region_38.BCM88470=1
+dtm_flow_nof_remote_cores_region_39.BCM88470=1
+dtm_flow_nof_remote_cores_region_40.BCM88470=1
+dtm_flow_nof_remote_cores_region_41.BCM88470=1
+dtm_flow_nof_remote_cores_region_42.BCM88470=1
+dtm_flow_nof_remote_cores_region_43.BCM88470=1
+dtm_flow_nof_remote_cores_region_44.BCM88470=1
+dtm_flow_nof_remote_cores_region_45.BCM88470=1
+dtm_flow_nof_remote_cores_region_46.BCM88470=1
+dtm_flow_nof_remote_cores_region_47.BCM88470=1
+dtm_flow_nof_remote_cores_region_48.BCM88470=1
+dtm_flow_nof_remote_cores_region_49.BCM88470=1
+dtm_flow_nof_remote_cores_region_50.BCM88470=1
+dtm_flow_nof_remote_cores_region_51.BCM88470=1
+dtm_flow_nof_remote_cores_region_52.BCM88470=1
+dtm_flow_nof_remote_cores_region_53.BCM88470=1
+dtm_flow_nof_remote_cores_region_54.BCM88470=1
+dtm_flow_nof_remote_cores_region_55.BCM88470=1
+dtm_flow_nof_remote_cores_region_56.BCM88470=1
+dtm_flow_nof_remote_cores_region_57.BCM88470=1
+dtm_flow_nof_remote_cores_region_58.BCM88470=1
+dtm_flow_nof_remote_cores_region_59.BCM88470=1
+dtm_flow_nof_remote_cores_region_60.BCM88470=1
+
+dtm_flow_mapping_mode_region_33.BCM88470=0
+dtm_flow_mapping_mode_region_34.BCM88470=0
+dtm_flow_mapping_mode_region_35.BCM88470=0
+dtm_flow_mapping_mode_region_36.BCM88470=0
+dtm_flow_mapping_mode_region_37.BCM88470=0
+dtm_flow_mapping_mode_region_38.BCM88470=0
+dtm_flow_mapping_mode_region_39.BCM88470=0
+dtm_flow_mapping_mode_region_40.BCM88470=0
+
+## Configure number of symmetric cores each region supports ##
+dtm_flow_nof_remote_cores_region_1.BCM88270=2
+dtm_flow_nof_remote_cores_region_2.BCM88270=2
+dtm_flow_nof_remote_cores_region_3.BCM88270=2
+dtm_flow_nof_remote_cores_region_4.BCM88270=2
+dtm_flow_nof_remote_cores_region_5.BCM88270=2
+dtm_flow_nof_remote_cores_region_6.BCM88270=2
+dtm_flow_nof_remote_cores_region_7.BCM88270=2
+dtm_flow_nof_remote_cores_region_8.BCM88270=2
+dtm_flow_nof_remote_cores_region_9.BCM88270=2
+dtm_flow_nof_remote_cores_region_10.BCM88270=2
+dtm_flow_nof_remote_cores_region_11.BCM88270=2
+dtm_flow_nof_remote_cores_region_12.BCM88270=2
+dtm_flow_nof_remote_cores_region_13.BCM88270=2
+dtm_flow_nof_remote_cores_region_14.BCM88270=2
+dtm_flow_nof_remote_cores_region_15.BCM88270=2
+dtm_flow_nof_remote_cores_region_16.BCM88270=2
+dtm_flow_nof_remote_cores_region_17.BCM88270=2
+dtm_flow_nof_remote_cores_region_18.BCM88270=2
+dtm_flow_nof_remote_cores_region_19.BCM88270=1
+dtm_flow_nof_remote_cores_region_20.BCM88270=1
+dtm_flow_nof_remote_cores_region_21.BCM88270=1
+dtm_flow_nof_remote_cores_region_22.BCM88270=1
+dtm_flow_nof_remote_cores_region_23.BCM88270=1
+dtm_flow_nof_remote_cores_region_24.BCM88270=1
+dtm_flow_nof_remote_cores_region_25.BCM88270=1
+dtm_flow_nof_remote_cores_region_26.BCM88270=1
+dtm_flow_nof_remote_cores_region_27.BCM88270=1
+dtm_flow_nof_remote_cores_region_28.BCM88270=1
+dtm_flow_nof_remote_cores_region_29.BCM88270=1
+dtm_flow_nof_remote_cores_region_30.BCM88270=1
+dtm_flow_nof_remote_cores_region_31.BCM88270=1
+dtm_flow_nof_remote_cores_region_32.BCM88270=1
+
+dtm_flow_mapping_mode_region_17.BCM88270=0
+dtm_flow_mapping_mode_region_18.BCM88270=0
+dtm_flow_mapping_mode_region_19.BCM88270=0
+dtm_flow_mapping_mode_region_20.BCM88270=0
+
+### Flow Control configuration ###
+# Set the Flow control type per Port.
+# Options: LL (Link-level) / CB2 (Class-Based - 2 classes) /
+# CB8 (Class-Based - 8 classes)
+# flow_control_type.BCM88650=LL
+
+## Out-Of-Band Flow control configuration
+#spn_FC_OOB_TYPE, spn_FC_OOB_MODE, spn_FC_OOB_CALENDER_LENGTH, spn_FC_OOB_CALENDER_REP_COUNT,
+
+## Set voltage mode for oob interfaces
+#HSTL_1.5V
+#3.3V
+#HSTL_1.5V_VDDO_DIV_2
+ext_voltage_mode_oob=3.3V
+
+## Inband Interlaken configuration
+# spn_FC_INBAND_INTLKN_MODE, spn_FC_INBAND_INTLKN_CALENDER_LENGTH, spn_FC_INBAND_INTLKN_CALENDER_REP_COUNT
+# spn_FC_INBAND_INTLKN_CALENDER_LLFC_MODE, spn_FC_INBAND_INTLKN_LLFC_MUB_ENABLE_MASK
+
+### Meter engine configuration ###
+
+# Specify meter operation mode
+# 32 - Two meters per packet (32k total)
+# 64 - One meter per packet (64k total) or two meter per packet in dual core device configured as SINGLE_CORE (128K total)
+# 128 - One meter per packet in dual core device configured as SINGLE_CORE (128K total)
+# Options: 0, 32, 64, 128
+policer_ingress_count.BCM88650=32
+policer_ingress_count.BCM88470=32
+policer_ingress_count.BCM88270=32
+policer_ingress_count.BCM88680=32
+
+
+# For meters in double 32k/64K mode, determine the sharing mode
+# Options:
+# 0 - NONE - For 64k or 128K (one meter per packet)
+# 1 - SERIAL - 32k mode only (two meters per packet)
+# 2 - PARALLEL - For 32k or 64k (two meter per packet)
+policer_ingress_sharing_mode.BCM88650=1
+policer_ingress_sharing_mode.BCM88470=1
+policer_ingress_sharing_mode.BCM88270=1
+policer_ingress_sharing_mode.BCM88680=1
+
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine the mapping
+# Options: BEST, WORST
+# policer_result_parallel_color_map.BCM88650=WORST
+
+# Applies only to Arad+ (88660)
+# For meters in parallel mode, determine how the buckets are changed
+# Options: CONSTANT, TRANSPARENT, DEFERRED
+# policer_result_parallel_bucket_update.BCM88650=CONSTANT
+
+# Applies only to Arad+ (88660)
+# Set the Ethernet policer to work in color blind mode
+# rate_color_blind.BCM88650=1
+
+# L2 learn limit mode
+# Options: VLAN, VLAN_PORT, TUNNEL or the numeric equivalent 0-2.
+# Default: VLAN
+# l2_learn_limit_mode = VLAN_PORT
+
+# Applies only to Arad+ (88660)
+# Determines the L2 learn limit ranges when l2_learn_limit_mode is set to VLAN_PORT
+# Two range bases can be selected, each of 16K size.
+# Options: 0, 16K, 32K, 48K.
+# Default: 0 & 16K
+# l2_learn_lif_range_base_0 = 0
+# l2_learn_lif_range_base_1 = 16K
+
+# SW shadow mode for exact match tables. Required for SER support and DBAL diagnostics.
+# 0 - Disabled (Default)
+# 1 - Enabled
+# 2 - Disabled for LEM, enabled for other exact match tables
+exact_match_tables_shadow_enable.BCM88650 = 1
+exact_match_tables_shadow_enable.BCM88675 = 2
+
+# determine how many cmcs connected to the CPU.
+# default value = 1
+# applies only to jericho and above.
+pci_cmcs_num.88675 = 3
+pci_cmcs_num.88470 = 3
+
+### Counter engine configuration ###
+
+# Set the Counter source
+# Options: INGRESS_FIELD / INGRESS_VOQ / INGRESS_VSQ / INGRESS_CNM /
+# INGRESS_LATENCY / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM (per queue) / EGRESS_TM_PORT (per port)
+# EGRESS_RECEIVE_VSI / EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM (per queue) / EGRESS_RECEIVE_TM_PORT (per port)
+# INGRESS_OAM / EGRESS_OAM
+# 2 Counter-Pointers can be set (with _0 and _1) for
+# INGRESS_FIELD / EGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT
+# Range extension can be set (with _LSB and _MSB) for
+# INGRESS_FIELD / EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT /EGRESS_RECEIVE_VSI /
+# EGRESS_RECEIVE_OUT_LIF / EGRESS_RECEIVE_TM / EGRESS_RECEIVE_TM_PORT
+counter_engine_source_0.BCM88650=INGRESS_FIELD_0
+counter_engine_source_1.BCM88650=INGRESS_FIELD_1
+counter_engine_source_2.BCM88650=INGRESS_VOQ
+counter_engine_source_3.BCM88650=EGRESS_FIELD
+
+# Configure the statistic interface egress transmit PP source and the ingress received PP source
+# Options for egress: EGRESS_VSI / EGRESS_OUT_LIF / EGRESS_TM / EGRESS_TM_PORT (the default is TM)
+# Options for ingress: INGRESS_VSI / INGRESS_IN_LIF / INGRESS_TM (the default is TM)
+# valid just when there is no conflict with the other counter engines
+#counter_engine_source_egress_pp_stat0.BCM88650=EGRESS_TM
+#counter_engine_source_egress_pp_stat1.BCM88650=EGRESS_VSI
+#counter_engine_source_ingress_pp_stat0.BCM88650=INGRESS_IN_LIF
+#counter_engine_source_ingress_pp_stat1.BCM88650=INGRESS_TM
+
+
+# Set the Counter engine resolution
+# SIMPLE_COLOR = green, not green
+# SIMPLE_COLOR_FWD = fwd green, fwd not green (BCM88660_A0 only)
+# SIMPLE_COLOR_DROP = drop green, drop not green (BCM88660_A0 only)
+# FWD_DROP = forwarded, dropped
+# GREEN_NOT_GREEN = fwd grn, drop grn, fwd not grn, drop not grn
+# FULL_COLOR = fwd grn, drop grn, fwd not grn, drop yel, drop red
+# ALL = received
+# FWD = forwarded, DROP = droped (not supported by ARAD_A0)
+# CONFIGURABLE = defined by counter_engine_map_ SOC properties (BCM88660_A0 only)
+counter_engine_statistics_0.BCM88650=FULL_COLOR
+counter_engine_statistics_1.BCM88650=FULL_COLOR
+counter_engine_statistics_2.BCM88650=FULL_COLOR
+counter_engine_statistics_3.BCM88650=FULL_COLOR
+
+# Set the Counter format
+# Options: PACKETS_AND_BYTES / PACKETS / BYTES
+# / MAX_QUEUE_SIZE / LATENCY / PACKETS_AND_PACKETS(supported just in FWD_DROP statistic in BCM88660_A0)
+# If not PACKETS_AND_BYTES or PACKETS_AND_PACKETS, the HW Counter width is 59 bits, thus
+# no background SW operation is performed
+counter_engine_format_0.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_1.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_2.BCM88650=PACKETS_AND_BYTES
+counter_engine_format_3.BCM88650=PACKETS_AND_BYTES
+
+# #enable/disable counter processor background thread (default:1-enable)
+# counter_engine_sampling_interval=1
+
+
+### Configurable mode configuration (BCM88660_A0 only)###
+# counter_engine_statistics_0.BCM88660_A0=CONFIGURABLE
+# counter_engine_map_enable_0.BCM88660_A0=1
+# counter_engine_map_size_0.BCM88660_A0=4
+# counter_engine_map_fwd_green_offset_0.BCM88660_A0=0
+# counter_engine_map_fwd_yellow_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_red_offset_0.BCM88660_A0=1
+# counter_engine_map_fwd_black_offset_0.BCM88660_A0=2
+# counter_engine_map_drop_green_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_yellow_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_red_offset_0.BCM88660_A0=3
+# counter_engine_map_drop_black_offset_0.BCM88660_A0=3
+
+### Statistic-Report configuration ###
+# Enable the Statistic-Interface configuration
+# stat_if_enable_<port> - not supported by ARAD_A0
+# stat_if_enable.BCM88650=1
+
+# ## Statistic-Report Properties
+# # Set Statistic-Report interface rate in Mbps
+# # If Value is '0' the statistics port rate will be used. Default: 0.
+# stat_if_rate.BCM88650=0
+# # Set the Statistic-Report mode
+# # Options: BILLING / BILLING_QUEUE_NUMBER (not supported by ARAD_A0)/ QSIZE
+# stat_if_report_mode.BCM88650=QSIZE
+# #Indicate if idle reports must be sent
+# #when the Statistic-report rate is too low
+# stat_if_idle_reports_present.BCM88650=0
+# # Indicate if the reported packet size is the original packet size
+# stat_if_report_original_pkt_size.BCM88650=1
+# #If set then a single ingress-billing report will be generated
+# #for the whole set of the multicast copies
+# stat_if_report_multicast_single_copy=1
+# ## Statistic Packet configurations
+# # Set the Statistic Packet size (Bytes)
+# # Valid values: 65B/126B/248B/492B (Queue-Size), 64B/128B/256B/512B/1024B (Billing).
+# stat_if_pkt_size=64B
+#
+# ## Scrubber configuration
+# # Set the range of VOQs to scrub. Range: 0 - 96K-1.
+# stat_if_scrubber_queue_min.BCM88650=0
+# stat_if_scrubber_queue_max.BCM88650=0
+#
+# # Set the scrubber rate range
+# # If set to 0 (default), the scrubber is disabled. Units: nanoseconds
+# stat_if_scrubber_rate_min.BCM88650=0
+# stat_if_scrubber_rate_max.BCM88650=0
+#
+# # Set the thresholds (thresh_id 0 - 15) defining
+# # occupancy range per resource type:
+# # DRAM Buffers, Buffer descriptors, Buffer descriptors buffers
+# stat_if_scrubber_bdb_th.BCM88650=0
+# stat_if_scrubber_buffer_descr_th.BCM88650=0
+# stat_if_uc_dram_buffer_descr_th.BCM88650=0
+#
+# #Relective report for queue size mode - not supported by ARAD_A0
+# #Reports will be created for queue num range (stat_if_selective_report_queue_min -stat_if_selective_report_queue_max)
+# #Default - all range
+# stat_if_selective_report_queue_min.BCM88650_B0=0
+# stat_if_selective_report_queue_max.BCM88650_B0=98303
+
+### Transaction - DMA configuration ###
+# Time to wait for SCHAN channel response (from CMIC). Units: microseconds.
+
+
+### Counter threads ###
+# # set port bitmap on which statistics collection will be enabled (default all ports)
+# bcm_stat_pbmp.BCM88675=0xfffffffff000000000000000000000000000000000000000000000000000000000003e002
+#
+# # set statistics collection interval in microseconds (default is 1000000)
+# bcm_stat_interval.BCM88675=1000000
+
+### Control optimization of cosq port initializations: speed for memory ###
+runtime_performance_optimize_enable_sched_allocation.BCM88650=1
+runtime_performance_optimize_enable_sched_allocation.BCM88675=1
+
+### static tables initiation (Supported for Jericho) ###
+# Options: 1 - initiating static tables, 0 - doesn't initiate tables (Default Value for PCID/emulation)
+#custom_feature_static_tbl_full_init.BCM88675=1
+#custom_feature_dynamic_tbl_full_init.BCM88675=1
+
+### Interrupts ###
+## Set interrupts global parameters.
+# Options: 1 - Polling interrupt mode, 0 - Line/MSI interrupt mode. Default: 1.
+polled_irq_mode.BCM88650=0
+polled_irq_mode.BCM88675=0
+# Set the delay in microsecond between the polling, relevant only to Polling mode. Default: 0x0.
+polled_irq_delay.BCM88650=50000
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling, relevant only to Polling completion mode.
+# SCHAN:
+#schan_intr_enable.0=1
+schan_timeout_usec.BCM88650=300000
+# TDMA
+tdma_intr_enable.BCM88650=1
+tdma_intr_enable.BCM88675=0
+tdma_timeout_usec.BCM88650=5000000
+tdma_timeout_usec.BCM88675=560000000
+# TSLAM
+tslam_intr_enable.BCM88650=1
+tslam_intr_enable.BCM88675=0
+tslam_timeout_usec.BCM88650=5000000
+tslam_timeout_usec.BCM88675=560000000
+# MIIM
+#miim_intr_enable.0=1
+miim_timeout_usec.0=300000
+
+### DRAM configuration ###
+
+# DRAM buffer (Dbuff) size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88650=1024
+ext_ram_dbuff_size.BCM88470=4096
+ext_ram_dbuff_size.BCM88270=4096
+
+# Number of external DRAMs.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# Allowed values for 88660: 0/1/2/3/4/6/8. A value of 1 is permitted only in ONE WAY BYPASS ocb mode.
+# Allowed values for 88675: 0/2/3/41/42/6/8. '41' - configure 4 drams in Single Side mode (A, B, C, D).
+# '42' - configure 4 drams in symmetric mode (A, C, F, H).
+# Value of 0 disables the DRAM.
+ext_ram_present.BCM88650=8
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+ext_ram_present.BCM88470=3
+ext_ram_present.BCM88270=1
+
+### Dram Tuning (Shmoo)
+# 3 = Skip Dram Tuning (Shmoo).
+# 2 = Use Dram saved config Parameters, if no Parameters Perform Shmoo on init. Default option.
+# 1 = Perform Shmoo on init.
+# 0 = Use Dram saved config Parameters, if no Parameters do nothing.
+ddr3_auto_tune.BCM88650=2
+ddr3_auto_tune.BCM88270=2
+ddr3_auto_tune.BCM88470=2
+
+##### DDR Tuning parameters for IL SVK4
+combo28_tune_dq_wr_min_vdl_byte3_ci1.0=0x00000004,0x00000003,0x00000007,0x00000003,0x00000002,0x00000000,0x00000006,0x00000004,
+combo28_tune_dq_rd_min_vdl_byte1_ci2.0=0x00000017,0x00000014,0x00000016,0x00000014,0x00000017,0x00000018,0x00000017,0x00000017,
+combo28_tune_common_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci1.0=0x00000003,
+combo28_tune_control_regs_read_clock_config_ci0.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci0.0=0x00000018,0x00000017,0x00000017,0x00000018,0x00000017,0x00000014,0x00000015,0x00000017,
+combo28_tune_dq_read_max_vdl_fsm_ci1.0=0x0000004c,0x0000004c,0x0000004c,0x0000004c,
+combo28_tune_aq_u_max_vdl_ctrl_ci1.0=0x00000214,
+combo28_tune_dq_rd_max_vdl_dqsn_ci1.0=0x00000017,0x00000019,0x0000002d,0x0000002d,
+combo28_tune_dq_ren_fifo_config_ci0.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_wr_min_vdl_dbi_ci1.0=0x00000001,0x00000004,0x00000002,0x00000003,
+combo28_tune_aq_u_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_dq_rd_min_vdl_edc_ci1.0=0x00000016,0x00000016,0x00000017,0x0000001a,
+combo28_tune_aq_l_max_vdl_addr_ci1.0=0x00000214,
+combo28_tune_dq_wr_max_vdl_data_ci2.0=0x00000238,0x00000406,0x00000247,0x00000416,
+combo28_tune_dq_wr_min_vdl_byte3_ci2.0=0x00000000,0x00000003,0x00000000,0x00000000,0x00000000,0x00000003,0x00000001,0x00000001,
+combo28_tune_common_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci2.0=0x00000003,
+combo28_tune_control_regs_read_clock_config_ci1.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci1.0=0x00000015,0x00000015,0x00000019,0x00000017,0x00000014,0x00000016,0x00000018,0x00000016,
+combo28_tune_dq_read_max_vdl_fsm_ci2.0=0x0000004d,0x0000004d,0x0000004d,0x0000004d,
+combo28_tune_aq_u_max_vdl_ctrl_ci2.0=0x00000048,
+combo28_tune_dq_rd_max_vdl_dqsn_ci2.0=0x00000023,0x00000022,0x0000002c,0x00000020,
+combo28_tune_dq_ren_fifo_config_ci1.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_wr_min_vdl_dbi_ci2.0=0x00000002,0x00000001,0x00000003,0x00000001,
+combo28_tune_aq_u_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_dq_rd_min_vdl_edc_ci2.0=0x00000016,0x00000017,0x00000016,0x00000017,
+combo28_tune_aq_l_max_vdl_addr_ci2.0=0x00000048,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci0.0=0x0000000f,
+combo28_tune_common_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_read_clock_config_ci2.0=0x00000002,
+combo28_tune_dq_rd_min_vdl_byte2_ci2.0=0x00000018,0x00000016,0x00000015,0x00000014,0x00000015,0x00000015,0x00000014,0x00000015,
+combo28_tune_dq_wr_min_vdl_byte0_ci0.0=0x00000001,0x00000002,0x00000000,0x00000002,0x00000002,0x00000003,0x00000004,0x00000001,
+combo28_tune_dq_ren_fifo_config_ci2.0=0x00000090,0x00000090,0x00000090,0x00000090,
+combo28_tune_dq_rd_min_vdl_byte3_ci0.0=0x00000019,0x00000017,0x0000001a,0x0000001c,0x00000017,0x00000018,0x00000014,0x00000014,
+combo28_tune_aq_u_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci1.0=0x0000000f,
+combo28_tune_aq_l_max_vdl_ctrl_ci0.0=0x00000201,
+combo28_tune_control_regs_input_shift_ctrl_ci0.0=0x00000070,
+combo28_tune_dq_wr_min_vdl_byte0_ci1.0=0x00000005,0x00000001,0x00000000,0x00000000,0x00000001,0x00000000,0x00000000,0x00000003,
+combo28_tune_dq_rd_min_vdl_byte3_ci1.0=0x00000018,0x00000017,0x0000001c,0x0000001d,0x00000014,0x00000017,0x0000001e,0x0000001d,
+combo28_tune_control_regs_ren_fifo_central_initializer_ci2.0=0x0000000f,
+combo28_tune_dq_rd_max_vdl_dqsp_ci0.0=0x00000018,0x00000019,0x00000025,0x0000002b,
+combo28_tune_aq_l_max_vdl_ctrl_ci1.0=0x00000214,
+combo28_tune_control_regs_input_shift_ctrl_ci1.0=0x00000070,
+combo28_tune_dq_wr_min_vdl_byte0_ci2.0=0x00000000,0x00000005,0x00000003,0x00000003,0x00000003,0x00000003,0x00000003,0x00000002,
+combo28_tune_dq_wr_min_vdl_edc_ci0.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_rd_min_vdl_byte3_ci2.0=0x00000015,0x00000017,0x00000014,0x00000015,0x00000016,0x00000018,0x00000018,0x00000019,
+combo28_tune_dq_wr_min_vdl_byte1_ci0.0=0x00000002,0x00000002,0x00000002,0x00000003,0x00000002,0x00000001,0x00000002,0x00000000,
+combo28_tune_control_regs_edcen_fifo_central_init_ci0.0=0x00000000,
+combo28_tune_dq_macro_reserved_reg_ci0.0=0x00000026,0x00000026,0x00000025,0x00000026,
+combo28_tune_dq_rd_max_vdl_dqsp_ci1.0=0x00000017,0x00000019,0x0000002d,0x0000002d,
+combo28_tune_aq_l_max_vdl_ctrl_ci2.0=0x00000048,
+combo28_tune_control_regs_input_shift_ctrl_ci2.0=0x00000070,
+combo28_tune_dq_rd_min_vdl_dbi_ci0.0=0x00000016,0x00000017,0x00000017,0x00000018,
+combo28_tune_dq_wr_min_vdl_edc_ci1.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_wr_min_vdl_byte1_ci1.0=0x00000006,0x00000007,0x00000005,0x00000005,0x00000000,0x00000001,0x00000007,0x00000005,
+combo28_tune_dq_edcen_fifo_config_ci0.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_control_regs_edcen_fifo_central_init_ci1.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci0.0=0x00760000,0x00740000,0x00800000,0x007c0000,
+combo28_tune_dq_macro_reserved_reg_ci1.0=0x00000026,0x0000002a,0x00000028,0x00000029,
+combo28_tune_dq_rd_max_vdl_dqsp_ci2.0=0x00000023,0x00000022,0x0000002c,0x00000020,
+combo28_tune_dq_rd_min_vdl_byte0_ci0.0=0x00000016,0x00000014,0x00000014,0x00000016,0x00000015,0x00000015,0x00000016,0x00000016,
+combo28_tune_dq_rd_min_vdl_dbi_ci1.0=0x00000016,0x00000016,0x00000017,0x0000001a,
+combo28_tune_aq_u_max_vdl_addr_ci0.0=0x00000201,
+combo28_tune_dq_wr_max_vdl_dqs_ci0.0=0x00000440,0x0000044a,0x00000422,0x00000430,
+combo28_tune_dq_wr_min_vdl_edc_ci2.0=0x00000000,0x00000000,0x00000000,0x00000000,
+combo28_tune_dq_wr_min_vdl_byte1_ci2.0=0x00000003,0x00000000,0x00000002,0x00000001,0x00000002,0x00000001,0x00000004,0x00000001,
+combo28_tune_dq_edcen_fifo_config_ci1.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_control_regs_edcen_fifo_central_init_ci2.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci1.0=0x007e0000,0x007a0000,0x00820000,0x00820000,
+combo28_tune_dq_macro_reserved_reg_ci2.0=0x00000028,0x00000028,0x0000002a,0x0000002b,
+combo28_tune_dq_wr_min_vdl_byte2_ci0.0=0x00000001,0x00000000,0x00000003,0x00000002,0x00000005,0x00000005,0x00000003,0x00000005,
+combo28_tune_dq_rd_min_vdl_byte0_ci1.0=0x00000015,0x00000017,0x00000017,0x00000017,0x00000017,0x00000015,0x00000014,0x00000015,
+combo28_tune_dq_rd_min_vdl_dbi_ci2.0=0x00000016,0x00000017,0x00000016,0x00000017,
+combo28_tune_control_regs_shared_vref_dac_config_ci0.0=0x00920000,
+combo28_tune_aq_u_max_vdl_addr_ci1.0=0x00000214,
+combo28_tune_dq_wr_max_vdl_dqs_ci1.0=0x00000440,0x00000446,0x0000042d,0x00000434,
+combo28_tune_dq_edcen_fifo_config_ci2.0=0x00000080,0x00000080,0x00000080,0x00000080,
+combo28_tune_aq_l_macro_reserved_reg_ci0.0=0x00000000,
+combo28_tune_dq_vref_dac_config_ci2.0=0x00840000,0x007e0000,0x008a0000,0x00820000,
+combo28_tune_dq_wr_min_vdl_byte2_ci1.0=0x00000000,0x00000001,0x00000002,0x00000004,0x00000003,0x00000000,0x00000004,0x00000007,
+combo28_tune_dq_rd_min_vdl_byte0_ci2.0=0x00000014,0x00000015,0x00000015,0x00000014,0x00000016,0x00000017,0x00000015,0x00000016,
+combo28_tune_control_regs_shared_vref_dac_config_ci1.0=0x00920000,
+combo28_tune_aq_u_max_vdl_addr_ci2.0=0x00000048,
+combo28_tune_dq_wr_max_vdl_dqs_ci2.0=0x00000424,0x00000435,0x0000043c,0x00000444,
+combo28_tune_dq_rd_min_vdl_byte1_ci0.0=0x00000017,0x00000017,0x00000018,0x00000018,0x00000014,0x00000015,0x00000015,0x00000015,
+combo28_tune_aq_l_macro_reserved_reg_ci1.0=0x00000000,
+combo28_tune_dq_wr_min_vdl_byte2_ci2.0=0x00000004,0x00000000,0x00000004,0x00000005,0x00000002,0x00000003,0x00000004,0x00000004,
+combo28_tune_dq_wr_max_vdl_data_ci0.0=0x00000416,0x00000428,0x00000232,0x00000241,
+combo28_tune_control_regs_shared_vref_dac_config_ci2.0=0x00920000,
+combo28_tune_dq_wr_min_vdl_byte3_ci0.0=0x00000005,0x00000005,0x00000005,0x00000004,0x00000003,0x00000003,0x00000003,0x00000000,
+combo28_tune_dq_rd_min_vdl_byte1_ci1.0=0x00000018,0x00000018,0x00000018,0x00000014,0x00000014,0x00000014,0x00000018,0x00000014,
+combo28_tune_aq_l_macro_reserved_reg_ci2.0=0x00000000,
+combo28_tune_control_regs_reserved_reg_ci0.0=0x00000003,
+combo28_tune_dq_read_max_vdl_fsm_ci0.0=0x0000004b,0x0000004b,0x0000004b,0x0000004b,
+combo28_tune_aq_u_max_vdl_ctrl_ci0.0=0x00000201,
+combo28_tune_dq_rd_max_vdl_dqsn_ci0.0=0x00000018,0x00000019,0x00000025,0x0000002b,
+combo28_tune_dq_wr_min_vdl_dbi_ci0.0=0x00000001,0x00000001,0x00000003,0x00000003,
+combo28_tune_dq_rd_min_vdl_edc_ci0.0=0x00000016,0x00000017,0x00000017,0x00000018,
+combo28_tune_aq_l_max_vdl_addr_ci0.0=0x00000201,
+combo28_tune_dq_wr_max_vdl_data_ci1.0=0x00000414,0x0000041e,0x00000234,0x00000245,
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Defult: 1.
+# bist_enable_dram.BCM88650=1
+bist_enable_dram.BCM88270=1
+bist_enable_dram.BCM88470=1
+
+### Example for Dram Saved config Parameters.
+## This example is for ci=14 (Dram=7).
+#ddr3_tune_addrc_ci14=0x000000ae
+#ddr3_tune_wr_dq_wl1_ci14=0x92929292,0x92929292,0x92929292,0x92929292
+#ddr3_tune_wr_dq_wl0_ci14=0x93939393,0x93939393,0x92929292,0x92929292
+#ddr3_tune_wr_dq_ci14=0x80808080
+#ddr3_tune_vref_ci14=0x000007df
+#ddr3_tune_rd_dqs_ci14=0x96969191,0x90909191
+#ddr3_tune_rd_dq_wl1_rn_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rn_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_dq_wl1_rp_ci14=0x82828282,0x82828282,0x82828282,0x82828282
+#ddr3_tune_rd_dq_wl0_rp_ci14=0x82828282,0x82828282,0x89898989,0x89898989
+#ddr3_tune_rd_en_ci14=0x009d9e9d,0x00a2a3a1
+#ddr3_tune_rd_data_dly_ci14=0x00000505
+
+
+### Dram type: Select ONLY ONE of the following DRAM types, to configure all dram related parameteres per type.
+
+# Dram Type for Arad:
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_933=1
+#dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_800=1
+#dram_type_DDR3_MICRON_MT41J256M16_4GBIT_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_1066=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_933=1
+#dram_type_DDR3_MICRON_MT41J128M16HA_125_800=1
+#dram_type_DDR3_MICRON_MT42J64M16LA_15E_667=1
+#dram_type_DDR3_SAMSUNG_K4B4G1646B_4GBIT_1066=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_933=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646G_800=1
+
+# Dram Type for Jericho:
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#dram_type_DDR4_MICRON_Y4016AABG_JD_F_4GBIT=1
+dram_type_DDR4_MICRON_MT40A256M16HA_083EA_4GBIT=1
+#dram_type_DDR4_HYNIX_H5AN4G6NMFR_VJC_4GBIT=1
+#dram_type_GDDR5_SAMSUNG_K4G20325FD_2GBIT=1
+#dram_type_GDDR5_SAMSUNG_K4G41325FC_4GBIT=1
+#dram_type_GDDR5_MICRON_EDW4032CABG_4GBIT=1
+#dram_type_GDDR5_HYNIX_H5GC4H24MFR_T2C_4GBIT=1
+
+# Dram Type for Ardon:
+#dram_type_DDR4_MICRON_EDY4016AABG_DRFR_4GBIT=1
+
+# DRAM frequency
+ext_ram_freq.BCM88675=1600
+
+### Setting dram_type_DDR3_HYNIX_H5TQ2G63BFR_TEC_1066 Parameters as Default:
+## All other dram types parameter resides in arad.soc. choosing another Dram Type will override the following parameters.
+ext_ram_t_rrd=6000
+ext_ram_columns=1024
+ext_ram_banks=8
+ext_ram_ap_bit_pos=10
+ext_ram_burst_size=32
+ext_ram_t_ref=3900000
+ext_ram_t_wr=15000
+ext_ram_t_wtr=7500
+ext_ram_t_rtp=7500
+ext_ram_freq=1066
+ext_ram_rows=16384
+ext_ram_jedec=29
+ext_ram_t_rc=46090
+ext_ram_t_rcd_rd=13090
+ext_ram_t_rcd_wr=13090
+ext_ram_t_rp=13090
+ext_ram_t_rfc=160000
+ext_ram_t_ras=33000
+ext_ram_c_wr_latency=10
+ext_ram_t_faw=35000
+ext_ram_c_cas_latency=14
+ddr3_mem_grade=0x141414
+
+## address or bank address swap example
+#swaps are found in bcm88xxx_board.soc
+#ext_ram_addr_bank_swap_dramX_bitY=M
+
+## dq swap example
+#swaps are found in bcm88xxx_board.soc
+#bit swap example:
+#ext_ram_dq_swap_dramX_byteY_bitZ=M
+#byte swap example:
+#ext_ram_dq_swap_dramX_byteY=M
+
+## Dram Gear down mode. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_gear_down_mode.BCM88675=0
+
+## Alert_n de-assertion period above which error is considered parity error
+#ext_ram_alert_n_period_thrs.BCM88675=20
+
+## Dram Address bus inversion. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_abi.BCM88675=0
+
+## Data bus inversion on write/read direction. Valid values: 0 - Disable, 1 - Enable. Default: 0x0.
+## those socs are configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_write_dbi.BCM88675=0
+#ext_ram_read_dbi.BCM88675=0
+
+## Enable write/read CRC (DDR4 does not support read CRC). Default: 0x0.
+## those socs are configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_write_crc.BCM88675=1
+#ext_ram_read_crc.BCM88675=0
+
+## Command parity latency. Valid values: 0 - Disable, 4,5 or 6 - Valid values. Default: 0x0.
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_cmd_par_latency.BCM88675=6
+
+# DRAM pre-configurations according to config variables which defines
+# Dram Type. BCM88650 supports only DDR3.
+# Dram Type. BCM88675 supports DDR4 and GDDR5.
+ext_ram_type.BCM88650=DDR3
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_type.BCM88675=DDR4
+
+# Total Dram Size (MBytes)
+# For 8 drams interfaces, 2 channel each, Each channel 2Gbit Dram. the total DRAM size is 32GBits=4000MBytes.
+ext_ram_total_size.BCM88650=4000
+## this soc is configured in per board soc file (bcm88x7x_board.soc)
+#ext_ram_total_size.BCM88675=8000
+
+# Total buffer size allocated for User buffer. Units: Mbytes. Default: '0x0'.
+# Supported suffix:
+# dram - the buffer size will be subtracted from the DRAM size available for packet memory.
+#user_buffer_size=0
+#user_buffer_size_dram=50
+
+# DRAM ClamShell (interface swap its HW PIN pairs during init.)
+# Note: Only one of DRAMs can have its PIN swapped
+# Valid values: 0/1
+#dram0_clamshell_enable.BCM88650=1
+#dram1_clamshell_enable.BCM88650=1
+
+# DRAM maximum number of crc error per buffer, buffer deleted by interrupt application.
+#dram_crc_del_buffer_max_reclaims=0
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+## If set, always configures synthesizers, even if the configured rate is equal to
+## their nominal rate. Can be disabled to speedup bringup time (keep in mind that if
+## disabled, changing a synt to a non-nominal freq and than back to nominal will not
+## work
+#synt_over.BCM88650=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88650=100000000
+synt_ddr.BCM88650=125000000
+synt_phy.BCM88650=156250000
+# in Jericho, this freq is used only for the core synth
+synth_dram_freq.BCM88650=25
+
+#Configure the reference clock frequencies for NIF and Fabric SerDes
+# Options: 0 - 125MHz, 1 - 156.25MHz, -1 - Disable
+serdes_nif_clk_freq.BCM88650=1
+serdes_fabric_clk_freq.BCM88650=1
+#serdes_nif_clk_freq.BCM88270=-1
+#serdes_fabric_clk_freq.BCM88270=-1
+serdes_nif_clk_freq.BCM8206=-1
+serdes_fabric_clk_freq.BCM8206=-1
+#serdes_nif_clk_freq_out0.BCM88675=1
+#serdes_nif_clk_freq_out1.BCM88675=1
+#serdes_nif_clk_freq_out2.BCM88675=1
+#serdes_nif_clk_freq_in0.BCM88675=1
+#serdes_nif_clk_freq_in1.BCM88675=1
+#serdes_nif_clk_freq_in2.BCM88675=1
+#serdes_fabric_clk_freq_out0.BCM88675=1
+#serdes_fabric_clk_freq_out1.BCM88675=1
+#serdes_fabric_clk_freq_in0.BCM88675=1
+#serdes_fabric_clk_freq_in1.BCM88675=1
+
+
+# IEEE 1588 / Broadsync -
+# configure clock :
+# DPLL mode/lock: 0 - eci ts pll clk disabled, 1 - configure eci ts pll clk
+# DPLL phase/freq. Default initial: lo = 0x40000000, hi = 0x10000000.
+#phy_1588_dpll_frequency_lock.BCM88650=1
+#phy_1588_dpll_phase_initial_lo.BCM88650=0x40000000
+#phy_1588_dpll_phase_initial_hi.BCM88650=0x10000000
+# IEEE 1588 -
+# port external MAC
+# indication whether external MAC exists or not.
+# 0: 1588 external MAC does not exist
+# 1: 1588 external MAC exists
+# the external MAC substracts the RX time from the correction field
+# and adds the TX time to the correction field.
+#ext_1588_mac_enable_14.BCM88650=1
+# If set, 48 bits stamping is used for 1588 packets. otherwise 32 bit stamping is used
+# 0: 1588 32b stamping (Default)
+# 1: 1588 48b stamping
+#bcm88660_1588_48b_stamping_enable.BCM88660=1
+
+## Trill configurations
+# Trill mode: 0 (disabled) / 1 (coarse-grained) / 2 (fine-grained)
+#trill_mode.BCM88650=1
+
+# Trill multicast prunning mode:
+# 0: no prunning - vsi is not part of the key
+# 1: VSI prunning: Key is dist-tree,esadit-bit,VSI.
+trill_mc_prune_mode.BCM88650=0
+
+# Enable SA authentication
+#sa_auth_enabled=1
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88650=0
+logical_port_drop.BCM88650=1
+
+#logical_port_mim_in.BCM88650=2
+#logical_port_mim_out.BCM88650=4096
+
+# Enable EVB application
+#evb_enable=1
+
+# Enable Flexible QinQ application
+#vlan_translation_match_ipv4=1
+
+# Enable presel mgmt advance mode
+#field_presel_mgmt_advanced_mode=1
+
+# Enable ITMH programmable mode
+# ITMH processing fully programmable (not fixed) by using the FP APIs.
+# In this mode ITMH processing uses the TCAM/direct table for TM programs lookup, in same manner as Ethernet frames.
+itmh_programmable_mode_enable.BCM88675=1
+itmh_programmable_mode_enable.BCM88470=1
+itmh_programmable_mode_enable.BCM88270=1
+itmh_programmable_mode_enable.BCM88680=1
+
+
+
+# Prepend tag to be 4 bytes or 8 bytes. Default: 4B.
+# Applicable only from ARAD+
+#prepend_tag_bytes=4B
+
+# The Prepend Tag is located at (12 + 2*offset) bytes from the start of the packet.
+# Range: 0-7. Default: 0
+#prepend_tag_offset=0
+
+# Enable ARP (next hop mac extension) feature
+bcm886xx_next_hop_mac_extension_enable.BCM88650=1
+
+# Set VLAN translate mode.
+# 0: normal
+# 1: advanced mode. Enable vlan edit settings with enhanced user control
+#bcm886xx_vlan_translate_mode=0
+
+# Set MPLS termination database mode
+# Set MPLS databases location for each MPLS namespace (L1,L2,L3)
+#bcm886xx_mpls_termination_database_mode=0
+
+# Enable , Disable MPLS indexed.
+# MPLS termination with known label stack location.
+# Must be enabled in case device supports more than 2 MPLS label terminations (L1,L2,L3)
+#mpls_termination_label_index_enable=1
+
+# Enable FastReRoute labels in device.
+#fast_reroute_labels_enable=0
+
+# Enable MPLS Context specific. Upstream label assignment in device.
+#mpls_context_specific_label_enable=0
+
+# MPLS context.
+# Can be global, per port , per interface or per port,interface.
+#mpls_context=global
+
+# MPLS TP MC reserved mac address (01-00-5E-90-00-00).
+# If set device will support My-MAC termination of reserved MC Ethernet
+#mpls_tp_mymac_reserved_address=0
+
+# MPLS ELI enable disable
+mpls_entropy_label_indicator_enable=0
+
+#########################################
+##cfg for BCM88202 - Ardon
+#########################################
+
+#Core clock and system reference clock (KHz)
+core_clock_speed_khz.BCM88202=450000
+system_ref_core_clock_khz.BCM88202=1200000
+
+## Set TM as device mode
+fap_device_mode.BCM88202=TM
+
+## Set CPU ports header type
+tm_port_header_type_in_0.BCM88202=TM
+tm_port_header_type_out_0.BCM88202=TM
+tm_port_header_type_in_200.BCM88202=TM
+tm_port_header_type_out_200.BCM88202=TM
+tm_port_header_type_in_201.BCM88202=TM
+tm_port_header_type_out_201.BCM88202=TM
+tm_port_header_type_in_202.BCM88202=TM
+tm_port_header_type_out_202.BCM88202=TM
+tm_port_header_type_in_203.BCM88202=TM
+tm_port_header_type_out_203.BCM88202=TM
+
+##### Application configuration
+### Default SDK Application
+ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+ucode_port_13.BCM88202=TM_INTERNAL_PKT.1
+ucode_port_14.BCM88202=TM_INTERNAL_PKT.2
+ucode_port_15.BCM88202=TM_INTERNAL_PKT.3
+ucode_port_16.BCM88202=TM_INTERNAL_PKT.4
+ucode_port_17.BCM88202=TM_INTERNAL_PKT.5
+
+### PortOpriority (additonal ports can be added)
+#diag_cosq_disable.BCM88202=1
+#ucode_port_1.BCM88202=IGNORE
+#ucode_port_13.BCM88202=IGNORE
+#ucode_port_14.BCM88202=IGNORE
+#ucode_port_15.BCM88202=IGNORE
+#ucode_port_16.BCM88202=IGNORE
+#ucode_port_17.BCM88202=IGNORE
+#ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+#ucode_port_2.BCM88202=TM_INTERNAL_PKT.1
+#ucode_port_3.BCM88202=TM_INTERNAL_PKT.2
+#ucode_port_4.BCM88202=TM_INTERNAL_PKT.3
+#ucode_port_5.BCM88202=TM_INTERNAL_PKT.4
+#ucode_port_6.BCM88202=TM_INTERNAL_PKT.5
+#ucode_port_7.BCM88202=TM_INTERNAL_PKT.6
+#ucode_port_8.BCM88202=TM_INTERNAL_PKT.7
+#ucode_port_9.BCM88202=TM_INTERNAL_PKT.8
+#ucode_port_10.BCM88202=TM_INTERNAL_PKT.9
+#ucode_port_11.BCM88202=TM_INTERNAL_PKT.10
+#ucode_port_12.BCM88202=TM_INTERNAL_PKT.11
+#ucode_port_13.BCM88202=TM_INTERNAL_PKT.12
+#ucode_port_14.BCM88202=TM_INTERNAL_PKT.13
+#ucode_port_15.BCM88202=TM_INTERNAL_PKT.14
+#ucode_port_16.BCM88202=TM_INTERNAL_PKT.15
+#ucode_port_17.BCM88202=TM_INTERNAL_PKT.16
+#ucode_port_18.BCM88202=TM_INTERNAL_PKT.17
+#ucode_port_19.BCM88202=TM_INTERNAL_PKT.18
+#ucode_port_20.BCM88202=TM_INTERNAL_PKT.19
+#ucode_port_21.BCM88202=TM_INTERNAL_PKT.20
+#ucode_port_22.BCM88202=TM_INTERNAL_PKT.21
+#ucode_port_23.BCM88202=TM_INTERNAL_PKT.22
+#ucode_port_24.BCM88202=TM_INTERNAL_PKT.23
+#ucode_port_25.BCM88202=TM_INTERNAL_PKT.24
+
+#dtm_flow_nof_remote_cores_region_1.BCM88202=1
+#dtm_flow_nof_remote_cores_region_2.BCM88202=1
+#dtm_flow_nof_remote_cores_region_3.BCM88202=1
+#dtm_flow_nof_remote_cores_region_4.BCM88202=1
+#dtm_flow_nof_remote_cores_region_5.BCM88202=1
+#dtm_flow_nof_remote_cores_region_6.BCM88202=1
+#dtm_flow_nof_remote_cores_region_7.BCM88202=1
+#dtm_flow_nof_remote_cores_region_8.BCM88202=1
+#dtm_flow_nof_remote_cores_region_9.BCM88202=1
+#dtm_flow_nof_remote_cores_region_10.BCM88202=1
+
+### PriorityOPort
+#diag_cosq_disable.BCM88202=1
+#stack_enable.BCM88202=0
+#ucode_port_17.BCM88202=IGNORE
+#ucode_port_16.BCM88202=IGNORE
+#ucode_port_15.BCM88202=IGNORE
+#ucode_port_14.BCM88202=IGNORE
+#ucode_port_13.BCM88202=IGNORE
+#ucode_port_1.BCM88202=TM_INTERNAL_PKT.0
+
+## Credit worth resolution (Fix the Interface rate)
+credit_worth_resolution.BCM88202=medium
+
+### Interrupts
+polled_irq_mode.BCM88202=1
+
+## To use MC-ID in the range of < 255
+egress_multicast_direct_bitmap_max.BCM88202=255
+
+### Flow Control
+## Enable Flow Control to CL SCH. Relevant only to Priority Over Port application
+## Valid values: 1 - Enable, 0 - Disable. Default: 0x0.
+custom_feature_cl_scheduler_fc.BCM88202=1
+
+## Valid values: 1 - Enable, 0 - Disable. Default: 0x0.
+#custom_feature_high_vsi_fp.BCM88660=0
+
+## Use lower CL. Ardon FC is mapped to CL 0-255.
+dtm_flow_mapping_mode_region_65.BCM88202=1
+dtm_flow_mapping_mode_region_66.BCM88202=1
+
+### Statistic-Report Properties
+stat_if_enable.BCM88202=1
+stat_if_rate.BCM88202=10000
+stat_if_pkt_size.BCM88202=126B
+## Set the Statistic-Report mode
+stat_if_report_mode.BCM88202=QSIZE
+## Enable statistics reports on EnQueue. Valid valued: 0/1. Default: '1'.
+stat_if_report_enqueue_enable.BCM88202=1
+## Enable statistics reports on DeQueue. Valid valued: 0/1. Default: '1'.
+stat_if_report_dequeue_enable.BCM88202=1
+
+## Disable removed features
+phy_1588_dpll_frequency_lock.BCM88202=0
+low_power_nif_mac.BCM88202=0
+low_power_fabric_mac.BCM88202=0
+custom_feature_nif_recovery_enable.BCM88202=0
+phy_null.BCM88202=0
+
+## Disable counter thread
+bcm_stat_interval.BCM88202=0
+#bcm_stat_sync_timeout.BCM88202=0xfffffff
+
+### EMUL changes
+#diag_emulator_partial_init.BCM88202=1
+#schan_timeout_usec.BCM88202=0x7fffffff
+#tdma_timeout_usec.BCM88202=0x7fffffff
+#tslam_timeout_usec.BCM88202=0x7fffffff
+#phy_null.BCM88202=0
+
+### Disable DMA
+#tdma_timeout_usec.BCM88202=0
+#tslam_timeout_usec.BCM88202=0
+#table_dma_enable.BCM88202=0
+#tslam_dma_enable.BCM88202=0
+
+### Dram setup
+# Number of external DRAMs.
+# Allowed values for 88202: 0 / 1 (Dram D) / 2 (Dram's C, D) / 3 (Dram's B, C, D) / 4 (Dram's A, B, C, D) /
+ext_ram_present.BCM88202=0
+
+### Total size of ram
+ext_ram_total_size.BCM88202=2000
+
+### OCB
+bcm886xx_ocb_databuffer_size.BCM88202=1024
+
+# DRAM frequency (DQ/2)
+ext_ram_freq.BCM88202=1200
+
+# Dram Type. Ardon supports only DDR4.
+ext_ram_type.BCM88202=DDR4
+
+### Dram Features
+
+## Dram Gear down mode. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+#ext_ram_gear_down_mode.BCM88202=1
+
+## Alert_n de-assertion period above which error is considered parity error
+#ext_ram_alert_n_period_thrs.BCM88202=0
+
+## Dram Address bus inversion. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_abi.BCM88202=0
+
+## Data bus inversion on write/read direction. Valid values: 0 - Disable, 1 - Enable. Default: 0x0.
+ext_ram_write_dbi.BCM88202=0
+ext_ram_read_dbi.BCM88202=0
+
+## Enable write/read CRC (DDR4 does not support read CRC). Default: 0x0.
+#ext_ram_write_crc=.BCM882021
+#ext_ram_read_crc=.BCM882021
+
+## Command parity latency. Valid values: 0 - Enable, 1 - Disable. Default: 0x0.
+ext_ram_cmd_par_latency.BCM88202=6
+
+## DRAM ClamShell (interface swap its HW PIN pairs during init.)
+# Note: Only one of DRAMs can have its PIN swapped). Valid values: 0/1.
+dram1_clamshell_enable_0.BCM88202=1
+dram1_clamshell_enable_1.BCM88202=1
+dram1_clamshell_enable_2.BCM88202=1
+dram1_clamshell_enable_3.BCM88202=1
+
+## Dram DQ Swap.
+## Format: ext_ram_dq_swap_dramX_byteY_bitZ=M. Means, In dram X, Byte Y swap DQ Z and M. Default: No swapping.
+#ext_ram_dq_swap_dram1_byte2_bit3.BCM88202=4
+#ext_ram_dq_swap_dram4_byte3_bit2.BCM88202=1
+
+### Dram Tuning (Shmoo)
+ddr3_auto_tune.BCM88202=2
+
+### Enable BIST
+# Run Dram BIST on initialization, if BIST fail the initialization will fail. Default: 1.
+bist_enable_dram.BCM88202=1
+
+### Fabric
+## Enable fabric links
+serdes_qrtt_active_0.BCM88202=1
+serdes_qrtt_active_1.BCM88202=1
+serdes_qrtt_active_2.BCM88202=1
+serdes_qrtt_active_3.BCM88202=1
+
+## Firmware Load Method
+load_firmware.BCM88202=2
+
+#SFI speed rate
+port_init_speed_sfi.BCM88202=11500
+
+#LC PLL in. Default: 156.25MHz.
+#xgxs_lcpll_xtal_refclk=125
+
+#########################################
+##cfg for BCM88640_A0 - Petra
+#########################################
+
+force_clk_m_n_divisors_zero_nif0.BCM88640_A0=0
+force_clk_m_n_divisors_zero_fabric0.BCM88640_A0=1
+force_clk_m_n_divisors_zero_comb0.BCM88640_A0=0
+
+combo_ref_clock.BCM88640=312500
+
+nif_ref_clock.BCM88640_A0=312500
+
+# Use variable cell size
+system_cell_format.BCM88640_A0=VCS128
+
+# Core clock speed (MHz)
+core_clock_speed.BCM88640_A0=300
+
+# Map bcm local port to CPU/NIF interfaces
+ucode_port_0.BCM88640_A0=CPU.0
+ucode_port_73.BCM88640_A0=CPU.1
+ucode_port_74.BCM88640_A0=CPU.2
+ucode_port_75.BCM88640_A0=CPU.3
+ucode_port_76.BCM88640_A0=CPU.4
+ucode_port_77.BCM88640_A0=CPU.5
+ucode_port_78.BCM88640_A0=CPU.6
+
+# Interlaken ports basic configuration (temporary).
+# This configuration replaces the above XAUI/RXAUI ports config
+# The following PB design constraint is not enforced in SW, so must be taken
+# care of here, when mapping ports to interfaces:
+# If using ilkn0, port 1 (if used) must be mapped to ilkn0
+# If using ilkn1, port 2 (if used) must be mapped to ilkn1
+# Note that in our default mapping, port 2 is mapped to RXAUI 6, thus won't
+# work. If one wants to use front panel port 2 with ilkn1, he should be map
+# RAXUI6 to a port != 2.
+#ilkn_num_lanes_0.BCM88640_A0=12
+#ucode_port_1.BCM88640_A0=ILKN0.0
+#ucode_port_2.BCM88640_A0=ILKN0.1
+#ucode_port_3.BCM88640_A0=ILKN0.2
+#ilkn_num_lanes_1.BCM88640_A0=12
+#ucode_port_4.BCM88640_A0=RXAUI6
+#ucode_port_5.BCM88640_A0=ILKN1.0
+#ucode_port_6.BCM88640_A0=ILKN1.1
+#ucode_port_7.BCM88640_A0=ILKN1.2
+
+# Default header type is derived from fap_device_mode: If fap_device_mode is
+# PP, default header type is ETH. Otherwise, defualt header type is TM.
+# Header type per port can be overriden.
+# All options: ETH/RAW/TM/PROG/CPU/STACKING/TDM/TDM_RAW/INJECTED
+
+# Set CPU to work with TM header (ITMH)
+#tm_port_header_type_0.BCM88640_A0=TM
+tm_port_header_type_in_0.BCM88640_A0=TM
+tm_port_header_type_out_0.BCM88640_A0=CPU
+tm_port_header_type_73.BCM88640_A0=TM
+tm_port_header_type_74.BCM88640_A0=TM
+tm_port_header_type_75.BCM88640_A0=TM
+tm_port_header_type_76.BCM88640_A0=TM
+tm_port_header_type_77.BCM88640_A0=TM
+tm_port_header_type_78.BCM88640_A0=TM
+# recycling port
+tm_port_header_type_40.BCM88640_A0=RAW
+ucode_port_40.BCM88640_A0=RCY.0
+
+# Enable ERP and OLP ports
+num_erp_tm_ports.BCM88640_A0=1
+num_olp_tm_ports.BCM88640_A0=1
+num_recycle_tm_ports.BCM88640_A0=1
+
+# Dram configuration
+# 600 Mhz
+ext_ram_pll_r.BCM88640_A0=4
+ext_ram_pll_f.BCM88640_A0=47
+ext_ram_pll_q.BCM88640_A0=1
+ext_ram_freq.BCM88640_A0=600
+
+# Dbuff size
+# Allowed values: 256/512/1024/2048.
+ext_ram_dbuff_size.BCM88640_A0=1024
+
+# Number of external DRAMs.
+# Allowed values for 88x4x: 0/2/3/4/6.
+# Allowed values for 88650: 0/2/3/4/6/8.
+# ext_ram_total_size below assumed this value is 6 for 88x4x and 8 for
+ext_ram_present.BCM88640_A0=6
+
+# Dram type: Select ONLY ONE of the following DRAM types, to configure all dram
+# related parameteres per type.
+# Dram Type for Pb:
+#dram_type_DDR3_MICRON_MT41J64M16_15E.BCM88640_A0=1
+#dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333.BCM88640_A0=1
+#dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600.BCM88640_A0=1
+#dram_type_GDDR3_SAMSUNG_K4J52324QE.BCM88640_A0=1
+dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G.BCM88640_A0=1
+
+# QDR configuration
+# Parity. Allowed values: PARITY/ECC.
+ext_qdr_protection_type.BCM88640_A0=PARITY
+ext_qdr_size_mbit.BCM88640_A0=72
+#QDR type: QDR/QDR2P/QDR3/NONE.
+ext_qdr_type.BCM88640_A0=QDR
+
+# QDR can use the core clock, or using it's own pll. Current example is for 250MHz pll (if used).
+# QDR using own pll configuration
+#ext_qdr_use_core_clock_freq.BCM88640_A0=0
+#ext_qdr_pll_m.BCM88640_A0=4
+#ext_qdr_pll_n.BCM88640_A0=4
+#ext_qdr_pll_p.BCM88640_A0=0
+
+# QDR using core clock
+ext_qdr_use_core_clock_freq.BCM88640_A0=1
+
+#Configure MDIO. If parameter is not defined, MDIO is disabled.
+mdio_clock_freq_khz.BCM88640_A0=1000
+
+# Streaming interface configuration
+streaming_if_enable_timeoutcnt.BCM88640_A0=1
+streaming_if_timeout_prd.BCM88640_A0=70
+streaming_if_quiet_mode.BCM88640_A0=0
+streaming_if_discard_bad_parity.BCM88640_A0=0
+
+# maximum packet size for WRED tests. 0 - means ignore max packet size.
+discard_mtu_size.BCM88640_A0=0
+
+# multicast egress vlan membership range. By default: 0-4095.
+egress_multicast_direct_bitmap_max.BCM88640_A0=4095
+
+# configure flow mapping base to 0
+flow_mapping_queue_base.BCM88640_A0=0
+
+dtm_flow_mapping_mode_region_25.BCM88640_A0=0
+dtm_flow_mapping_mode_region_26.BCM88640_A0=0
+dtm_flow_mapping_mode_region_27.BCM88640_A0=0
+dtm_flow_mapping_mode_region_28.BCM88640_A0=0
+dtm_flow_mapping_mode_region_29.BCM88640_A0=0
+dtm_flow_mapping_mode_region_30.BCM88640_A0=0
+dtm_flow_mapping_mode_region_31.BCM88640_A0=0
+dtm_flow_mapping_mode_region_32.BCM88640_A0=0
+dtm_flow_mapping_mode_region_33.BCM88640_A0=1
+dtm_flow_mapping_mode_region_34.BCM88640_A0=1
+dtm_flow_mapping_mode_region_35.BCM88640_A0=1
+dtm_flow_mapping_mode_region_36.BCM88640_A0=1
+dtm_flow_mapping_mode_region_37.BCM88640_A0=1
+dtm_flow_mapping_mode_region_38.BCM88640_A0=1
+dtm_flow_mapping_mode_region_39.BCM88640_A0=1
+dtm_flow_mapping_mode_region_40.BCM88640_A0=1
+dtm_flow_mapping_mode_region_41.BCM88640_A0=1
+dtm_flow_mapping_mode_region_42.BCM88640_A0=2
+dtm_flow_mapping_mode_region_43.BCM88640_A0=2
+dtm_flow_mapping_mode_region_44.BCM88640_A0=2
+dtm_flow_mapping_mode_region_45.BCM88640_A0=2
+dtm_flow_mapping_mode_region_46.BCM88640_A0=2
+dtm_flow_mapping_mode_region_47.BCM88640_A0=2
+dtm_flow_mapping_mode_region_48.BCM88640_A0=2
+dtm_flow_mapping_mode_region_49.BCM88640_A0=2
+dtm_flow_mapping_mode_region_50.BCM88640_A0=2
+dtm_flow_mapping_mode_region_51.BCM88640_A0=2
+dtm_flow_mapping_mode_region_52.BCM88640_A0=2
+dtm_flow_mapping_mode_region_53.BCM88640_A0=2
+dtm_flow_mapping_mode_region_54.BCM88640_A0=2
+dtm_flow_mapping_mode_region_55.BCM88640_A0=2
+
+# Power up state (DOWN/UP/UP_AND_RELOCK). Can be configured per lane.
+pb_serdes_lane_power_state.BCM88640_A0=UP_AND_RELOCK
+
+# SeDes media type: Pre-configuration for tx params, according to
+# media type.
+# Allowed values: SHORT_BACKPLANE/LONG_BACKPLANE/CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type.BCM88640_A0=SHORT_BACKPLANE
+pb_serdes_lane_tx_phys_media_type_28.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_29.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_30.BCM88640_A0=CHIP2CHIP
+pb_serdes_lane_tx_phys_media_type_31.BCM88640_A0=CHIP2CHIP
+
+system_is_fe1600_in_system.BCM88640_A0=0
+
+# Counter engine configuration
+counter_engine_source_1.BCM88640_A0=0
+counter_engine_statistics_1.BCM88640_A0=4
+counter_engine_source_2.BCM88640_A0=1
+counter_engine_statistics_2.BCM88640_A0=4
+
+# Statistic Reporting
+stat_if_enable=0
+
+# Clock Phases: 0/90/180/270
+stat_if_phase=0
+
+# Rate in nm
+stat_if_sync_rate=0
+
+# TRUE/FALSE
+stat_if_parity_enable=FALSE
+
+# BILLING/FAP20V
+stat_if_report_mode=BILLING
+
+# Billing Mode
+# EGR_Q_NB/CUD/VSI_VLAN/BOTH_LIFS
+stat_if_report_billing_mode=VSI_VLAN
+
+# Fap20V Mode
+# QUEUE/PACKET
+stat_if_report_fap20v_mode=QUEUE
+
+# QUEUE_NUM/MC_ID (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_fabric_mc=QUEUE_NUM
+stat_if_report_fap20v_ing_mc=QUEUE_NUM
+
+# TRUE/FALSE (only valid in Fap20V PACKET mode)
+stat_if_report_fap20v_cnm_report=FALSE
+
+# TRUE/FALSE
+stat_if_report_fap20v_count_snoop=FALSE
+stat_if_report_original_pkt_size=FALSE
+stat_if_report_fap20v_single_copy_reported=FALSE
+
+schan_timeout_usec.BCM88640_A0=300000
+
+
+polled_irq_mode.BCM88640_A0=0
+polled_irq_delay.BCM88640_A0=1000
+
+# Set the FTMH Load-Balancing Key extension mode
+# Options for 88650: ENABLED
+# Options for 88640 compatible:
+# DISABLED / 8B_LB_KEY_8B_STACKING_ROUTE_HISTORY / 16B_STACKING_ROUTE_HISTORY
+# Default: DISABLED
+system_ftmh_load_balancing_ext_mode.BCM88640=DISABLED
+
+#########################################
+##cfg for BCM88750 (FE1600)
+#########################################
+
+fabric_device_mode.BCM88750=SINGLE_STAGE_FE2
+
+is_dual_mode.BCM88750=0
+system_is_vcs_128_in_system.BCM88750=0
+
+system_is_dual_mode_in_system.BCM88750=0
+system_is_single_mode_in_system.BCM88750=1
+
+system_is_fe600_in_system.BCM88750=0
+
+system_ref_core_clock_khz.BCM88750=1200000
+
+fabric_merge_cells.BCM88750=0
+fabric_multicast_mode.BCM88750=DIRECT
+fabric_load_balancing_mode.BCM88750=NORMAL_LOAD_BALANCE
+fabric_tdm_fragment.BCM88750=0x180
+##Allows single pipe device to send TDM traffic over the fabric primary pipe - available for Fe1600_B0 only
+#change vcs128_unicast_priority to be lower than 2 - when enabling
+fabric_tdm_over_primary_pipe.BCM88750=0
+fabric_optimize_partial_links.BCM88750=0
+vcs128_unicast_priority.BCM88750=2
+
+polled_irq_mode.BCM88750=0
+polled_irq_delay.BCM88750=1000
+
+#Selects if to run MBIST (Memory Built In Self Test) of internal memory (tables) during startup.
+#Supported values: 0=don't run, 1=run, 2=run with extra logs
+#bist_enable.BCM88650=1
+bist_enable.BCM88750=1
+bist_enable.BCM88470=0
+#High voltage driver strap. If 0, connected to 1.4V supply; if 1, connected to 1V mode.
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88750=0
+load_firmware.BCM88750=2
+
+#0-LFEC 1-8b\10b 2-FEC 3-BEC
+backplane_serdes_encoding.BCM88750=2
+
+#enable\disable CL72
+port_init_cl72.BCM88750=1
+#Avaliable speeds for BCM88750: 5750, 6250, 10312, 11500, 12500
+port_init_speed.BCM88750=10312
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88750=1
+serdes_fabric_clk_freq_out.BCM88750=1
+serdes_mixed_rate_enable.BCM88750_B0=0
+
+# VSC128 or VSC256
+fabric_cell_format.BCM88750=VSC256
+
+# Core clock speed (MHz)
+core_clock_speed_khz.BCM88750=533333
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88750=0
+schan_timeout_usec.BCM88750=300000
+# TDMA
+tdma_intr_enable.BCM88750=0
+tdma_timeout_usec.BCM88750=5000000
+# TSLAM
+tslam_intr_enable.BCM88750=0
+tslam_timeout_usec.BCM88750=5000000
+# MIIM
+miim_intr_enable.BCM88750=0
+miim_timeout_usec.BCM88750=300000
+
+#########################################
+##cfg for BCM88950 (FE3200)
+#########################################
+#Device operation
+fabric_device_mode.BCM88950=SINGLE_STAGE_FE2
+fabric_load_balancing_mode.BCM88950=NORMAL_LOAD_BALANCE
+
+#Cell format
+system_is_vcs_128_in_system.BCM88950=0
+
+#Fabric pipe configuration
+
+fabric_num_pipes.BCM88950=1
+fabric_pipe_map.BCM88950=0
+system_contains_multiple_pipe_device.BCM88950=0
+
+#multicast table mode
+fabric_multicast_mode.BCM88950=DIRECT
+fe_mc_id_range.BCM88950=128K_HALF
+
+#Core clock and system reference clock (KHz)
+system_ref_core_clock_khz.BCM88950=1200000
+core_clock_speed_khz.BCM88950=720000
+
+#LC PLL in\out 0=125MHz 1=156.25MHz
+serdes_fabric_clk_freq_in.BCM88950=0
+serdes_fabric_clk_freq_out.BCM88950=1
+
+#TODO
+polled_irq_mode.BCM88950=1
+polled_irq_delay.BCM88950=1000
+
+#Memory Bist
+bist_enable.BCM88950=0
+
+#High voltage driver strap. If 0, connected to 1.25V supply;
+#if 1, connected to 1V mode (For unused Falcon Quads that are connected to 1.0V).
+#for specific quad use srd_tx_drv_hv_disable_quad_X where X is (FSRD num * 4 + internal quad)
+srd_tx_drv_hv_disable.BCM88950=0
+load_firmware.BCM88950=0x102
+
+
+##Per port properties
+#Possible values - KR_FEC, 64_66, RS_FEC, LL_RS_FEC
+backplane_serdes_encoding.BCM88950=RS_FEC
+
+#enable\disable CL72
+port_init_cl72.BCM88950=1
+
+#link speed
+port_init_speed.BCM88950=25000
+
+#Link connected to a reapter
+#Values: 0/1. Default: 0
+#repeater_link_enable_<port>.BCM88950=0
+
+##Fabric cell FIFO DMA
+fabric_cell_fifo_dma_enable.BCM88950=1
+
+## CMIC interrupts:
+# Enable: Use interrupts completion instead of polling completion for the following operations.
+# Options: 1 - Enable, 0 - Disable. Default: 0.
+# Timeout: delay in Microsecond between the polling,
+# SCHAN:
+schan_intr_enable.BCM88950=0
+schan_timeout_usec.BCM88950=300000
+# TDMA
+tdma_intr_enable.BCM88950=0
+tdma_timeout_usec.BCM88950=5000000
+# TSLAM
+tslam_intr_enable.BCM88950=0
+tslam_timeout_usec.BCM88950=5000000
+# MIIM
+miim_intr_enable.BCM88950=0
+miim_timeout_usec.BCM88950=300000
+
+##############################
+# Configuration for devices run in emulation
+##############################
+#diag_emulator_partial_init.BCM88470=2
+#phy_simul.BCM88470=1
+#system_ref_core_clock_khz.BCM88470=250000
+#system_ref_core_clock_khz.BCM88470=600000
+#phy_simul.BCM88270=1
+
+polled_irq_mode.BCM88470=1
+polled_irq_mode.BCM88270=1
+
+schan_intr_enable.BCM88470=0
+schan_intr_enable.BCM88270=0
+
+# For emulation use:
+#schan_timeout_usec.BCM88470=600000000
+schan_timeout_usec.BCM88470=300000
+schan_timeout_usec.BCM88270=200000
+
+# TDMA
+tdma_intr_enable.BCM88470=0
+#tdma_intr_enable.BCM88270=0
+
+# For emulation use:
+#tdma_timeout_usec.BCM88470=600000000
+tdma_timeout_usec.BCM88470=60000000
+tdma_timeout_usec.BCM88270=500000
+
+# TSLAM
+tslam_intr_enable.BCM88470=0
+tslam_intr_enable.BCM88270=0
+
+# For emulation use:
+#tslam_timeout_usec.BCM88470=600000000
+tslam_timeout_usec.BCM88470=60000000
+tslam_timeout_usec.BCM88270=500000
+
+#otm_base_q_pair.BCM88470=2
+
+##############################
+# Config variable below are only accessed from dune.soc, and are used to
+# configure BSP / example application / group of formal config variables.
+##############################
+
+# Support (and configure on init) packet processing features.
+# If not defined - only traffic management capabilities are enabled.
+packet_processing=1
+
+## PCP (Petra Co-Processor) features
+#pcp_elk.BCM88640_A0=1
+#pcp_oam.BCM88640_A0=1
+#pcp_dma.BCM88640_A0=1
+
+## Set/Override TDM related config variables
+#tdm.BCM88640_A0=1
+
+# If set, always configures synthesizers, even if the configured rate is
+# equal to
+# their nominal rate. Can be disabled to speedup bringup time
+# (keep in mind that if disabled, changing a synt to a non-nominal freq and
+# than back to nominal will not work
+#synt_over.BCM88640_A0=1
+
+# Local variables for board synthesizers freq. Fabric, combo and nif also configure
+# the *_ref_clock soc properties for these frequencies. core, ddr and phy only
+# configures the synthesizer
+synt_core.BCM88640_A0=100000000
+synt_ddr.BCM88640_A0=125000000
+synt_phy.BCM88640_A0=156250000
+
+
+############################
+### Warmboot & SW State ####
+############################
+#
+#HW journal working mode. Allowed values: 0-2.
+# 0 : Disabled
+# 1 : Commit After Each Api
+# 2 : Commit Upon User Request
+ha_hw_journal_mode=0
+
+ha_hw_journal_size=15728640
+ha_sw_journal_size=15728640
+ha_crash_recovery=1
+
+
+# stable_size - a strict bound on the application's external storage size
+stable_size.BCM88950=200000
+stable_size.BCM88750=200000
+stable_size.BCM88650=281000000
+stable_size.BCM88675=500000000
+stable_size.BCM88680=500000000
+stable_size.BCM88690=500000000
+stable_size.BCM88470=350000000
+stable_size.BCM88270=650000000
+stable_size=420000000
+
+# determine the memory size pre-allocated for the SDK's SW State
+sw_state_max_size.BCM88650=210000000
+sw_state_max_size.BCM88675=350000000
+sw_state_max_size.BCM88680=350000000
+sw_state_max_size.BCM88470=300000000
+sw_state_max_size.BCM88270=210000000
+sw_state_max_size=350000000
+
+# stable location
+## part of scache initialization for warmboot persistent storage.
+## values: 1-2:Not Valid for dnx 3: Store in a file 4: Use Shared Mem.
+# 4 is the preffered option, using 3 for Arad and FE in order to regress both modes.
+stable_location.BCM88950=3
+stable_location.BCM88750=3
+stable_location.BCM88650=3
+stable_location.BCM88660=3
+stable_location.BCM88675=3
+stable_location=3
+
+# stable_filename - the warmboot file name (if stored on a file)
+stable_filename=/tmp/warmboot_data
+
+# emulation file name
+stable_filename.BCM88470=/tmp/warmboot_data
+
+
+# create the file in memory for a faster warmboot debug
+#stable_filename=/dev/shm/warmboot_data
+
+# stable_flags - not in use
+stable_flags=0
+
+############################
+############################
+
+
+# Bridge default logical interfaces allocation IDS
+logical_port_l2_bridge.BCM88640=1
+logical_port_drop.BCM88640=-1
+
+#logical_port_mim_in.BCM88640=2
+#logical_port_mim_out.BCM88640=3
+
+## IPV6 tunnel
+bcm886xx_ipv6_tunnel_enable=1
+
+## Inlif Profile Management Mode - QoS L3 L2 marking mode
+#
+# BCM88660 ONLY
+#
+# QoS L3 L2 marking allows changing the DSCP and/or EXP values
+# of IP and/or MPLS packets according to the incoming port
+# (or inlif), and the Traffic Class/Drop Precedence.
+#
+# The inlif profile is used to control the DSCP/EXP marking.
+# This SOC property controls which mode is used for the inlif profile:
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the DSCP/EXP marking).
+# 0: Advanced mode (the user controls which inlif profile values perform DSCP/EXP marking directly).
+#bcm886xx_qos_l3_l2_marking=1
+
+## Unicast RPF mode per RIF
+#
+# This SOC property allows the user to set the unicast RPF mode - loose, strict or disabled - per RIF.
+# If disabled, the unicast RPF mode of a RIF is set globally.
+# Options: 0 / 1
+
+##Jericho only, number of inrif mac termination combinations. Legal values 0 - 16, default value 16 */
+#Note: Two sets of identical mac termination combinations with different RPF modes (loose and strict)
+#will consume two termination combinations resources.
+#Two sets of identical mac termination combinations with and without loose RPF will consume only one resource.
+number_of_inrif_mac_termination_combinations=8
+
+##Jericho only, ipmc_l3mcastl2_mode SOC allows a per RIF program selection in the case of ipv4 MC with IPMC disable
+#instead of the global bcmSwitchL3McastL2 switch control selection.
+#Legal values:
+#0: bcmSwitchL3McastL2 switch control.
+#1: PER In-RIF selection.
+#Note that enabling this SOC will reduce the number of In-RIF mac termination combinations bits by one to a maximum of 3 bits
+#so it can't be enabled with number_of_inrif_mac_termination_combinations larger than 8.
+ipmc_l3mcastl2_mode = 1
+
+# The bcm_ipmc_add adds bridge or route entries according to the BCM_IPMC_L2 flag.
+# Setting custom_feature_ipmc_set_entry_type_by_rif=1 will use the related IN-RIF IPMC state (enable/disable)
+# to select the bcm_ipmc_add entry type (bridge/route).
+#custom_feature_ipmc_set_entry_type_by_rif=0
+
+# bcm886xx_l3_ingress_urpf_enable=1
+
+## BOS handling mode
+# BCM8866X ONLY
+#
+# There are two ways to handle BOS, controlled by bcm886xx_mpls_termination_mode:
+# 0 - Use BOS as key in lookup.
+# 1 - Don't use it (except for reserved labels).
+#
+#bcm886xx_mpls_termination_key_mode=0
+
+# Color resolution mode allows the user to have more detailed metering color information.
+# BCM88660 ONLY
+#
+# Options: 0-2
+# 0: A red result from both Ethernet policer and meter implies DP=3.
+# 1: A red result from meter implies that DP=2, while a red result from rate (Ethernet policer) implies DP=3.
+#policer_color_resolution_mode=1
+
+## Inlif Profile Management Mode - Disable Same Interface Filter
+# BCM8866X ONLY
+#
+# Controls which mode is used for the inlif profile management.
+# 1: Basic mode (1 bit of the inlif profile is reserved and is used for the same-interface filter).
+# 0: Advanced mode (the user controls which inlif profile values have the same-interface filter disabled for them).
+#bcm886xx_logical_interface_bridge_filter_enable=1
+
+## Default Block Forwarding Strength
+#
+# Configure the default forwarding strength of blocks.
+#
+# SOC Properties:
+#block_trap_strength_vtt - VTT block forwarding strength
+#block_trap_strength_flp - FLP block forwarding strength
+#block_trap_strength_hash - SLB block forwarding strength (BCM8866X ONLY)
+#block_trap_strength_pmf_0 - PMF 1st lookup forwarding strength
+#block_trap_strength_pmf_1 - PMF 2nd lookup forwarding strength
+#
+# Options: 0-7
+
+## Stateful Load Balancing
+# BCM8866X ONLY
+#
+# Stateful Load Balancing (SLB) allows the load balancing of ECMP and LAG
+# groups to become stateful.
+# In standard load balancing, removing a member from the ECMP/LAG
+# group may affect the selected member, since the formula
+# depends on group size.
+# In stateful load balancing the member is selected once and saved.
+# Later, the member is always retrieved, and does not depend on
+# the size of the LAG/ECMP group.
+#
+# resilient_hash_enable - Enable/disable SLB. Values:
+# 1 - Enable SLB.
+# 0 - Disable SLB.
+#resilient_hash_enable=1
+
+# When this flag is set (and speculative parsing is used) it is possible for a packet of L4oIPv4/6oMPLS(1-3 labels)oETH
+# with MPLS forwarding to use the L4 header, otherwise the IPv4/6 is the last known header.
+#Note: setting this flag can cause unexpected behavior when BOS is used in the scenario above.
+#custom_feature_speculative_L4_support=0
+
+#Make Arad SOC properties work for Arad+, by mapping the BCM88660 suffix to BCM88650
+soc_family.BCM88660=BCM88650
+#Make Arad SOC properties work for Jericho, by mapping the BCM88675 suffix to BCM88650
+soc_family.BCM88675=BCM88650
+#Make Arad SOC properties work for QMX, by mapping the BCM88375 suffix to BCM88650
+soc_family.BCM88375=BCM88650
+#Make Arad SOC properties work for Ardon, by mapping the BCM88202 suffix to BCM88650
+soc_family.BCM88202=BCM88650
+#Make FE3200 SOC properties work for FE3200 SKU 8952, by mapping the BCM88952 suffix to BCM88950
+soc_family.BCM88952=BCM88950
+#Make FE1600 SOC properties work for FE1600 SKU 8753, by mapping the BCM88753 suffix to BCM88750
+soc_family.BCM88753=BCM88750
+#Make FE1600 SOC properties work for FE1600 SKU 8752, by mapping the BCM88752 suffix to BCM88750
+soc_family.BCM88752=BCM88750
+#Make Arad SOC properties work for QAX, by mapping the BCM88470 suffix to BCM88650
+soc_family.BCM88470=BCM88650
+
+#Make Arad SOC properties work for QUX, by mapping the BCM88270 suffix to BCM88650
+soc_family.BCM88270=BCM88650
+#Make Arad SOC properties work for FLAIR, by mapping the BCM8206 suffix to BCM88650
+soc_family.BCM8206=BCM88650
+#Make Arad SOC properties work for JERICHO_PLUS, by mapping the BCM88470 suffix to BCM88650
+soc_family.BCM88680=BCM88650
+
+# Use different mymac addresses for ipv4 and ipv6 when using vrrp for mymac termination.
+#l3_vrrp_ipv6_distinct=1
+
+# Enable multiple mymac termination mode.
+# In order to enable it, also set l3_vrrp_ipv6_distinct=0 and l3_vrrp_max_vid=0 since vrrp and
+# multiple mymac mode can't co exist.
+#l3_multiple_mymac_termination_enable=1
+
+# Distinguish between ipv4 and all other l3 protocols when multiple mymac terminating
+#l3_multiple_mymac_termination_mode=1
+
+# Usually the final DP given by the meter (or the In-DP) is unchanged, and can be from 0-3.
+# When this SOC property is set to 1, when the final INGRESS DP is 2,
+# it is mapped to 1 instead, and thus only the values 0-1 and 3 can be output.
+# This has no effect when policer_color_resolution_mode=1.
+#custom_feature_always_map_result_dp_2_to_1=1
+
+# Dynamic port feature
+#custom_feature_dynamic_port=1
+
+# low power nif mac
+#low_power_nif_mac=0
+
+# allow modifications during traffic
+#custom_feature_allow_modifications_during_traffic=1
+
+# mem_cache_enable property
+# Cache memory mode - enable memory caching during init.
+# Note: The user MUST add the property name with suffix '_specific' before providing the list of the cached memories.
+# Possible options (suffixes):
+# _all - enable all tables (excluding read-only/write-only/dynamic/signal)
+# _predefined - enable predefined list of tables
+# _parity - enable tables protected by parity field
+# _ecc - enable tables protected by ecc field
+# _specific - enable specific tables - MUST add this suffix if specific tables should be cached
+# _specific_X - enable caching for memory X, where X is memory name. Note: will not work without the previous suffix
+# Example: (this example will enable caching of the IHP_RECYCLE_COMMAND table)
+# mem_cache_enable_specific.BCM88650=1 #(MUST be added in case specific tables should be cached)
+# mem_cache_enable_specific_IHP_RECYCLE_COMMAND.BCM88650=1
+# mem_cache_enable_specific.BCM88675=1
+# mem_cache_enable_specific_IPS_QUEUE_PRIORITY_TABLE.BCM88675=1
+
+mem_cache_enable_parity.BCM88650=1
+mem_cache_enable_parity.BCM88675=1
+mem_cache_enable_parity.BCM88202=1
+mem_cache_enable_parity.BCM88750=1
+mem_cache_enable_parity.BCM88950=1
+mem_cache_enable_ecc=0
+
+# mem_nocache property
+# Cache memory mode - disable memory caching for specific table during init.
+# Note: the user MUST add the default property name before providing the list of the uncached memories.
+# Possible options (suffixes):
+# specific_X - disable caching for memory X, where X is memory name. Note: will not work without the previous suffix
+# Example: (this example will enable caching of the IHP_TERMINATION_PROFILE_TABLE table)
+# mem_nocache.BCM88660=1 #(MUST be added in case there are uncached memories)
+# mem_nocache_IHP_TERMINATION_PROFILE_TABLE.BCM88660=1
+#mem_nocache.BCM88680=1
+#mem_nocache_PPDB_B_LIF_TABLE_LABEL_PROTOCOL_OR_LSP.BCM88680=1
+#mem_nocache_PPDB_B_LIF_TABLE.BCM88680=1
+
+
+custom_feature_no_backdoor=1
+
+# Jericho split horizon mode
+# 0 - Use 0-1 range for lif orientation.
+# 1 (default) - Use 0-1 range for lif orientation in AC lifs and 0-3 range for orientation in other lif types.
+split_horizon_forwarding_groups_mode.BCM88675=1
+split_horizon_forwarding_groups_mode.BCM88470=1
+split_horizon_forwarding_groups_mode.BCM88680=1
+
+
+# Entries capacities for public and private IP forwarding tables
+private_ip_frwrd_table_size=500000
+public_ip_frwrd_table_size=500000
+
+
+#Enable KAPS ARM and Descriptor-DMA
+dma_desc_aggregator_chain_length_max=500
+dma_desc_aggregator_buff_size_kb=100
+dma_desc_aggregator_timeout_usec=1000
+dma_desc_aggregator_enable_specific_KAPS=1
+
+#In Jericho the KAPS ARM DMA already consumes 64KB of buffer memory
+dma_desc_aggregator_buff_size_kb.BCM88675=40
+
+# Entries capacities for direct access tables in KAPS (8K granularity)
+#pmf_kaps_large_db_size=8096
+
+#enable expose of HW id instead of SW id in Traps.
+bcm886xx_rx_use_hw_trap_id.BCM88650=1
+bcm886xx_rx_use_hw_trap_id.BCM88675=1
+
+# Jericho - maximum RIF Id ( valid range is 0 to 32*1024-1)
+#rif_id_max=20000
+
+#If set, never add the PPH learn extension (unless explictly required in FP action).
+#bcm886xx_pph_learn_extension_disable.BCM88650=0
+#bcm886xx_pph_learn_extension_disable.BCM88660=0
+#bcm886xx_pph_learn_extension_disable.BCM88675=0
+
+# Jericho - field_ip_first_fragment_parsed
+#field_ip_first_fragment_parsed=0
+
+# learning_fifo_dma_buffer_size in bytes (host memory size). Valid range is 20-327680
+learning_fifo_dma_buffer_size=200000
+# learning_fifo_dma_timeout in microseconds. Valid range is 0-65535. 0 means no timeout.
+learning_fifo_dma_timeout=32767
+# learning_fifo_dma_threshold valid range is 1-16384 (0x4000)
+learning_fifo_dma_threshold=4
+
+###################################
+########### OAM and BFD ###########
+###################################
+
+# OAM / BFD initialization
+# To enable OAM set oam_enable to 1
+# To enable BFD set bfd_enable to 1
+# Be aware that OAM requires more settings (Configuring OAMP and Recycle port)
+
+# oam_enable=1
+# bfd_enable=1
+
+# Set OAMP port
+num_oamp_ports.BCM88650=0
+
+# If BFD is used, runtime_performance_optimize_enable_sched_allocation should be set to 0
+# to prevent high memory consumption
+
+# Disable the following:
+# bcm886xx_next_hop_mac_extension_enable
+# bcm886xx_ipv6_tunnel_enable
+
+# To use IEEE 1588, configure DPLL clock
+
+# Configure recycle port (assuming ucode_port_40=RCY.0)
+
+#oam_rcy_port.BCM88650=40
+#tm_port_header_type_in_40.BCM88650=TM
+#tm_port_header_type_out_40.BCM88650=ETH
+#ucode_port_40.0=RCY.0:core_0.40
+
+# MPLS-TP channel types for OAM/BFD - If MPLS-TP used, channel should be specified
+# Available types: mplstp_bfd_control_channel_type
+# mplstp_pw_ach_channel_type
+# mplstp_dlm_channel_type
+# mplstp_ilm_channel_type
+# mplstp_dm_channel_type
+# mplstp_ipv4_channel_type
+# mplstp_cc_channel_type
+# mplstp_cv_channel_type
+# mplstp_on_demand_cv_channel_type
+# mplstp_pwe_oam_channel_type
+# mplstp_ipv6_channel_type
+# mplstp_fault_oam_channel_type
+# mplstp_g8113_channel_type
+#mplstp_g8113_channel_type=0x8902
+#mplstp_fault_oam_channel_type=0x5678
+
+# Use BFD MPLS TP
+#bfd_encapsulation_mode=1
+
+# Use 1711 protocol
+#custom_feature_y1711_enabled=1
+
+# OAM DMA threshold
+#oamp_fifo_dma_event_interface_enable=1
+#oamp_fifo_dma_event_interface_timeout=0
+#oamp_fifo_dma_event_interface_buffer_size=0x1000
+#oamp_fifo_dma_event_interface_threshold=10
+
+# PORT BASED PWE TERMINATION
+#pwe_termination_port_mode_enable =1
+
+# Walk around for Inlif data Errata, for GAL packets, lookup mpls table with valid mpls label
+# it's not offical solution, just for some dedicated customer.
+# offical solution will be PMF. please refer the relevant doc.
+#custom_feature_gal_lookup_exactly=1
+
+custom_feature_cmodel_loopback=1
+
+#for IPv6UC: use Tcam instead of KAPS
+#custom_feature_l3_ipv6_uc_use_tcam=0
+# ipv6_mc need KPB library
+custom_feature_ipv6_mc_forwarding_disable = 1
+vlan_match_criteria_mode=PON_PCP_ETHERTYPE
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/dnx.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/dnx.soc
new file mode 100644
index 0000000..eb90675
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/dnx.soc
@@ -0,0 +1,192 @@
+#
+# $Id: jer.soc,v 1.90 2013/08/14 08:32:00 ninash Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+debug info
+debug appl rcload warn
+debug appl symtab warn
+debug bcm rx,tx,link,attach warn
+debug soc tests warn
+debug soc rx,phy,schan,reg,socmem,dma,mem,miim,mii,intr,counter,ddr warn
+debug soc common err
+debug sys verinet warn
+debug soc physim warn
+
+if $?QMX_A0 || $?BCM88370_A0 || $?BCM88371_A0 || $?BCM88371M_A0 || $?BCM88375_A0 || $?BCM88376_A0 || $?BCM88376M_A0 || $?BCM88377_A0 || $?BCM88378_A0 || $?BCM88379_A0 || \
+ $?QMX_A1 || $?BCM88370_A1 || $?BCM88371_A1 || $?BCM88371M_A1 || $?BCM88375_A1 || $?BCM88376_A1 || $?BCM88376M_A1 || $?BCM88377_A1 || $?BCM88378_A1 || $?BCM88379_A1 ||\
+ $?QMX_B0 || $?BCM88370_B0 || $?BCM88371_B0 || $?BCM88371M_B0 || $?BCM88375_B0 || $?BCM88376_B0 || $?BCM88376M_B0 || $?BCM88377_B0 || $?BCM88378_B0 || $?BCM88379_B0 \
+ 'local QMX 1'
+if $?JERICHO_A0 || $?BCM88670_A0 || $?BCM88671_A0 || $?BCM88671M_A0 || $?BCM88672_A0 || $?BCM88673_A0 || $?BCM88674_A0 || $?BCM88675_A0 || $?BCM88675M_A0 || $?BCM88676_A0 || $?BCM88676M_A0 || $?BCM88678_A0 || $?BCM88679_A0 || \
+ $?JERICHO_A1 || $?BCM88670_A1 || $?BCM88671_A1 || $?BCM88671M_A1 || $?BCM88672_A1 || $?BCM88673_A1 || $?BCM88674_A1 || $?BCM88675_A1 || $?BCM88675M_A1 || $?BCM88676_A1 || $?BCM88676M_A1 || $?BCM88678_A1 || $?BCM88679_A1 || \
+ $?JERICHO_B0 || $?BCM88670_B0 || $?BCM88671_B0 || $?BCM88671M_B0 || $?BCM88672_B0 || $?BCM88673_B0 || $?BCM88674_B0 || $?BCM88675_B0 || $?BCM88675M_B0 || $?BCM88676_B0 || $?BCM88676M_B0 || $?BCM88678_B0 || $?BCM88679_B0 \
+ 'local JERICHO 1'
+if $?BCM88680_A0 || $?BCM88681_A0 || $?BCM88682_A0 || $?BCM88683_A0 || $?BCM88380_A0 || $?BCM88381_A0 \
+ 'local JERPLUS 1'
+
+if $?BCM88690_A0 \
+ 'local JERTWO 1'
+
+if $?QMX \
+ 'rcload bcm88375_board.soc'
+if $?JERICHO \
+ 'rcload bcm88675_board.soc'
+
+if $?JERPLUS \
+ 'rcload bcm88680_board.soc'
+
+#
+# For Jericho-2:
+# This will have to change when we have bcm88690_board.soc
+#
+if $?JERTWO \
+ 'rcload bcm88680_board.soc'
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+set RCError=off
+debug appl shell warn
+if $?QMX \
+ 'rcload /home/negev/bcm88375_dram_tune.soc'
+
+if $?JERICHO \
+ 'rcload /home/negev/bcm88675_dram_tune.soc'
+
+debug appl shell =
+set RCError=on
+
+set RCError=off
+rcload combo28_dram.soc
+set RCError=on
+
+#Set fabric connect mode as FE for multi FAP system
+if $?diag_chassis " \
+ config add fabric_connect_mode.BCM88675=FE"
+
+# Set modid:
+# If diag_chassis is enabled (two line cards), and 'slot' is defined (slot is defined only when
+# working without a management card - set modid to be 'slot'
+# Otherwise (single line card, or management card), set modid to be 0 for unit 0, and 1 for unit != 0
+if $?diag_chassis && $?slot "\
+ local modid $slot" \
+else "\
+ local modid $unit"
+expr $modid==1; if $? "local modid 2"
+
+if $?module_id " \
+ local modid $module_id"
+
+echo "$unit: modid=$modid"
+
+# Set base_modid:
+# Id base_module_id is set, then set base_modid to have base_module_id value.
+# Otherwise, set base_modid to be 0.
+if $?base_module_id " \
+ local base_modid $base_module_id" \
+else " \
+ local base_modid 0"
+
+expr $base_modid > 0
+if $? " \
+ echo '$unit: base_modid=$base_modid'"
+
+if $?diag_chassis " \
+ local nof_devices 2" \
+else "\
+ local nof_devices 1"
+
+if $?n_devices " \
+ local nof_devices $n_devices"
+
+expr $nof_devices > 1
+if $? " \
+ echo '$unit: nof_devices=$nof_devices'"
+
+if $?mng_cpu " \
+ echo '$unit:management card - polling is set on'; \
+ config add polled_irq_mode.BCM88675=1; \
+ config add schan_intr_enable.BCM88675=0; \
+ config add tdma_intr_enable.BCM88675=0; \
+ config add tslam_intr_enable.BCM88675=0; \
+ config add miim_intr_enable.BCM88675=0; "
+
+#Counters unavailable in cmodel
+if $?cmodel " \
+ config add counter_engine_sampling_interval=0;"
+
+#default values in a case which these parameters are not exist
+if !$?diag_cosq_disable "\
+ local diag_cosq_disable 0"
+if !$?warmboot "\
+ local warmboot 0"
+if !$?diag_disable "\
+ local diag_disable 0"
+if !$?diag_no_itmh_prog_mode "\
+ local diag_no_itmh_prog_mode 0"
+if !$?l2_mode "\
+ local l2_mode 0"
+
+if $?JERPLUS "\
+ local diag_disable 0"
+local init_others NoLinkscan=0
+if $?JERPLUS "\
+ local init_others 'NoIntr=1 NoLinkscan=1 NoApplStk=0'"
+
+#Disable interrupts in cmodel
+if $?cmodel "\
+ local no_intr 1" \
+else "\
+ local no_intr 0"
+
+#
+# For Jericho-2, we TEMPORARILY disable some components to quickly enable
+# a working PCID version.
+#
+if $?JERTWO "\
+ local no_soc 0"
+
+if $?JERTWO "\
+ local no_intr 1"
+
+
+#INIT_DNX ModID=$modid NofDevices=$nof_devices CosqDisable=$diag_cosq_disable NoAppl=$diag_disable Warmboot=$warmboot NoRxLos=1 $init_others NoItmhProgMode=$diag_no_itmh_prog_mode L2Mode=$l2_mode NoIntr=$no_intr NoSoc=$no_soc
+
+INIT_DNX
+
+#LED support section start
+#Program of LED0
+local ledcode_0 '02 05 67 2D 02 01 67 2D 02 11 67 2D 02 09 67 2D\
+ 02 15 67 2D 02 0D 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+#Program of LED1
+local ledcode_1 '02 1D 67 2D 02 2D 67 2D 02 05 67 2D 02 0D 67 2D\
+ 02 09 67 2D 02 01 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+
+#Program of LED2
+local ledcode_2 '02 01 67 2D 02 09 67 2D 02 0D 67 2D 02 05 67 2D\
+ 02 2D 67 2D 02 1D 67 2D 86 E0 3A 06 28 32 00 32\
+ 01 B7 97 75 3E 16 E0 CA 06 70 3E 77 3A 67 33 75\
+ 3A 77 1C 12 A0 F8 15 1A 00 57 32 0E 87 57 32 0F\
+ 87 57' #sdk88670.hex
+
+# Download LED code into LED processors and enable (if applicable).
+if $?feature_led_proc && !$?simulator \
+ "led 0 prog $ledcode_0; \
+ led 1 prog $ledcode_1; \
+ led 2 prog $ledcode_2; \
+ led auto on; \
+ led 0 start; \
+ led 1 start; \
+ led 2 start"
+
+
+echo "dnx.soc: Done............................."
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/dune.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/dune.soc
new file mode 100644
index 0000000..57f24ea
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/dune.soc
@@ -0,0 +1,1080 @@
+#
+# $Id: dune.soc,v 1.5 2011/12/20 10:53:28 yaronm Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+# Configure fap device mode (TM/PP/TDM_OPTIMIZED/TDM_STANDARD)
+# and ftmh outlif extension depending on config variables 'packet_processing' and 'tdm' variables
+if $?tdm "\
+ echo '*** TDM MODE ***'; \
+ config add diag_cosq_disable=1; \
+ if !$?fap_device_mode 'config add fap_device_mode=TDM_STANDARD'; \
+ config add fabric_ftmh_outlif_extension=ALWAYS; \
+ config ext_qdr_type=NONE; \
+ config ext_ram_present=0"
+if !$?tdm && $?packet_processing "\
+ echo '*** PACKET PROCESSING MODE ***'; \
+ config add fabric_ftmh_outlif_extension=ALWAYS; \
+ config add fap_device_mode=PP; \
+ config add egress_encap_ip_tunnel_range_min=4095; \
+ config add egress_encap_ip_tunnel_range_max=4095; \
+ config add mpls_tunnel_term_label_range_min_0=1000; \
+ config add mpls_tunnel_term_label_range_max_0=1001; \
+ config add mpls_tunnel_term_label_range_min_1=1002; \
+ config add mpls_tunnel_term_label_range_max_1=1003; \
+ config add mpls_tunnel_term_label_range_min_2=1004; \
+ config add mpls_tunnel_term_label_range_max_2=1005; \
+ if !$?diag_cosq_disable 'config add diag_cosq_disable=0';"
+if !$?tdm && !$?packet_processing "\
+ echo '*** TM ONLY MODE ***'; \
+ config add fap_device_mode=TM; \
+ config add fabric_ftmh_outlif_extension=IF_MC; \
+ if !$?diag_cosq_disable 'config add diag_cosq_disable=0'"
+
+# When more than a single device, set connect mode to FE and modid
+# to the slot id. For a single device, set connect mode to SINGLE_FAP
+# and modid to 0. Note that when using single_fap, all fabric-facing serdes
+# lanes are set in loopback, for fabric multicast to work.
+# All options for fabric_connect_mode are FE/BACK2BACK/MESH/MULTI_STAGE_FE/SINGLE_FAP
+
+if !$?diag_cosq_disable "config add diag_cosq_disable=0"
+if !$?slot || !$?diag_chassis "local slot 0"
+if !$?board_type_GFA_BI "local board_type_GFA_BI 1"
+if !$?board_type_GFA_BI_2 "local board_type_GFA_BI_2 0"
+
+if $?diag_chassis " \
+ local nof_devices 2; \
+ config add fabric_connect_mode=FE" \
+else "\
+ local nof_devices 1; \
+ if !$?fabric_connect_mode 'config add fabric_connect_mode=SINGLE_FAP'"
+
+#Enable all quartets. Can be done per quartet using _N suffix
+config add pb_serdes_qrtt_active=1
+
+local lane_rate_nif 6250000
+local lane_rate_com_a 6250000
+if $board_type_GFA_BI "\
+ local lane_rate_fbr 5000000; \
+ local lane_rate_com_b 3125000; \
+ config add fabric_ref_clock=250000; \
+ config add combo_nif_0=1; \
+ config add combo_nif_1=1" \
+else '\
+ local lane_rate_fbr 6250000; \
+ local lane_rate_com_b 6250000; \
+ config add fabric_ref_clock=312500; \
+ config add combo_nif_0=0; \
+ config add combo_nif_1=0; \
+ for i=32,59 \'config add pb_serdes_lane_tx_phys_media_type_$i=CHIP2CHIP\''
+
+# Nif serdes quartets
+for i=0,2 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_nif'
+for i=4,6 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_nif'
+
+# Nif serdes quartet (combo-a)
+config add pb_serdes_qrtt_max_expected_rate_3=$lane_rate_com_a
+
+# Nif serdes quartet (combo-b)
+config add pb_serdes_qrtt_max_expected_rate_7=$lane_rate_com_b
+
+# Fabric serdes quartets
+for i=8,14 'config add pb_serdes_qrtt_max_expected_rate_$i=$lane_rate_fbr'
+
+# set default rate to nif rate. Override fabric lanes.
+config add pb_serdes_lane_rate=$lane_rate_nif
+for i=12,15 'config add pb_serdes_lane_rate_$i=$lane_rate_com_a'
+for i=28,31 'config add pb_serdes_lane_rate_$i=$lane_rate_com_b'
+for i=32,59 'config add pb_serdes_lane_rate_$i=$lane_rate_fbr'
+
+# Board Type configuration.
+
+if $board_type_GFA_BI "\
+ echo Configure GFA_BI Port/Interfcae/Nif/SerDes parameters; \
+ config add ucode_port_1=RXAUI7; \
+ config add ucode_port_2=RXAUI6; \
+ config add ucode_port_3=XAUI7; \
+ config add ucode_port_4=RXAUI0; \
+ config add ucode_port_5=RXAUI2; \
+ config add ucode_port_6=RXAUI4; \
+ config add ucode_port_7=RXAUI12; \
+ config add ucode_port_8=RXAUI10; \
+ config add ucode_port_9=RXAUI8; \
+ config add pb_serdes_lane_swap_polarity_tx_9=1; \
+ config add pb_serdes_lane_swap_polarity_tx_29=1; \
+ config add pb_serdes_lane_swap_polarity_rx_13=1; \
+ config add pb_serdes_lane_swap_polarity_rx_18=1; \
+ config add pb_serdes_lane_swap_polarity_rx_22=1; \
+ config add pb_serdes_lane_swap_polarity_rx_30=1; \
+ config add pb_serdes_lane_swap_polarity_rx_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt=1; \
+ config add pb_serdes_lane_rx_phys_dfelth=20; \
+ config add pb_serdes_lane_rx_phys_tlth=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt=1; \
+ config add pb_serdes_lane_tx_phys_amp_12=30; \
+ config add pb_serdes_lane_tx_phys_main_12=18; \
+ config add pb_serdes_lane_tx_phys_pre_12=3; \
+ config add pb_serdes_lane_tx_phys_post_12=13; \
+ config add pb_serdes_lane_tx_phys_amp_13=30; \
+ config add pb_serdes_lane_tx_phys_main_13=18; \
+ config add pb_serdes_lane_tx_phys_pre_13=3; \
+ config add pb_serdes_lane_tx_phys_post_13=13; \
+ config add pb_serdes_lane_tx_phys_amp_14=30; \
+ config add pb_serdes_lane_tx_phys_main_14=18; \
+ config add pb_serdes_lane_tx_phys_pre_14=3; \
+ config add pb_serdes_lane_tx_phys_post_14=13; \
+ config add pb_serdes_lane_tx_phys_amp_15=30; \
+ config add pb_serdes_lane_tx_phys_main_15=18; \
+ config add pb_serdes_lane_tx_phys_pre_15=3; \
+ config add pb_serdes_lane_tx_phys_post_15=13;"
+
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_3=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_3=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_3=15; \
+ config add pb_serdes_lane_rx_phys_tlth_3=18; \
+ config add pb_serdes_lane_rx_phys_g1cnt_3=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_12=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=1; \
+ config add pb_serdes_lane_rx_phys_tlth_12=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=18; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=0; \
+ config add pb_serdes_lane_rx_phys_tlth_13=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=2; \
+ config add pb_serdes_lane_rx_phys_tlth_14=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=19; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=0; \
+ config add pb_serdes_lane_rx_phys_tlth_15=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=0; \
+ config add pb_serdes_lane_rx_phys_tlth_28=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=0; \
+ config add pb_serdes_lane_rx_phys_tlth_29=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=0; \
+ config add pb_serdes_lane_rx_phys_tlth_30=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=12; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=0; \
+ config add pb_serdes_lane_rx_phys_tlth_31=0; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1;"
+
+# TX params for fabric rate of 5000 mbps (Negev system).
+# Overrides media type configuration.
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_tx_phys_amp_32=31; \
+ config add pb_serdes_lane_tx_phys_main_32=24; \
+ config add pb_serdes_lane_tx_phys_pre_32=0; \
+ config add pb_serdes_lane_tx_phys_post_32=0; \
+ config add pb_serdes_lane_tx_phys_amp_33=31; \
+ config add pb_serdes_lane_tx_phys_main_33=24; \
+ config add pb_serdes_lane_tx_phys_pre_33=0; \
+ config add pb_serdes_lane_tx_phys_post_33=0; \
+ config add pb_serdes_lane_tx_phys_amp_34=31; \
+ config add pb_serdes_lane_tx_phys_main_34=24; \
+ config add pb_serdes_lane_tx_phys_pre_34=0; \
+ config add pb_serdes_lane_tx_phys_post_34=0; \
+ config add pb_serdes_lane_tx_phys_amp_35=31; \
+ config add pb_serdes_lane_tx_phys_main_35=24; \
+ config add pb_serdes_lane_tx_phys_pre_35=0; \
+ config add pb_serdes_lane_tx_phys_post_35=0; \
+ config add pb_serdes_lane_tx_phys_amp_36=31; \
+ config add pb_serdes_lane_tx_phys_main_36=24; \
+ config add pb_serdes_lane_tx_phys_pre_36=0; \
+ config add pb_serdes_lane_tx_phys_post_36=0; \
+ config add pb_serdes_lane_tx_phys_amp_37=31; \
+ config add pb_serdes_lane_tx_phys_main_37=24; \
+ config add pb_serdes_lane_tx_phys_pre_37=0; \
+ config add pb_serdes_lane_tx_phys_post_37=0; \
+ config add pb_serdes_lane_tx_phys_amp_38=31; \
+ config add pb_serdes_lane_tx_phys_main_38=24; \
+ config add pb_serdes_lane_tx_phys_pre_38=0; \
+ config add pb_serdes_lane_tx_phys_post_38=0; \
+ config add pb_serdes_lane_tx_phys_amp_39=31; \
+ config add pb_serdes_lane_tx_phys_main_39=24; \
+ config add pb_serdes_lane_tx_phys_pre_39=0; \
+ config add pb_serdes_lane_tx_phys_post_39=0; \
+ config add pb_serdes_lane_tx_phys_amp_40=31; \
+ config add pb_serdes_lane_tx_phys_main_40=24; \
+ config add pb_serdes_lane_tx_phys_pre_40=0; \
+ config add pb_serdes_lane_tx_phys_post_40=0; \
+ config add pb_serdes_lane_tx_phys_amp_41=31; \
+ config add pb_serdes_lane_tx_phys_main_41=24; \
+ config add pb_serdes_lane_tx_phys_pre_41=0; \
+ config add pb_serdes_lane_tx_phys_post_41=0; \
+ config add pb_serdes_lane_tx_phys_amp_42=31; \
+ config add pb_serdes_lane_tx_phys_main_42=24; \
+ config add pb_serdes_lane_tx_phys_pre_42=0; \
+ config add pb_serdes_lane_tx_phys_post_42=0"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_tx_phys_amp_43=31; \
+ config add pb_serdes_lane_tx_phys_main_43=24; \
+ config add pb_serdes_lane_tx_phys_pre_43=0; \
+ config add pb_serdes_lane_tx_phys_post_43=0; \
+ config add pb_serdes_lane_tx_phys_amp_44=31; \
+ config add pb_serdes_lane_tx_phys_main_44=24; \
+ config add pb_serdes_lane_tx_phys_pre_44=0; \
+ config add pb_serdes_lane_tx_phys_post_44=0; \
+ config add pb_serdes_lane_tx_phys_amp_45=31; \
+ config add pb_serdes_lane_tx_phys_main_45=24; \
+ config add pb_serdes_lane_tx_phys_pre_45=0; \
+ config add pb_serdes_lane_tx_phys_post_45=0; \
+ config add pb_serdes_lane_tx_phys_amp_46=31; \
+ config add pb_serdes_lane_tx_phys_main_46=24; \
+ config add pb_serdes_lane_tx_phys_pre_46=0; \
+ config add pb_serdes_lane_tx_phys_post_46=0; \
+ config add pb_serdes_lane_tx_phys_amp_47=31; \
+ config add pb_serdes_lane_tx_phys_main_47=24; \
+ config add pb_serdes_lane_tx_phys_pre_47=0; \
+ config add pb_serdes_lane_tx_phys_post_47=0; \
+ config add pb_serdes_lane_tx_phys_amp_48=31; \
+ config add pb_serdes_lane_tx_phys_main_48=24; \
+ config add pb_serdes_lane_tx_phys_pre_48=0; \
+ config add pb_serdes_lane_tx_phys_post_48=0; \
+ config add pb_serdes_lane_tx_phys_amp_49=31; \
+ config add pb_serdes_lane_tx_phys_main_49=24; \
+ config add pb_serdes_lane_tx_phys_pre_49=0; \
+ config add pb_serdes_lane_tx_phys_post_49=0; \
+ config add pb_serdes_lane_tx_phys_amp_50=31; \
+ config add pb_serdes_lane_tx_phys_main_50=24; \
+ config add pb_serdes_lane_tx_phys_pre_50=0; \
+ config add pb_serdes_lane_tx_phys_post_50=0; \
+ config add pb_serdes_lane_tx_phys_amp_51=31; \
+ config add pb_serdes_lane_tx_phys_main_51=24; \
+ config add pb_serdes_lane_tx_phys_pre_51=0; \
+ config add pb_serdes_lane_tx_phys_post_51=0; \
+ config add pb_serdes_lane_tx_phys_amp_52=31; \
+ config add pb_serdes_lane_tx_phys_main_52=24; \
+ config add pb_serdes_lane_tx_phys_pre_52=0; \
+ config add pb_serdes_lane_tx_phys_post_52=0; \
+ config add pb_serdes_lane_tx_phys_amp_53=31; \
+ config add pb_serdes_lane_tx_phys_main_53=24; \
+ config add pb_serdes_lane_tx_phys_pre_53=0; \
+ config add pb_serdes_lane_tx_phys_post_53=0; \
+ config add pb_serdes_lane_tx_phys_amp_54=31; \
+ config add pb_serdes_lane_tx_phys_main_54=24; \
+ config add pb_serdes_lane_tx_phys_pre_54=0; \
+ config add pb_serdes_lane_tx_phys_post_54=0; \
+ config add pb_serdes_lane_tx_phys_amp_55=31; \
+ config add pb_serdes_lane_tx_phys_main_55=24; \
+ config add pb_serdes_lane_tx_phys_pre_55=0; \
+ config add pb_serdes_lane_tx_phys_post_55=0; \
+ config add pb_serdes_lane_tx_phys_amp_56=31; \
+ config add pb_serdes_lane_tx_phys_main_56=24; \
+ config add pb_serdes_lane_tx_phys_pre_56=0; \
+ config add pb_serdes_lane_tx_phys_post_56=0; \
+ config add pb_serdes_lane_tx_phys_amp_57=31; \
+ config add pb_serdes_lane_tx_phys_main_57=24; \
+ config add pb_serdes_lane_tx_phys_pre_57=0; \
+ config add pb_serdes_lane_tx_phys_post_57=0; \
+ config add pb_serdes_lane_tx_phys_amp_58=31; \
+ config add pb_serdes_lane_tx_phys_main_58=24; \
+ config add pb_serdes_lane_tx_phys_pre_58=0; \
+ config add pb_serdes_lane_tx_phys_post_58=0; \
+ config add pb_serdes_lane_tx_phys_amp_59=31; \
+ config add pb_serdes_lane_tx_phys_main_59=24; \
+ config add pb_serdes_lane_tx_phys_pre_59=0; \
+ config add pb_serdes_lane_tx_phys_post_59=0;"
+
+# RX params for fabric rate of 5000 mbps (Negev system)
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_32=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=21; \
+ config add pb_serdes_lane_rx_phys_tlth_32=35; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_33=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=28; \
+ config add pb_serdes_lane_rx_phys_tlth_33=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=18; \
+ config add pb_serdes_lane_rx_phys_tlth_34=26; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=23; \
+ config add pb_serdes_lane_rx_phys_tlth_35=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=22; \
+ config add pb_serdes_lane_rx_phys_tlth_36=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=20; \
+ config add pb_serdes_lane_rx_phys_tlth_37=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=23; \
+ config add pb_serdes_lane_rx_phys_tlth_38=29; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=24; \
+ config add pb_serdes_lane_rx_phys_tlth_39=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=21; \
+ config add pb_serdes_lane_rx_phys_tlth_40=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=20; \
+ config add pb_serdes_lane_rx_phys_tlth_41=6; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1;"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=18; \
+ config add pb_serdes_lane_rx_phys_tlth_42=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=26; \
+ config add pb_serdes_lane_rx_phys_tlth_43=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=22; \
+ config add pb_serdes_lane_rx_phys_tlth_44=34; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=21; \
+ config add pb_serdes_lane_rx_phys_tlth_46=28; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=16; \
+ config add pb_serdes_lane_rx_phys_tlth_47=9; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=23; \
+ config add pb_serdes_lane_rx_phys_tlth_48=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=28; \
+ config add pb_serdes_lane_rx_phys_tlth_49=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=24;"
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_tlth_50=19; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_51=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=22; \
+ config add pb_serdes_lane_rx_phys_tlth_51=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=24; \
+ config add pb_serdes_lane_rx_phys_tlth_52=33; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=20; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=10; \
+ config add pb_serdes_lane_rx_phys_tlth_53=5; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=29; \
+ config add pb_serdes_lane_rx_phys_tlth_54=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=24; \
+ config add pb_serdes_lane_rx_phys_tlth_55=22; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=22; \
+ config add pb_serdes_lane_rx_phys_tlth_56=31; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=22; \
+ config add pb_serdes_lane_rx_phys_tlth_57=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1;"
+
+if $board_type_GFA_BI "\
+ config add pb_serdes_lane_rx_phys_zcnt_58=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=23; \
+ config add pb_serdes_lane_rx_phys_tlth_58=26; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=21; \
+ config add pb_serdes_lane_rx_phys_tlth_59=25; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1;"
+
+if $board_type_GFA_BI_2 "\
+ echo Configure GFA_BI_2 Port/Interfcae/Nif/SerDes parameters; \
+ config add ucode_port_1=RXAUI3; \
+ config add ucode_port_2=RXAUI2; \
+ config add ucode_port_3=RXAUI1; \
+ config add ucode_port_4=RXAUI0; \
+ config add ucode_port_5=RXAUI8; \
+ config add ucode_port_6=RXAUI9; \
+ config add ucode_port_7=RXAUI5; \
+ config add ucode_port_8=RXAUI4; \
+ config add ucode_port_9=RXAUI12; \
+ config add ucode_port_10=RXAUI13; \
+ config add ucode_port_11=RXAUI10; \
+ config add ucode_port_12=RXAUI11; \
+ config add lanes_swap_6=1; \
+ config add lanes_swap_10=1; \
+ config add lanes_swap_11=1; \
+ config add lanes_swap_12=1; \
+ config add pb_serdes_lane_swap_polarity_tx_12=1; \
+ config add pb_serdes_lane_swap_polarity_tx_14=1; \
+ config add pb_serdes_lane_swap_polarity_tx_28=1; \
+ config add pb_serdes_lane_swap_polarity_tx_31=1; \
+ config add pb_serdes_lane_swap_polarity_tx_32=1; \
+ config add pb_serdes_lane_swap_polarity_tx_34=1; \
+ config add pb_serdes_lane_swap_polarity_tx_41=1; \
+ config add pb_serdes_lane_swap_polarity_rx_48=1; \
+ config add pb_serdes_lane_swap_polarity_rx_50=1; \
+ config add pb_serdes_lane_swap_polarity_rx_52=1; \
+ config add pb_serdes_lane_swap_polarity_rx_55=1; \
+ config add pb_serdes_lane_swap_polarity_rx_56=1; \
+ config add pb_serdes_lane_swap_polarity_rx_58=1;"
+
+if $board_type_GFA_BI_2 && !$system_is_fe600_in_system "\
+ config add pb_serdes_lane_rx_phys_zcnt=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt=1; \
+ config add pb_serdes_lane_rx_phys_dfelth=1; \
+ config add pb_serdes_lane_rx_phys_tlth=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt=1; \
+ config add pb_serdes_lane_tx_phys_amp=30; \
+ config add pb_serdes_lane_tx_phys_main=18; \
+ config add pb_serdes_lane_tx_phys_pre=3; \
+ config add pb_serdes_lane_tx_phys_post=13;"
+
+#GFA-BI2, with fe600, slot 0
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_12=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=11; \
+ config add pb_serdes_lane_rx_phys_tlth_12=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=17; \
+ config add pb_serdes_lane_rx_phys_tlth_13=7; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=18; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=7; \
+ config add pb_serdes_lane_rx_phys_tlth_14=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=21; \
+ config add pb_serdes_lane_rx_phys_tlth_15=21; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=18; \
+ config add pb_serdes_lane_rx_phys_tlth_28=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=9; \
+ config add pb_serdes_lane_rx_phys_tlth_29=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=18; \
+ config add pb_serdes_lane_rx_phys_tlth_30=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=10; \
+ config add pb_serdes_lane_rx_phys_tlth_31=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_32=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=22; \
+ config add pb_serdes_lane_rx_phys_tlth_32=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_33=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=13; \
+ config add pb_serdes_lane_rx_phys_tlth_33=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=20; \
+ config add pb_serdes_lane_rx_phys_tlth_34=30; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=11; \
+ config add pb_serdes_lane_rx_phys_tlth_35=5; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=0; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=11; \
+ config add pb_serdes_lane_rx_phys_tlth_36=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=10; \
+ config add pb_serdes_lane_rx_phys_tlth_37=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=20; \
+ config add pb_serdes_lane_rx_phys_tlth_38=11; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=9; \
+ config add pb_serdes_lane_rx_phys_tlth_39=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=24; \
+ config add pb_serdes_lane_rx_phys_tlth_40=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=9; \
+ config add pb_serdes_lane_rx_phys_tlth_41=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=10; \
+ config add pb_serdes_lane_rx_phys_tlth_42=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=25; \
+ config add pb_serdes_lane_rx_phys_tlth_43=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=9; \
+ config add pb_serdes_lane_rx_phys_tlth_44=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=9; \
+ config add pb_serdes_lane_rx_phys_tlth_46=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=11; \
+ config add pb_serdes_lane_rx_phys_tlth_47=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=8; \
+ config add pb_serdes_lane_rx_phys_tlth_48=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=15; \
+ config add pb_serdes_lane_rx_phys_tlth_49=13; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=17; \
+ config add pb_serdes_lane_rx_phys_tlth_50=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && !$slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_51=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=8; \
+ config add pb_serdes_lane_rx_phys_tlth_51=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=6; \
+ config add pb_serdes_lane_rx_phys_tlth_52=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=11; \
+ config add pb_serdes_lane_rx_phys_tlth_53=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=5; \
+ config add pb_serdes_lane_rx_phys_tlth_54=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=14; \
+ config add pb_serdes_lane_rx_phys_tlth_55=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=20; \
+ config add pb_serdes_lane_rx_phys_tlth_56=21; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=14; \
+ config add pb_serdes_lane_rx_phys_tlth_57=7; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_58=19; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=11; \
+ config add pb_serdes_lane_rx_phys_tlth_58=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=12; \
+ config add pb_serdes_lane_rx_phys_tlth_59=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1"
+
+#GFA-BI2, with fe600, slot 1
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_12=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_12=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_12=9; \
+ config add pb_serdes_lane_rx_phys_tlth_12=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_12=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_13=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_13=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_13=20; \
+ config add pb_serdes_lane_rx_phys_tlth_13=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_13=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_14=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_14=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_14=9; \
+ config add pb_serdes_lane_rx_phys_tlth_14=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_14=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_15=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_15=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_15=10; \
+ config add pb_serdes_lane_rx_phys_tlth_15=9; \
+ config add pb_serdes_lane_rx_phys_g1cnt_15=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_28=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_28=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_28=14; \
+ config add pb_serdes_lane_rx_phys_tlth_28=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_28=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_29=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_29=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_29=9; \
+ config add pb_serdes_lane_rx_phys_tlth_29=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_29=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_30=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_30=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_30=6; \
+ config add pb_serdes_lane_rx_phys_tlth_30=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_30=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_31=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_31=14; \
+ config add pb_serdes_lane_rx_phys_tlth_31=8; \
+ config add pb_serdes_lane_rx_phys_g1cnt_31=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_32=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_32=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_32=19; \
+ config add pb_serdes_lane_rx_phys_tlth_32=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_32=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_33=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_33=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_33=11; \
+ config add pb_serdes_lane_rx_phys_tlth_33=10; \
+ config add pb_serdes_lane_rx_phys_g1cnt_33=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_34=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_34=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_34=17; \
+ config add pb_serdes_lane_rx_phys_tlth_34=20; \
+ config add pb_serdes_lane_rx_phys_g1cnt_34=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_35=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_35=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_35=12; \
+ config add pb_serdes_lane_rx_phys_tlth_35=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_35=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_36=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_36=10; \
+ config add pb_serdes_lane_rx_phys_tlth_36=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_36=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_37=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_37=10; \
+ config add pb_serdes_lane_rx_phys_tlth_37=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_37=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_38=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_38=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_38=20; \
+ config add pb_serdes_lane_rx_phys_tlth_38=14; \
+ config add pb_serdes_lane_rx_phys_g1cnt_38=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_39=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_39=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_39=11; \
+ config add pb_serdes_lane_rx_phys_tlth_39=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_39=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_40=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_40=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_40=24; \
+ config add pb_serdes_lane_rx_phys_tlth_40=18; \
+ config add pb_serdes_lane_rx_phys_g1cnt_40=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_41=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_41=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_41=11; \
+ config add pb_serdes_lane_rx_phys_tlth_41=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_41=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_42=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_42=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_42=10; \
+ config add pb_serdes_lane_rx_phys_tlth_42=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_42=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_43=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_43=4; \
+ config add pb_serdes_lane_rx_phys_dfelth_43=22; \
+ config add pb_serdes_lane_rx_phys_tlth_43=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_43=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_44=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_44=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_44=7; \
+ config add pb_serdes_lane_rx_phys_tlth_44=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_44=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_45=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_45=18; \
+ config add pb_serdes_lane_rx_phys_tlth_45=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_45=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_46=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_46=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_46=9; \
+ config add pb_serdes_lane_rx_phys_tlth_46=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_46=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_47=22; \
+ config add pb_serdes_lane_rx_phys_z1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_dfelth_47=9; \
+ config add pb_serdes_lane_rx_phys_tlth_47=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_47=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_48=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_48=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_48=8; \
+ config add pb_serdes_lane_rx_phys_tlth_48=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_48=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_49=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_49=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_49=12; \
+ config add pb_serdes_lane_rx_phys_tlth_49=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_49=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_50=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_50=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_50=18; \
+ config add pb_serdes_lane_rx_phys_tlth_50=11; \
+ config add pb_serdes_lane_rx_phys_g1cnt_50=1"
+if $board_type_GFA_BI_2 && $system_is_fe600_in_system && $slot "\
+ config add pb_serdes_lane_rx_phys_zcnt_51=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_51=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_51=7; \
+ config add pb_serdes_lane_rx_phys_tlth_51=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_51=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_52=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_52=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_52=8; \
+ config add pb_serdes_lane_rx_phys_tlth_52=2; \
+ config add pb_serdes_lane_rx_phys_g1cnt_52=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_53=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_53=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_53=12; \
+ config add pb_serdes_lane_rx_phys_tlth_53=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_53=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_54=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_54=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_54=7; \
+ config add pb_serdes_lane_rx_phys_tlth_54=3; \
+ config add pb_serdes_lane_rx_phys_g1cnt_54=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_55=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_55=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_55=12; \
+ config add pb_serdes_lane_rx_phys_tlth_55=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_55=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_56=24; \
+ config add pb_serdes_lane_rx_phys_z1cnt_56=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_56=21; \
+ config add pb_serdes_lane_rx_phys_tlth_56=16; \
+ config add pb_serdes_lane_rx_phys_g1cnt_56=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_57=23; \
+ config add pb_serdes_lane_rx_phys_z1cnt_57=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_57=8; \
+ config add pb_serdes_lane_rx_phys_tlth_57=4; \
+ config add pb_serdes_lane_rx_phys_g1cnt_57=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_58=17; \
+ config add pb_serdes_lane_rx_phys_z1cnt_58=3; \
+ config add pb_serdes_lane_rx_phys_dfelth_58=8; \
+ config add pb_serdes_lane_rx_phys_tlth_58=1; \
+ config add pb_serdes_lane_rx_phys_g1cnt_58=1; \
+ config add pb_serdes_lane_rx_phys_zcnt_59=21; \
+ config add pb_serdes_lane_rx_phys_z1cnt_59=2; \
+ config add pb_serdes_lane_rx_phys_dfelth_59=14; \
+ config add pb_serdes_lane_rx_phys_tlth_59=12; \
+ config add pb_serdes_lane_rx_phys_g1cnt_59=1"
+
+# DRAM pre-configurations according to config variables which defines
+# the dram type.
+
+#DDR3
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 || \
+ $?dram_type_DDR3_MICRON_MT41J64M16_15E || \
+ $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G "\
+ config add ext_ram_type=DDR3; \
+ config add ext_ram_columns=1024; \
+ config add ext_ram_banks=8"
+if $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G "\
+ config add ext_ram_total_size=3072"
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 || \
+ $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 || \
+ $?dram_type_DDR3_MICRON_MT41J64M16_15E "\
+ config add ext_ram_total_size=1536"
+
+#GDDR3
+if $?dram_type_GDDR3_SAMSUNG_K4J52324QE \
+ "config add ext_ram_type=GDDR3" \
+ "config add ext_ram_columns=512" \
+ "config add ext_ram_banks=8" \
+ "config add ext_ram_total_size=384"
+
+#DDR2
+if $?dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7 \
+ "config add ext_ram_type=DDR2" \
+ "config add ext_ram_columns=1024" \
+ "config add ext_ram_banks=4" \
+ "config add ext_ram_total_size=768"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1600 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=11" \
+ "config add ext_ram_c_wr_latency=8" \
+ "config add ext_ram_t_rc=48750" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=35000" \
+ "config add ext_ram_t_faw=40000" \
+ "config add ext_ram_t_rcd_rd=13750" \
+ "config add ext_ram_t_rcd_wr=13750" \
+ "config add ext_ram_t_rrd=7500" \
+ "config add ext_ram_t_ref=3900" \
+ "config add ext_ram_t_rp=13750" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+if $?dram_type_DDR3_SAMSUNG_K4B1G1646E_HCK0_1333 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=8" \
+ "config add ext_ram_t_rc=50000" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=36666" \
+ "config add ext_ram_t_faw=45000" \
+ "config add ext_ram_t_rcd_rd=15000" \
+ "config add ext_ram_t_rcd_wr=15000" \
+ "config add ext_ram_t_rrd=8333" \
+ "config add ext_ram_t_ref=3900" \
+ "config add ext_ram_t_rp=15000" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=8333" \
+ "config add ext_ram_t_rtp=6666"
+
+if $?dram_type_DDR3_MICRON_MT41J64M16_15E || $?dram_type_DDR3_MICRON_MT41J128M16HA_15E_2G \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=32" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=7" \
+ "config add ext_ram_t_rc=49500" \
+ "config add ext_ram_t_rfc=110000" \
+ "config add ext_ram_t_ras=36000" \
+ "config add ext_ram_t_faw=50000" \
+ "config add ext_ram_t_rcd_rd=13500" \
+ "config add ext_ram_t_rcd_wr=13500" \
+ "config add ext_ram_t_rrd=7500" \
+ "config add ext_ram_t_ref=3900c" \
+ "config add ext_ram_t_rp=13500" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+# Samsung (K4J52324QE)
+# The following parameters correspond to BC-16 dash, and were tested in
+# dune's lab with BC-14 dash dram working in frequency of 533MHz.
+if $?dram_type_GDDR3_SAMSUNG_K4J52324QE \
+ "config add ext_ram_ap_bit_pos=8" \
+ "config add ext_ram_burst_size=16" \
+ "config add ext_ram_gddr3_mrs0_wr1=0x00000312" \
+ "config add ext_ram_gddr3_emr0_wr1=0x0000109d" \
+ "config add ext_ram_c_cas_latency=9" \
+ "config add ext_ram_c_wr_latency=1" \
+ "config add ext_ram_t_rc_clk=24" \
+ "config add ext_ram_t_rfc_clk=29" \
+ "config add ext_ram_t_ras_clk=16" \
+ "config add ext_ram_t_faw_clk=5" \
+ "config add ext_ram_t_rcd_rd_clk=9" \
+ "config add ext_ram_t_rcd_wr_clk=6" \
+ "config add ext_ram_t_rrd_clk=7" \
+ "config add ext_ram_t_ref=1450" \
+ "config add ext_ram_t_rp_clk=8" \
+ "config add ext_ram_t_wr_clk=8" \
+ "config add ext_ram_t_wtr_clk=4" \
+ "config add ext_ram_t_rtp_clk=4"
+
+if $?dram_type_DDR2_MICRON_K4T51163QE_ZC_LF7 \
+ "config add ext_ram_ap_bit_pos=10" \
+ "config add ext_ram_burst_size=16" \
+ "config add ext_ram_auto_mode=TRUE" \
+ "config add ext_ram_c_cas_latency=6" \
+ "config add ext_ram_c_wr_latency=5" \
+ "config add ext_ram_t_rc=60000" \
+ "config add ext_ram_t_rfc=105000" \
+ "config add ext_ram_t_ras=45000" \
+ "config add ext_ram_t_faw=45000" \
+ "config add ext_ram_t_rcd_rd=15000" \
+ "config add ext_ram_t_rcd_wr=15000" \
+ "config add ext_ram_t_rrd=10000" \
+ "config add ext_ram_t_ref=3900)" \
+ "config add ext_ram_t_rp=15000" \
+ "config add ext_ram_t_wr=15000" \
+ "config add ext_ram_t_wtr=7500" \
+ "config add ext_ram_t_rtp=7500"
+
+
+# If using elk, override relevant parameters:
+if $?pcp_elk "\
+ echo *** OVERRIDING DEFAULT CONFIG WITH ELK CONFIG ***; \
+ config combo_ref_clock=125000; \
+ config pb_serdes_qrtt_max_expected_rate_7=3750000; \
+ config pb_serdes_lane_rate_28=3750000; \
+ config pb_serdes_lane_rate_29=3750000; \
+ config pb_serdes_lane_rate_30=3750000; \
+ config pb_serdes_lane_rate_31=3750000; \
+ config add external_lookup_mal=14; \
+ config add spaui_ipg_dic_mode=MIN; \
+ config add spaui_ipg_size=1; \
+ config add spaui_crc_mode=32b; \
+ config add spaui_preamble_size=0; \
+ config add spaui_preamble_skip_sop=1; \
+ config add spaui_is_double_size_sop_even_only=1; \
+ config add spaui_link_partner_double_size_bus=1"
+
+if $?pcp_elk || $?pcp_oam || $?pcp_dma "\
+ config add streaming_if_multi_port_mode=1; \
+ config add streaming_if_discard_pkt_streaming=0; \
+ config add fabric_ftmh_outlif_extension=IF_MC" \
+else "\
+ config add streaming_if_multi_port_mode=0; \
+ config add streaming_if_discard_pkt_streaming=1;"
+
+# Run sweep pcp on real HW
+if !$?plisim && !$?warmboot " \
+ sweep pcp"
+
+# Set synts according to reference clocks
+expr $nif_ref_clock*1000; local synt_nif $?
+expr $combo_ref_clock*1000; local synt_combo $?
+expr $fabric_ref_clock*1000; local synt_fabric $?
+
+# Real HW: Take petra out of reset
+if !$?plisim && !$?warmboot " \
+ gfa_bi utils petra_reset 1; \
+ echo Configure synthesizers:; \
+ echo Fabric: $synt_fabric; gfa_bi utils synt_set 1 $synt_fabric $synt_over; \
+ echo Combo: $synt_combo; gfa_bi utils synt_set 2 $synt_combo $synt_over; \
+ echo Nif: $synt_nif; gfa_bi utils synt_set 3 $synt_nif $synt_over; \
+ echo Core: $synt_core; gfa_bi utils synt_set 4 $synt_core $synt_over; \
+ echo DDR: $synt_ddr; gfa_bi utils synt_set 5 $synt_ddr $synt_over; \
+ echo Phy: $synt_phy; gfa_bi utils synt_set 10 $synt_phy $synt_over; \
+ gfa_bi utils petra_reset 0"
+
+dbm soc error
+dbm bcm error
+
+echo "$unit:init soc"
+init soc
+echo "$unit:init soc - Done"
+
+echo "$unit:init bcm"
+init bcm
+
+echo "$unit:init bcm - Done"
+
+if $?warmboot "\
+ echo 'Warmboot: init done'; \
+ echo 'dune.soc: Done.'; \
+ exit"
+
+# Real HW + non using sweep: Init phys
+if !$?plisim " \
+ gfa_bi utils phys"
+
+if !$?no_bcm && !$?diag_disable "\
+ init appl_dpp $slot $nof_devices $diag_cosq_disable;" \
+else "\
+ echo 'Skipping diag_init. In order to run traffic, extra configuration must be performed.'"
+
+# If running BCM library:
+# Start linkscan task and set port linkscan mode.
+if !$?no_bcm && !$?pcp_elk "\
+ linkscan 250000; \
+ linkscan spbm=xe"
+
+# If using elk, configure bsp:
+if $?pcp_elk "\
+ echo *** BSP ELK CONFIGURATIONS ***; \
+ gfa_bi elk_init;"
+
+# If using pcp dma then init dma
+if !$?plisim && $?pcp_dma " \
+ echo *** PCP DMA CONFIGURATIONS ***; \
+ gfa_bi dma_init"
+
+#if $?diag_chassis && !$slot "rcload rc/negev_rpc_master.soc.assi" # Master on slot 0
+#if $?diag_chassis && $slot "rcload rc/negev_rpc_slave.soc.assi" # Slave on slot 1
+
+echo "dune.soc: Done."
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/mk_bcm_node.sh b/bal_release/3rdparty/bcm-sdk/rc/svk4/mk_bcm_node.sh
new file mode 100755
index 0000000..80ce413
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/mk_bcm_node.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+mknod /dev/linux-user-bde c 126 0
+mknod /dev/linux-kernel-bde c 127 0
+mknod /dev/linux-uk-proxy c 125 0
+
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/qax.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/qax.soc
new file mode 100644
index 0000000..895ae81
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/qax.soc
@@ -0,0 +1,128 @@
+#
+# $Id: qax.soc,v 1.90 2013/08/14 08:32:00 ninash Exp $
+#
+# $Copyright: (c) 2011 Broadcom Corporation
+# All Rights Reserved.$
+#
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+#der 0x40 4
+#exit
+
+debug info
+debug appl rcload warn
+debug appl symtab warn
+debug bcm rx,tx,link,attach warn
+debug soc tests warn
+debug soc rx,phy,schan,reg,socmem,dma,mem,miim,mii,intr,counter,ddr warn
+debug soc common err
+debug sys verinet warn
+debug soc physim warn
+
+if $?QAX \
+ 'rcload bcm88470_board.soc'
+
+if $?QUX \
+ 'rcload bcm88270_board.soc'
+
+# Load DRAM tuning properties from local File. RcLoad will not fail if file not found, and will not show errors of missing file.
+set RCError=off
+debug appl shell warn
+if $?QAX \
+ 'rcload /home/negev/bcm88470_dram_tune.soc'
+if $?QUX \
+ 'rcload /home/negev/bcm88270_dram_tune.soc'
+
+debug appl shell =
+set RCError=on
+
+set RCError=off
+rcload combo28_dram.soc
+set RCError=on
+
+#Set fabric connect mode as FE for multi FAP system
+if $?diag_chassis " \
+ config add fabric_connect_mode.BCM88470=FE"
+
+# Set modid:
+# If diag_chassis is enabled (two line cards), and 'slot' is defined (slot is defined only when
+# working without a management card - set modid to be 'slot'
+# Otherwise (single line card, or management card), set modid to be 0 for unit 0, and 1 for unit != 0
+if $?diag_chassis && $?slot "\
+ local modid $slot" \
+else "\
+ local modid $unit"
+expr $modid==1; if $? "local modid 2"
+
+if $?module_id " \
+ local modid $module_id"
+
+echo "$unit: modid=$modid"
+
+# Set base_modid:
+# Id base_module_id is set, then set base_modid to have base_module_id value.
+# Otherwise, set base_modid to be 0.
+if $?base_module_id " \
+ local base_modid $base_module_id" \
+else " \
+ local base_modid 0"
+
+expr $base_modid > 0
+if $? " \
+ echo '$unit: base_modid=$base_modid'"
+
+if $?diag_chassis " \
+ local nof_devices 2" \
+else "\
+ local nof_devices 1"
+
+if $?n_devices " \
+ local nof_devices $n_devices"
+
+expr $nof_devices > 1
+if $? " \
+ echo '$unit: nof_devices=$nof_devices'"
+
+if $?mng_cpu " \
+ echo '$unit:management card - polling is set on'; \
+ config add polled_irq_mode.BCM88675=1; \
+ config add schan_intr_enable.BCM88675=0; \
+ config add tdma_intr_enable.BCM88675=0; \
+ config add tslam_intr_enable.BCM88675=0; \
+ config add miim_intr_enable.BCM88675=0; "
+
+#Counters unavailable in cmodel
+if $?cmodel " \
+ config add counter_engine_sampling_interval=0;"
+
+#default values in a case which these parameters are not exist
+if !$?diag_cosq_disable "\
+ local diag_cosq_disable 0"
+if !$?warmboot "\
+ local warmboot 0"
+if !$?diag_disable "\
+ local diag_disable 0"
+if !$?diag_no_itmh_prog_mode "\
+ local diag_no_itmh_prog_mode 0"
+if !$?l2_mode "\
+ local l2_mode 0"
+
+#Disable interrupts in cmodel
+if $?cmodel "\
+ local no_intr 1" \
+else "\
+ local no_intr 0"
+
+if $?QUX "\
+ local no_elk 1" \
+else "\
+ local no_elk 0"
+
+INIT_DNX ModID=$modid NofDevices=$nof_devices CosqDisable=$diag_cosq_disable NoAppl=$diag_disable Warmboot=$warmboot NoRxLos=1 NoLinkscan=0 NoElkDevice=$no_elk NoElkAppl=0 NoItmhProgMode=$diag_no_itmh_prog_mode L2Mode=$l2_mode NoIntr=$no_intr
+
+#echo "performing force forward to sysport 1"
+#mod IHP_PINFO_LLR 0 256 DEFAULT_CPU_TRAP_CODE=200 DEFAULT_ACTION_PROFILE_FWD=7
+#mod IHB_FWD_ACT_PROFILE 200 1 FWD_ACT_DESTINATION=0x10001 FWD_ACT_DESTINATION_OVERWRITE=1
+#echo "performing credit flush from NIF to EGQ"
+#m NBIH_TX_EGRESS_CREDITS_DEBUG_PM TX_FLUSH_EGRESS_PORT_0_MLF_0_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_1_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_2_QMLF_N=1 TX_FLUSH_EGRESS_PORT_0_MLF_3_QMLF_N=1
+echo "qax.soc: Done."
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/rc.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/rc.soc
new file mode 100644
index 0000000..b38ed6f
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/rc.soc
@@ -0,0 +1,1790 @@
+# $Id: rc.soc,v 1.192 2013/07/17 22:13:43 dkelley Exp $
+# $Copyright: (c) 1998-2001 Broadcom Corp.
+# All Rights Reserved.$
+#
+# Initialization RC (run commands) file
+#
+# These are default commands that are read and executed by default
+# when BCM boots up. Typically this file is called rc.soc and resides
+# in the flash filesystem, NVRAM, or disk.
+#
+# Board Configuration Setting
+#
+# This file uses configuration properties to know on which board
+# it is running. Currently one of following settings must be made:
+#
+# BCM95670K8 config add herc8=1
+# BCM95690K24 config add draco_b2b=1
+# BCM95690K24S config add draco_stk=1
+# BCM95690R24 config add galahad=1
+# BCM95690R24S config add merlin=1
+# BCM95690R48S config add lancelot=1
+# BCM95691K12 config add draco_k12=1
+# White Knight config add white_knight=1 (not shipping)
+# Black Knight config add black_knight=1 (not shipping)
+# BCM95673K2S config add twolynx=1
+# BCM95673R8 config add herculynx=1
+# BCM95673R24S config add lynxalittle=1
+# BCM95673R48S config add lynxalot=1
+# BCM95695P24SX_10 config add guenevere=1
+# BCM95650K24 config add magnum=1 (automatic for 5650L)
+# BCM95675 config add herc8_15=1
+# BCM95650R24 config add tuc24_ref=1
+# BCM95695P48LM config add lm48p=1
+# BCM95695P48LM-10 config add lm48p_B=1
+# BCM956504P48LM-10 config add lm48p_C=1
+# BCM956504P48LM-20 config add lm48p_C=1
+# BCM956504P48LM-50 config add lm48p_D=1
+# BCM956504P48POEREF config add fbpoe=1
+# BCM956504P24REF P0 config add fb24=1
+# BCM956504P24 P0 config add fb24=1
+# BCM956102P48 config add felix48=1
+# BCM953300P24REF config add mirage24=1
+# BCM956800K20C config add bradley_1g=1
+# BCM956700K16 config add humv=1
+# BCM956800K20 config add bradley=1
+# BCM956580K16 config add goldwing=1
+# BCM956314P24REF config add bcm56314p24ref=1
+# BCM956024P48REF config add BCM956024P48REF=1
+# BCM956224P48REF config add BCM956224P48REF=1
+# BCM956224R50T config add BCM956224R50T=1
+# BCM956024R50T config add BCM956024R50T=1
+# BCM56820K24XG config add BCM56820K24XG=1
+# BCM953314R24GS config add BCM953314R24GS=1
+# BCM953314K24 config add BCM953314K24=1
+# BCM956820R24XG config add BCM956820R24XG=1
+# BCM956160R config add bcm956160r=1
+
+if $?BCM56146_A0 \
+ 'local BCM56146 1'
+
+if $?BCM56147_A0 \
+ 'local BCM56147 1'
+
+
+if $?1 "echo rc: arguments not supported; exit"
+if !$?unit "echo rc: no current unit; exit"
+
+echo "rc: unit $unit device $devname"
+local quiet no
+local echo echo
+local rcdone \$rc$unit
+if !"expr $rcdone + 0" "local echo noecho; local quiet yes"
+
+# Set convenience local variables
+
+# simulation related
+#if $?plisim \
+# "local no_bcm 1"
+if $?quickturn || $?plisim \
+ "local simulator 1"
+
+if $?simulator \
+ 'echo -n "Chip init starts at: ";date'
+
+# board related
+if $?galahad \
+ "local draco_b2b 1"
+if $?black_knight || $?white_knight || $?merlin \
+ "local draco_herc4 1"
+
+#if $?QUX_A0 \
+# 'echo blablabla;der 0x40 4 ; exit'
+
+if $?FLAIR_A0 \
+ 'echo blablabla;der 0x40 4 ; exit'
+
+if $?BCM88750_A0 || $?BCM88750_B0 || $?BCM88753_A0 || $?BCM88753_B0 || $?BCM88752_A0 || $?BCM88752_B0 || $?BCM88755_B0 || $?BCM88754_A0 || $?BCM88770_A1 || $?BCM88773_A1 || $?BCM88774_A1 || $?BCM88775_A1 || $?BCM88776_A1 || $?BCM88777_A1 || $?BCM88950_A0 || $?BCM88950_A1 || $?BCM88953_A1 || $?BCM88954_A1 || $?BCM88955_A1 || $?BCM88956_A1 || $?BCM88952_A0 || $?BCM88952_A1 || $?BCM88772_A1 \
+ 'rcload dfe.soc ; exit'
+
+if $?BCM88790_A0 \
+ 'rcload dnxf.soc ; exit'
+
+if $?ARAD_A0 || $?ARAD_B0 || $?ARAD_B1 || $?ARADPLUS_A0 || $?BCM88650_A0 || $?BCM88650_B0 || $?BCM88650_B1 || $?BCM88652_A0 || $?BCM88652_B0 || $?BCM88350_B1 || $?BCM88351_B1 || \
+ $?BCM88450_B1 || $?BCM88451_B1 || $?BCM88550_B1 || $?BCM88551_B1 || $?BCM88552_B1 || $?BCM88651_B1 || $?BCM88654_B1 || $?BCM88660_A0 || $?BCM88360_A0 || $?BCM88361_A0 || $?BCM88363_A0 ||\
+ $?BCM88460_A0 || $?BCM88461_A0 || $?BCM88560_A0 || $?BCM88561_A0 || $?BCM88562_A0 || $?BCM88661_A0 || $?BCM88664_A0 \
+ 'rcload arad.soc ; exit'
+
+if $?BCM83207_A0 \
+ 'rcload samar.soc ; exit'
+if $?BCM83208_A0 \
+ 'rcload sinai.soc ; exit'
+
+if $?QAX_A0 || $?BCM88470_A0 || $?BCM88471_A0 || $?BCM88473_A0 || $?BCM88474_A0 || $?BCM88474H_A0 || $?BCM88476_A0 || $?BCM88477_A0 || \
+ $?QAX_B0 || $?BCM88470_B0 || $?BCM88471_B0 || $?BCM88473_B0 || $?BCM88474_B0 || $?BCM88474H_B0 || $?BCM88476_B0 || $?BCM88477_B0 \
+ 'setenv QAX 1'
+
+if $?QUX_A0 || $?BCM88270_A0 \
+ 'setenv QUX 1'
+
+if $?JERICHO_A0 || $?BCM88670_A0 || $?BCM88671_A0 || $?BCM88671M_A0 || $?BCM88672_A0 || $?BCM88673_A0 || $?BCM88674_A0 || $?BCM88675_A0 || $?BCM88675M_A0 || $?BCM88676_A0 || $?BCM88676M_A0 || $?BCM88677_A0 || $?BCM88678_A0 || $?BCM88679_A0 || \
+ $?JERICHO_A1 || $?BCM88670_A1 || $?BCM88671_A1 || $?BCM88671M_A1 || $?BCM88672_A1 || $?BCM88673_A1 || $?BCM88674_A1 || $?BCM88675_A1 || $?BCM88675M_A1 || $?BCM88676_A1 || $?BCM88676M_A1 || $?BCM88677_A1 || $?BCM88678_A1 || $?BCM88679_A1 || \
+ $?QMX_A0 || $?BCM88370_A0 || $?BCM88371_A0 || $?BCM88371M_A0 || $?BCM88375_A0 || $?BCM88376_A0 || $?BCM88376M_A0 || $?BCM88377_A0 || $?BCM88378_A0 || $?BCM88379_A0 || \
+ $?QMX_A1 || $?BCM88370_A1 || $?BCM88371_A1 || $?BCM88371M_A1 || $?BCM88375_A1 || $?BCM88376_A1 || $?BCM88376M_A1 || $?BCM88377_A1 || $?BCM88378_A1 || $?BCM88379_A1 || \
+ $?JERICHO_B0 || $?BCM88670_B0 || $?BCM88671_B0 || $?BCM88671M_B0 || $?BCM88672_B0 || $?BCM88673_B0 || $?BCM88674_B0 || $?BCM88675_B0 || $?BCM88675M_B0 || $?BCM88676_B0 || $?BCM88676M_B0 || $?BCM88677_B0 || $?BCM88678_B0 || $?BCM88679_B0 || $?BCM88680_A0 || \
+ $?QMX_B0 || $?BCM88370_B0 || $?BCM88371_B0 || $?BCM88371M_B0 || $?BCM88375_B0 || $?BCM88376_B0 || $?BCM88376M_B0 || $?BCM88377_B0 || $?BCM88378_B0 || $?BCM88379_B0 || $?BCM88379_A1 || \
+ $?JERPLUS || $?BCM88680_A0 || $?BCM88681_A0 || $?BCM88682_A0 || $?BCM88683_A0 || $?BCM88380_A0 || $?BCM88381_A0 \
+ 'rcload jer.soc ; exit'
+
+if $?BCM88690_A0 \
+ 'rcload dnx.soc ; exit'
+
+if $?QAX || $?QUX\
+ 'rcload qax.soc ; exit'
+
+
+if $?BCM88202_A0 || $?ARDON_A0 || $?BCM88202_A1 || $?ARDON_A1 || $?BCM88202_A2 || $?ARDON_A2\
+ 'rcload atmf.soc ; exit'
+
+if $?ACP \
+ 'exit'
+
+if $?BCM88690_A0\
+ 'exit'
+
+if !"expr $pcidev + 0 == 0x5650" \
+ "local magnum 1"
+if $?drac || $?drac15 \
+ "local drac_any 1"
+if $?lynx || $?lynx15 \
+ "local lynx_any 1"
+if $?tucana || $?magnum \
+ "local tucana_any 1"
+if $?herc || $?herc15 \
+ "local herc_any 1"
+if $?firebolt || $?firebolt2 || $?helix || \
+ $?felix || $?helix15 || $?felix15 || $?raptor || $?raven || $?hawkeye\
+ "local firebolt_any 1"
+if !"expr $pcidev + 0 == 0xb501" \
+ "local firebolt_10x4 1"
+if $?easyrider \
+ "local easyrider_any 1"
+if !"expr $pcidev + 0 == 0xb602" \
+ "local easyrider_1x1 1"
+if $?bradley || $?humv || $?goldwing \
+ "local bradley_any 1"
+if $?drac_any || $?lynx_any || $?tucana_any \
+ "local xgs12_switch 1"
+if $?firebolt_any || $?easyrider_any || $?bradley_any \
+ "local xgs3_switch 1"
+if $?xgs12_switch || $?xgs3_switch \
+ "local xgs_switch 1"
+if $?herc_any \
+ "local xgs_fabric 1"
+if $?xgs_fabric || $?xgs_switch \
+ "local xgs 1"
+if !$?xgs \
+ "local strata 1"
+if $?strata && !$?gsl \
+ "local PBMP_ALL 0x0bffffff"
+if $?strata && $?gsl \
+ "local PBMP_ALL 0x080000ff"
+if $?BCM56214_A0 || $?BCM56014_A0 || $?BCM56215_A0 || \
+ $?BCM56214_A1 || $?BCM56014_A1 || $?BCM56215_A1 && \
+ !$?BCM956024P48REF \
+ "local rap24_ref 1"
+
+if $?BCM5655_A0 || $?BCM5655_B0 \
+ "local tucana_nohg 1"
+
+if $?BCM956024P48REF || $?BCM956224P48REF || $?BCM956024R50T || \
+ $?BCM956224R50T \
+ "local raven_eb_48p 1"
+
+if $?BCM953314R24GS \
+ "local hawkeye_p24 1"
+
+if $?BCM953314K24 \
+ "local hawkeye_k24 1"
+
+if $?firebolt_any && $?lm48p || $?lm48p_D \
+ "config add lmfb48=1"
+
+# Set software's wait for S-Channel response to 3 seconds for QuickTurn
+# (Recommend at least 10 seconds if the ARL is 100% busy with inserts.)
+if $?quickturn "stimeout 3000000"
+if $?plisim "stimeout 60000000"
+
+# Direct phy led programming: 5464 activity led becomes link/activity
+if $?drac_any && $?lancelot || $?lynxalot || $?guenevere \
+ "config add phy_led_ctrl=0x18"
+
+# Shutdown threads if system is already running
+if $?triumph3 \
+ "ibodSync off"
+counter off
+linkscan off
+if $?feature_arl_hashed && !$?simulator \
+ "l2mode off"
+if $?feature_ces && $?BCM56440_A0 \
+ "ces off"
+
+# Test on-chip memory before initializing
+#if !$?simulator "init soc; bist l3 arl cbp"
+init soc
+
+# Initialize miscellaneous chip registers
+init misc
+
+# Initialize external TCAM if necessary
+# NOTE : tcam is initialized during "init misc" unless
+# tcam_reset_toggle = 1 is configured
+if "expr $rcdone + 0" && !"expr $tcam_reset_toggle + 0" \
+ "dispatch attach 0 esw 0"
+if !"expr $tcam_reset_toggle + 0" "muxsel 0; muxsel 0x80"
+if !"expr $tcam_reset_toggle + 0" "init tcam; $echo rc: TCAM initialized"
+
+# Initialize the StrataSwitch MMU registers
+init mmu
+if $?katana2 \
+ kt2config.soc
+
+
+# Uncomment to turn off Single-Bit Error reporting on 5670
+#if $?herc "m mmu_intcntl pp_sbe_en=0"
+
+# Initialize Cell Free Address Pool
+# NOTE: this should NOT be done unless chip is known to have bad CFAP
+# memory entries that need to be mapped out.
+if $?cfap_tests "$echo rc: Initializing CFAP; cfapinit"
+
+$echo rc: MMU initialized
+
+#
+# Load uKernel
+#
+
+# Pick default FW names if not set already by config
+if !$?fw_core_0 \
+ 'local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec; \
+ if $?greyhound || $?hurricane2 || $?hurricane3 "local fw_core_0 ${fw_prefix}_0_ptpfull.srec"; \
+ if $?caladan3 "local fw_core_0 ${fw_prefix}_0.srec"; \
+ if $?helix4 && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?helix4 && $?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd_bhh.srec"; \
+ if $?tomahawk && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?tomahawk_plus && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ if $?trident2plus && !$?feature_bhh "local fw_core_0 ${fw_prefix}_0_bfd.srec"; \
+ '
+
+if !$?fw_core_1 \
+ 'local fw_core_1 ${fw_prefix}_1_ptpfull.srec; \
+ if $?caladan3 "local fw_core_1 ${fw_prefix}_1_bs.srec"; \
+ '
+
+if !$?fw_core_2 \
+ "local fw_core_2 ${fw_prefix}_2_eth_lmdm.srec"
+
+# Load the firmwares
+if $?feature_cmicm && !$?rcpu_only && !$ihost_mode && !$?feature_iproc \
+ "mcsload 0 ${fw_core_0} InitMCS=true; \
+ mcsload 1 ${fw_core_1};"
+
+if $?hurricane2 \
+ "mcsload 0 ${fw_core_0} InitMCS=true;"
+
+if $?feature_iproc && !$?hurricane2 && !$?hurricane3 && !$?rcpu_only && !$?feature_uc_mhost && !$ihost_mode\
+ "mcsload 0 ${fw_core_0} InitMCS=true TwoStage=true TwoStageAddr=0x60000000;\
+ mcsload 1 ${fw_core_1} TwoStage=true TwoStageAddr=0x6002c000;"
+
+if $?feature_iproc && !$?rcpu_only && $?feature_uc_mhost && $?num_ucs\
+ 'if !"expr $num_ucs > 0" "mcsload 0 ${fw_core_0} InitMCS=true"; \
+ if !"expr $num_ucs > 1" "mcsload 1 ${fw_core_1}"; \
+ if !"expr $num_ucs > 2" "mcsload 2 ${fw_core_2}";'
+
+#
+# Init CLI and BCM API
+#
+# This must be done after the raw register writes to avoid having state
+# clobbered. NOTE: Tables are cleared by "init bcm" below. If
+# table modifications are required, put them after "init bcm". Some
+# registers might also be affected.
+#
+
+if !$?no_bcm \
+ "init bcm; \
+ $echo rc: BCM driver initialized"
+
+if $?no_bcm \
+ "$echo rc: *** NOT initializing BCM driver ***"
+
+if $?no_bcm && $?strata \
+ 'write vtable 0 1 VLAN_TAG=0,PORT_BITMAP=0,UT_PORT_BITMAP=0; \
+ insert vtable VLAN_TAG=1,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ local pv \
+ VLAN_TAG=1,SP_ST=3,PORT_BITMAP=$PBMP_ALL,UT_PORT_BITMAP=$PBMP_ALL; \
+ write ptable 0 32 PTYPE=0; \
+ if !$?gsl "write ptable 0 24 $pv,PTYPE=1"; \
+ if !$?gsl "write ptable 24 2 $pv,PTYPE=2"; \
+ if $?gsl "write ptable 0 8 $pv,PTYPE=2"; \
+ write ptable 27 1 $pv,PTYPE=3; \
+ local pv'
+
+# Turn on mirroring of hardware ARL operations into software ARL table.
+if $?feature_arl_sorted \
+ "arlmode intr_dma; \
+ $echo rc: ARL DMA shadowing enabled"
+
+if $?feature_arl_hashed && !$?simulator && !$?rcpu_only \
+ "l2mode interval=3000000; \
+ $echo rc: L2 Table shadowing enabled"
+
+# If running BCM library, start linkscan task and set port modes
+
+if !$?no_bcm && !$?rcpu_only \
+ "linkscan 250000; \
+ port fe,ge linkscan=on autoneg=on \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port st linkscan=on txpause=false rxpause=false; \
+ port xe,ce linkscan=on autoneg=off \
+ speed=0 fullduplex=true txpause=true rxpause=true; \
+ port hg linkscan=on fullduplex=true txpause=false rxpause=false; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?rcpu_only \
+ "linkscan 250000; \
+ port e linkscan=on; \
+ port st linkscan=on; \
+ port xe linkscan=on; \
+ $echo rc: Port modes initialized"
+
+if !$?no_bcm && $?shadow \
+ "port il linkscan=on; \
+ $echo rc: Interlaken Port mode initialized"
+
+# Selectively re-enable Auto Negotiation based on config port_force_an_list.
+#if $?port_force_an_list \
+# "port $port_force_an_list autoneg=on"
+
+# No spanning tree is running, so put ports all in the forwarding state
+# stp support not available for shadow device.
+
+if !$?no_bcm && !$?shadow \
+ "stg stp 1 all forward"
+
+# Start counter task unless already started by "init bcm" above.
+if $?plisim "local dma false"
+if !$?plisim "local dma true"
+if $?device_eb_vli "local dma false"
+if $?no_bcm && !$?rcpu_only\
+ "counter Interval=1000 Pbm=all Dma=$dma; \
+ $echo rc: Counter collection enabled"
+if $?rcpu_only \
+ "counter Interval=2000000 Pbm=all Dma=false; \
+ $echo rc: Counter collection enabled"
+
+# Resynchronize the saved values kept by the 'show counter' command.
+if !$?simulator \
+ "counter sync"
+
+# By default, dump data of packets that go to CPU.
+if !$?testinit \
+ "pw report +raw"
+
+# Default LED processor program for various SDKs and reference designs.
+# Source code can be found in $SDK/led/examples.
+
+if !$?p48 "local ledcode '\
+ E0 28 60 7F 67 2F 67 6B 06 7F 80 D2 1A 74 01 12 \
+ 7E 85 05 D2 0F 71 19 52 00 12 7D 85 05 D2 1F 71 \
+ 23 52 00 12 7C 85 05 D2 05 71 2D 52 00 3A 68 32 \
+ 00 97 75 3B 12 A0 FE 7F 02 0A 50 32 01 97 75 47 \
+ 12 BA FE 7F 02 0A 50 12 BA FE 7F 95 75 59 85 12 \
+ A0 FE 7F 95 75 A8 85 77 9A 12 A0 FE 7F 95 75 63 \
+ 85 77 A1 16 7C DA 02 71 A1 77 A8 32 05 97 71 76 \
+ 06 7D D2 01 71 9A 06 7F 67 93 75 9A 32 02 97 71 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 7E D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5605.hex
+
+if $?p48 "local ledcode '\
+ E0 28 60 7F 67 43 67 3C 67 35 67 2F 06 7F 80 D2 \
+ 18 74 01 28 60 7F 67 9B 67 89 67 BF 67 83 67 3C \
+ 67 73 67 68 67 5D 06 7F 80 D2 1A 74 13 3A 70 67 \
+ AD 71 C3 77 BF 32 03 97 71 C3 77 BF 32 05 97 71 \
+ C3 77 BF 12 BA FE 7F 32 01 97 75 4F 02 06 50 32 \
+ 00 97 75 57 02 06 50 95 75 C3 85 77 BF 67 AD 75 \
+ BF 32 04 97 71 C3 77 BF 67 AD 75 BF 32 03 97 71 \
+ C3 77 BF 67 AD 75 BF 32 03 97 71 BF 32 04 97 71 \
+ BF 77 C3 67 B6 71 C3 77 BF 12 A0 FE 7F 32 00 97 \
+ 75 95 02 06 50 95 75 C3 85 77 BF 12 BA FE 7F 32 \
+ 01 97 75 A7 02 06 50 95 75 C3 85 77 BF 06 7F 12 \
+ 80 F8 15 1A 00 57 06 7F 12 80 F8 15 1A 07 57 32 \
+ 0F 87 57 32 0E 87 57'" # p48.hex
+
+if $?herc && !$?black_knight "local ledcode '\
+ 02 01 67 36 29 32 08 D7 87 32 07 D7 87 32 01 D7 \
+ 87 32 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 \
+ 74 24 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 \
+ 87 91 74 2D 3A 28 10 DA 07 75 3E FA 02 57 EA 06 \
+ 57'" # sdk5670.hex
+
+if $?herc && $?black_knight "local ledcode '\
+ 2A 03 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 00 \
+ D7 87 2A 06 32 08 D7 87 32 07 D7 87 32 01 D7 87 \
+ 32 00 D7 87 3A 08'" # knigget.hex
+
+if $?drac_any "local ledcode '\
+ E0 28 60 C3 67 4E 67 8A 06 C3 80 D2 0C 74 01 28 \
+ 60 C3 32 00 D7 87 32 01 D7 87 32 07 D7 87 32 08 \
+ D7 87 32 0F 87 32 0F 87 32 0F 87 32 0F 87 12 C2 \
+ 85 05 D2 0F 71 38 52 00 12 C1 85 05 D2 1F 71 42 \
+ 52 00 12 C0 85 05 D2 05 71 4C 52 00 3A 38 32 00 \
+ 97 75 5A 12 A0 FE C3 02 0A 50 32 01 97 75 66 12 \
+ AD FE C3 02 0A 50 12 AD FE C3 95 75 78 85 12 A0 \
+ FE C3 95 75 C0 85 77 B9 12 A0 FE C3 95 75 82 85 \
+ 77 C7 16 C0 DA 02 71 C7 77 C0 32 05 97 71 9A 32 \
+ 02 97 71 B9 06 C1 D2 01 71 B9 06 C3 67 B2 75 B9 \
+ 32 03 97 71 C0 32 04 97 75 C7 06 C2 D2 07 71 C7 \
+ 77 C0 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk5690.hex
+
+if $?draco_k12 "local ledcode '\
+ 02 0B A2 01 28 A2 01 60 C3 67 32 67 6E 06 C3 90 \
+ 75 02 12 C2 85 05 D2 0F 71 1C 52 00 12 C1 85 05 \
+ D2 1F 71 26 52 00 12 C0 85 05 D2 05 71 30 52 00 \
+ 3A 30 32 00 97 75 3E 12 A0 FE C3 02 0A 50 32 01 \
+ 97 75 4A 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 \
+ 5C 85 12 A0 FE C3 95 75 A6 85 77 9F 12 A0 FE C3 \
+ 95 75 66 85 77 AD 16 C0 DA 02 71 AD 77 A6 32 05 \
+ 97 71 7E 32 02 97 71 9F 06 C1 D2 01 71 9F 06 C3 \
+ 67 96 75 9F 32 03 97 71 A6 32 04 97 75 AD 06 C2 \
+ D2 07 71 AD 77 A6 12 80 A2 01 F8 15 1A 00 57 32 \
+ 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 \
+ 32 0E 87 57'" # k12-5690.hex
+
+if $?herc && $?white_knight "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 07 \
+ D7 87 32 01 D7 87 32 00 D7 87 57'" # wk5670.hex
+
+if $?herc && $?merlin "local ledcode '\
+ 2A 03 67 0A 2A 06 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # merlin5670.hex
+
+if $?herc && $?lancelot "local ledcode '\
+ 2A 05 67 12 2A 06 67 12 2A 03 67 12 2A 04 67 12 \
+ 3A 10 32 08 D7 87 32 00 D7 87 32 01 D7 87 32 07 \
+ D7 87 57'" # lancelot.hex
+
+if $?xgs_fabric && $?guenevere "local ledcode '\
+ 2A 04 67 0A 2A 05 67 0A 3A 04 32 07 D7 87 32 00 \
+ 32 01 B7 D7 87 57'" # guenevere5670.hex
+
+if $?drac_any && $?white_knight "local ledcode '\
+ E0 28 60 C3 67 2f 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # wk5690.hex
+
+if $?drac_any && $?merlin "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # merlin5690.hex
+
+if $?drac_any && $?galahad "local ledcode '\
+ E0 28 60 C3 67 2F 67 6B 06 C3 80 D2 0C 74 01 12 \
+ C2 85 05 D2 0F 71 19 52 00 12 C1 85 05 D2 1F 71 \
+ 23 52 00 12 C0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE C3 02 0A 50 32 01 97 75 47 \
+ 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 59 85 12 \
+ A0 FE C3 95 75 A8 85 77 9A 12 A0 FE C3 95 75 63 \
+ 85 77 A1 16 C0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 C1 D2 01 71 9A 06 C3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 C2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0F 87 32 0E 87 57 32 0E 87 32 0F 87 57'" # galahad.hex
+
+if $?drac_any && $?lm "local ledcode '\
+E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+32 0F 87 57 32 0F 87 32 0E 87 57'" # lm5690.hex
+
+if $?twolynx "local ledcode '\
+ 2A 01 67 0A 2A 00 67 0A 3A 08 32 08 D7 87 32 00 \
+ D7 87 32 01 D7 87 32 07 D7 87 57'" # twolynx.hex
+
+if $?lynx_any && $?herculynx || $?lynxalot || $?lm || $?guenevere \
+ "local ledcode '\
+12 C0 85 05 D2 03 71 0A 52 00 2A 00 67 10 3A 04 \
+32 08 D7 87 06 C0 D2 01 71 22 32 0F 87 32 0F 87 \
+77 2A 32 00 D7 87 32 01 D7 87 32 07 D7 87 57'" # herculynx.hex
+
+if $?tucana && !$?magnum "local ledcode '\
+ E0 67 23 D2 18 74 01 02 20 67 23 D2 38 74 09 02 \
+ 18 67 23 D2 1C 74 11 E9 02 80 45 80 81 DA 0D 74 \
+ 1A 3A 68 28 60 E3 67 4A 67 36 06 E4 30 87 06 E5 \
+ 30 87 06 E3 80 57 32 00 97 71 45 32 01 97 71 45 \
+ 02 0F 60 E5 57 02 0E 60 E5 57 06 E3 12 A0 F8 15 \
+ 1A 00 75 59 02 0E 60 E4 57 02 0F 60 E4 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC 67 5A 67 9C 06 FA 67 DA 06 FB 67 DA \
+ 06 FC 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0E 74 51 3A 70 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 D7 85 77 D1 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 D4 16 FF DA 02 02 FA 71 D4 77 D7 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 D1 06 FC 67 CA 02 FB 75 \
+ D1 32 02 97 71 D1 32 03 97 71 D7 32 04 97 75 D4 \
+ 06 FD D2 07 02 FB 71 D4 77 D7 12 A0 F8 15 1A 00 \
+ 57 42 00 57 42 01 57 42 02 57 D2 02 74 E3 32 0F \
+ 87 77 E6 32 0E 87 D2 01 74 EE 32 0F 87 57 32 0E \
+ 87 57'" # sdk5665.hex
+
+if $?magnum && !$?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 75 09 A2 01 60 FC 28 67 37 67 73 \
+ 06 FB 80 D2 1C 74 01 12 FD 85 05 D2 0F 71 21 52 \
+ 00 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 3A 70 32 00 97 75 43 12 C0 FE FC \
+ 02 0A 50 32 01 97 75 4F 12 DC FE FC 02 0A 50 12 \
+ DC FE FC 95 75 61 85 12 C0 FE FC 95 75 B0 85 77 \
+ A2 12 C0 FE FC 95 75 6B 85 77 A9 16 FF DA 02 71 \
+ A9 77 B0 32 05 97 71 7E 06 FE D2 01 71 A2 06 FC \
+ 67 9B 75 A2 32 02 97 71 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 FD D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0F 87 32 0F 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57'" # magnum_sdk.hex
+
+if $?tuc24_ref && $?BCM5650_C0 "local ledcode '\
+ E0 60 FB D2 18 71 10 60 FC 28 67 D0 67 C0 77 19 \
+ A2 01 60 FC 28 67 40 67 7C 06 FB 80 D2 1C 74 01 \
+ 12 FD 85 05 D2 0F 71 2A 52 00 12 FE 85 05 D2 1F \
+ 71 34 52 00 12 FF 85 05 D2 05 71 3E 52 00 3A 68 \
+ 32 00 97 75 4C 12 C0 FE FC 02 0A 50 32 01 97 75 \
+ 58 12 DC FE FC 02 0A 50 12 DC FE FC 95 75 6A 85 \
+ 12 C0 FE FC 95 75 B9 85 77 AB 12 C0 FE FC 95 75 \
+ 74 85 77 B2 16 FF DA 02 71 B2 77 B9 32 05 97 71 \
+ 87 06 FE D2 01 71 AB 06 FC 67 A4 75 AB 32 02 97 \
+ 71 AB 32 03 97 71 B9 32 04 97 75 B2 06 FD D2 07 \
+ 71 B2 77 B9 12 A0 F8 15 1A 00 57 32 0F 87 32 0F \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 \
+ 02 0E 32 00 97 71 CD 32 01 97 71 CD 80 30 87 57 \
+ 06 FC 12 A0 F8 15 1A 00 02 0F 75 DD 90 30 87 57'" # magnum.hex
+
+if $?tuc24_ref && !$?BCM5650_C0 "local ledcode '\
+ E0 28 60 FC D2 18 71 0E 67 E9 67 D9 77 1A 67 5A \
+ 67 9C 06 FA 67 D0 06 FB 67 D0 06 FC 80 D2 1C 74 \
+ 01 12 FE 85 05 D2 1F 71 2B 52 00 12 FF 85 05 D2 \
+ 05 71 35 52 00 E9 05 98 98 98 98 C2 0F 60 F9 05 \
+ 88 88 88 88 C2 F0 B6 F9 50 81 DA 0C 74 36 E9 02 \
+ 80 45 80 81 DA 0D 74 51 3A 68 32 00 97 75 66 12 \
+ C0 FE FC 02 0A 50 32 01 97 75 72 12 DC FE FC 02 \
+ 0A 50 12 DC FE FC 95 75 86 85 12 C0 FE FC 95 02 \
+ FA 75 CD 85 77 C7 12 C0 FE FC 95 75 92 85 02 FA \
+ 77 CA 16 FF DA 02 02 FA 71 CA 77 CD 32 05 97 71 \
+ A9 06 FE D2 01 02 FB 71 C7 06 FC 67 C0 02 FB 75 \
+ C7 32 02 97 71 C7 32 03 97 71 CD 32 04 97 75 CA \
+ 12 A0 F8 15 1A 00 57 42 FF 57 42 FE 57 42 EF 57 \
+ 30 87 98 98 98 98 30 87 57 02 0E 32 00 97 71 E6 \
+ 32 01 97 71 E6 80 30 87 57 06 FC 12 A0 F8 15 1A \
+ 00 02 0F 75 F6 90 30 87 57'" # tuc24_ref.hex
+
+if $?herc8_15 "local ledcode '\
+ 02 01 28 32 08 D7 87 32 07 D7 87 32 01 D7 87 32 \
+ 00 D7 87 80 D2 09 74 02 86 7F 06 7F C2 07 74 22 \
+ 86 7E 16 7E CA 07 E0 17 0D 12 08 98 27 D7 87 91 \
+ 74 2B 3A 28'" # sdk5675.hex
+
+if $?drac_any && $?lm "local ledcode '\
+ E0 28 60 C3 67 2D 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 17 52 00 12 C1 85 05 D2 1F 71 21 52 \
+ 00 12 C0 85 05 D2 05 71 2B 52 00 3A 18 32 00 97 \
+ 75 39 12 A0 FE C3 02 0A 50 32 01 97 75 45 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 5F 85 12 A0 FE \
+ C3 95 71 5C 16 C0 DA 02 71 A6 77 B4 85 77 77 12 \
+ A0 FE C3 95 75 6F 85 16 C0 DA 02 71 A6 77 AD 16 \
+ C0 DA 02 71 AD 77 B4 32 05 97 71 82 06 C1 D2 01 \
+ 71 A6 06 C3 67 9F 75 A6 32 02 97 71 A6 32 03 97 \
+ 71 B4 32 04 97 75 AD 06 C2 D2 07 71 AD 77 B4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57 00 00 00 00 00'" # lm5690.hex
+
+if $?drac_any && $?lm48p "local ledcode '\
+ E0 28 60 C3 67 7C 06 C3 80 28 60 C3 67 7C 67 40 \
+ 06 C3 90 28 60 C3 67 40 06 C3 80 80 D2 0C 74 01 \
+ 12 C2 85 05 D2 0F 71 2A 52 00 12 C1 85 05 D2 1F \
+ 71 34 52 00 12 C0 85 05 D2 05 71 3E 52 00 3A 30 \
+ 32 00 97 75 4C 12 A0 FE C3 02 0A 50 32 01 97 75 \
+ 58 12 AC FE C3 02 0A 50 12 AC FE C3 95 75 6A 85 \
+ 12 A0 FE C3 95 75 B9 85 77 AB 12 A0 FE C3 95 75 \
+ 74 85 77 B2 16 C0 DA 02 71 B2 77 B9 32 05 97 71 \
+ 8C 32 02 97 71 AB 06 C1 D2 01 71 AB 06 C3 67 A4 \
+ 75 AB 32 03 97 71 B9 32 04 97 75 B2 06 C2 D2 07 \
+ 71 B2 77 B9 12 80 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695.hex
+
+if $?drac_any && $?lm48p_B "local ledcode '\
+ E0 28 60 C3 67 79 06 C3 67 3D 06 C3 80 28 60 C3 \
+ 67 3D 06 C3 67 79 06 C3 80 D2 0C 74 01 12 C2 85 \
+ 05 D2 0F 71 27 52 00 12 C1 85 05 D2 1F 71 31 52 \
+ 00 12 C0 85 05 D2 05 71 3B 52 00 3A 30 32 00 97 \
+ 75 49 12 A0 FE C3 02 0A 50 32 01 97 75 55 12 AC \
+ FE C3 02 0A 50 12 AC FE C3 95 75 67 85 12 A0 FE \
+ C3 95 75 B6 85 77 A8 12 A0 FE C3 95 75 71 85 77 \
+ AF 16 C0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 C1 D2 01 71 A8 06 C3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 C2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p5695_10.hex
+
+if $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 55 67 91 06 E3 80 28 60 E3 67 91 \
+ 67 55 06 E3 80 D2 18 74 01 28 60 E3 67 B9 75 26 \
+ 67 CE 67 55 77 2E 32 0E 87 32 08 87 67 C0 06 E3 \
+ 80 D2 1C 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 3A 70 32 00 97 75 61 12 A0 FE E3 02 0A \
+ 50 32 01 97 75 6D 12 BC FE E3 02 0A 50 12 BC FE \
+ E3 95 75 7F 85 12 A0 FE E3 95 75 CE 85 77 C0 12 \
+ A0 FE E3 95 75 89 85 77 C7 16 E0 DA 02 71 C7 77 \
+ CE 32 05 97 71 A1 32 02 97 71 C0 06 E1 D2 01 71 \
+ C0 06 E3 67 B9 75 C0 32 03 97 71 CE 32 04 97 75 \
+ C7 06 E2 D2 07 71 C7 77 CE 12 80 F8 15 1A 00 57 \
+ 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 32 0F \
+ 87 32 0E 87 57'" # sdk56504.hex
+
+#Led program for new rev of FB SDK and Ref design
+if $?firebolt_any && !$?fb24 "local ledcode '\
+ E0 28 60 E3 67 4B 67 87 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AF 75 1C 67 C4 67 4B 77 24 32 0E 87 32 \
+ 08 87 67 B6 06 E3 80 D2 1C 74 0F 12 E2 85 05 D2 \
+ 0F 71 35 52 00 12 E1 85 05 D2 1F 71 3F 52 00 12 \
+ E0 85 05 D2 05 71 49 52 00 3A 70 32 00 97 75 57 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 63 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 75 85 12 A0 FE E3 95 \
+ 75 C4 85 77 B6 12 A0 FE E3 95 75 7F 85 77 BD 16 \
+ E0 DA 02 71 BD 77 C4 32 05 97 71 97 32 02 97 71 \
+ B6 06 E1 D2 01 71 B6 06 E3 67 AF 75 B6 32 03 97 \
+ 71 C4 32 04 97 75 BD 06 E2 D2 07 71 BD 77 C4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56504ref.hex
+
+#Override Default Firebolt LED program for Line Module
+if $?lm && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 79 06 E3 67 3D 06 E3 80 28 60 E3 \
+ 67 3D 06 E3 67 79 06 E3 80 D2 18 74 01 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 60 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B6 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AF 16 E0 DA 02 71 AF 77 B6 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B6 32 04 97 75 AF 06 E2 D2 07 71 AF 77 \
+ B6 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 \
+ 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # lm48p56504.hex
+
+#Override Default Firebolt LED program for Line Module -50 version
+if $?lm && $?lm48p_D && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 6D 06 E3 67 31 06 E3 80 D2 18 74 \
+ 01 12 E2 85 05 D2 0F 71 1B 52 00 12 E1 85 05 D2 \
+ 1F 71 25 52 00 12 E0 85 05 D2 05 71 2F 52 00 3A \
+ 60 32 00 97 75 3D 12 A0 FE E3 02 0A 50 32 01 97 \
+ 75 49 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 5B \
+ 85 12 A0 FE E3 95 75 AA 85 77 9C 12 A0 FE E3 95 \
+ 75 65 85 77 A3 16 E0 DA 02 71 A3 77 AA 32 05 97 \
+ 71 7D 32 02 97 71 9C 06 E1 D2 01 71 9C 06 E3 67 \
+ 95 75 9C 32 03 97 71 AA 32 04 97 75 A3 06 E2 D2 \
+ 07 71 A3 77 AA 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # lm48p56504_50.hex
+
+if $?lm && $?firebolt_10x4 "local ledcode '\
+ 02 18 28 32 07 67 1E 75 0A D7 87 32 01 D7 87 32 \
+ 00 D7 87 32 08 D7 87 80 D2 1C 74 02 3A 0C 12 80 \
+ F8 15 1A 00 57 '" # lm12pcx456501.hex
+
+if $?fbpoe && $?firebolt_any "local ledcode '\
+ E0 28 60 E3 67 85 67 49 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 AD 75 1A 67 C2 77 20 32 0E 87 32 08 87 \
+ 67 49 06 E3 80 D2 1A 74 0F 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 32 00 97 75 55 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 61 12 BA FE E3 02 0A \
+ 50 12 BA FE E3 95 75 73 85 12 A0 FE E3 95 75 C2 \
+ 85 77 B4 12 A0 FE E3 95 75 7D 85 77 BB 16 E0 DA \
+ 02 71 BB 77 C2 32 05 97 71 95 32 02 97 71 B4 06 \
+ E1 D2 01 71 B4 06 E3 67 AD 75 B4 32 03 97 71 C2 \
+ 32 04 97 75 BB 06 E2 D2 07 71 BB 77 C2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # poe48p56504.hex
+
+#Override Default Firebolt LED program for felix
+if $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0E 87 32 0F 87 57'" # sdk56102.hex
+
+#Override Default Felix LED program for felix48
+if $?felix48 && $?felix || $?felix15 "local ledcode '\
+ E0 28 60 E3 67 6B 67 A7 06 E3 80 D2 18 74 01 02 \
+ 18 28 60 E3 67 49 02 19 28 60 E3 67 49 32 0E 87 \
+ 32 0E 87 32 0E 87 32 0E 87 12 E2 85 05 D2 0F 71 \
+ 33 52 00 12 E1 85 05 D2 1F 71 3D 52 00 12 E0 85 \
+ 05 D2 05 71 47 52 00 3A 68 67 CF 75 52 32 0E 87 \
+ 77 55 32 0F 87 32 00 97 75 5E 32 0E 87 57 32 01 \
+ 97 75 67 32 0E 87 57 32 0F 87 57 32 00 97 75 77 \
+ 12 A0 FE E3 02 0A 50 32 01 97 75 83 12 BC FE E3 \
+ 02 0A 50 12 BC FE E3 95 75 95 85 12 A0 FE E3 95 \
+ 75 E4 85 77 D6 12 A0 FE E3 95 75 9F 85 77 DD 16 \
+ E0 DA 02 71 DD 77 E4 32 05 97 71 B7 32 02 97 71 \
+ D6 06 E1 D2 01 71 D6 06 E3 67 CF 75 D6 32 03 97 \
+ 71 E4 32 04 97 75 DD 06 E2 D2 07 71 DD 77 E4 12 \
+ 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 \
+ 32 0F 87 57 32 0F 87 32 0E 87 57'" # felix48.hex
+
+if $?easyrider_any "local ledcode '\
+ E0 28 60 E3 67 59 67 95 06 E3 80 28 60 E3 67 95 \
+ 67 59 06 E3 80 D2 0C 74 01 28 60 E3 67 BD 75 26 \
+ 67 D2 67 59 77 2E 32 0E 87 32 08 87 67 C4 06 E3 \
+ 80 D2 0D 74 19 12 E2 85 05 D2 0F 71 3F 52 00 12 \
+ E1 85 05 D2 1F 71 49 52 00 12 E0 85 05 D2 05 71 \
+ 53 52 00 67 C4 67 C4 3A 38 32 00 97 75 65 12 A0 \
+ FE E3 02 0A 50 32 01 97 75 71 12 AD FE E3 02 0A \
+ 50 12 AD FE E3 95 75 83 85 12 A0 FE E3 95 75 D2 \
+ 85 77 C4 12 A0 FE E3 95 75 8D 85 77 CB 16 E0 DA \
+ 02 71 CB 77 D2 32 05 97 71 A5 32 02 97 71 C4 06 \
+ E1 D2 01 71 C4 06 E3 67 BD 75 C4 32 03 97 71 D2 \
+ 32 04 97 75 CB 06 E2 D2 07 71 CB 77 D2 12 80 F8 \
+ 15 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F \
+ 87 57 32 0F 87 32 0E 87 57'" # sdk56601.hex
+
+#Override Default Easyrider LED program for 56602
+if $?easyrider_1x1 "local ledcode '\
+ E0 60 E1 67 7C 67 7C 06 E1 80 D2 0C 74 01 02 0C \
+ 28 60 E1 67 75 75 1D 67 8A 67 39 77 25 32 0E 87 \
+ 32 08 87 67 7C 06 E1 D2 00 02 00 74 10 12 E0 85 \
+ 05 D2 05 71 37 52 00 3A 38 32 00 97 75 45 12 A0 \
+ FE E1 02 0A 50 32 01 97 75 51 12 AD FE E1 02 0A \
+ 50 12 AD FE E1 95 75 63 85 12 A0 FE E1 95 75 8A \
+ 85 77 7C 12 A0 FE E1 95 75 6D 85 77 83 16 E0 DA \
+ 02 71 83 77 8A 12 80 F8 15 1A 00 57 32 0E 87 32 \
+ 0E 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 \
+ 57'" # sdk56602.hex
+
+#Override Default LED program for 53300
+if $?mirage24 "local ledcode '\
+ E0 28 60 E3 67 6B 67 2F 06 E3 80 D2 18 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 30 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 BC FE E3 02 0A 50 12 BC FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A2 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 9E 16 E0 DA 02 71 9E 77 A2 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A2 32 04 97 75 9E 06 E2 D2 07 71 \
+ 9E 77 A2 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E \
+ 87 57 32 0E 87 57'" # sdk53300.hex
+
+#Override Default LED program for 56314
+if $?bcm56314p24ref "local ledcode '\
+ E0 28 60 E3 67 79 67 3D 06 E3 80 D2 18 74 01 28 \
+ 60 E3 67 79 67 A8 06 E3 80 D2 1C 74 0F 12 E2 85 \
+ 05 D2 0F 71 27 52 00 12 E1 85 05 D2 1F 71 31 52 \
+ 00 12 E0 85 05 D2 05 71 3B 52 00 3A 38 32 00 97 \
+ 75 49 12 A0 FE E3 02 0A 50 32 01 97 75 55 12 BC \
+ FE E3 02 0A 50 12 BC FE E3 95 75 67 85 12 A0 FE \
+ E3 95 75 B0 85 77 A8 12 A0 FE E3 95 75 71 85 77 \
+ AC 16 E0 DA 02 71 AC 77 B0 32 05 97 71 89 32 02 \
+ 97 71 A8 06 E1 D2 01 71 A8 06 E3 67 A1 75 A8 32 \
+ 03 97 71 B0 32 04 97 75 AC 06 E2 D2 07 71 AC 77 \
+ B0 12 80 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ 32 0E 87 57'" # bcm956314p24ref.hex
+
+if $?bradley "local ledcode '\
+ E0 28 60 F2 67 1B 06 F2 80 D2 14 74 01 86 F3 12 \
+ F0 85 05 D2 05 71 19 52 00 3A 28 32 00 97 75 27 \
+ 12 A8 FE F2 02 0A 50 32 01 97 75 33 12 BC FE F2 \
+ 02 0A 50 12 BC FE F2 95 75 45 85 12 A8 FE F2 95 \
+ 75 91 85 77 57 12 A8 FE F2 95 75 4F 85 77 8A 16 \
+ F0 DA 02 71 8A 77 91 06 F2 12 94 F8 15 02 02 C1 \
+ 74 6E 02 04 C1 74 6E 02 08 C1 74 6E 77 74 C6 F3 \
+ 74 91 77 8A 06 F2 67 7C 75 83 77 91 12 80 F8 15 \
+ 1A 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 \
+ 57 32 0F 87 32 0E 87 57'" # sdk56800.hex
+
+if $?humv "local ledcode '\
+ E0 28 60 F2 67 21 06 F2 80 D2 08 74 0F F2 02 D2 \
+ 12 74 01 86 F3 12 F0 85 05 D2 05 71 1F 52 00 3A \
+ 20 32 00 97 75 2D 12 A8 FE F2 02 0A 50 32 01 97 \
+ 75 39 12 BA FE F2 02 0A 50 12 BA FE F2 95 75 4B \
+ 85 12 A8 FE F2 95 75 97 85 77 5D 12 A8 FE F2 95 \
+ 75 55 85 77 90 16 F0 DA 02 71 90 77 97 06 F2 12 \
+ 94 F8 15 02 02 C1 74 74 02 04 C1 74 74 02 08 C1 \
+ 74 74 77 7A C6 F3 74 97 77 90 06 F2 67 82 75 89 \
+ 77 97 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" # sdk56700.hex
+
+if $?bradley_1g "local ledcode '\
+ E0 28 60 E3 67 2F 67 6B 06 E3 80 D2 14 74 01 12 \
+ E2 85 05 D2 0F 71 19 52 00 12 E1 85 05 D2 1F 71 \
+ 23 52 00 12 E0 85 05 D2 05 71 2D 52 00 3A 50 32 \
+ 00 97 75 3B 12 A0 FE E3 02 0A 50 32 01 97 75 47 \
+ 12 B4 FE E3 02 0A 50 12 B4 FE E3 95 75 59 85 12 \
+ A0 FE E3 95 75 A8 85 77 9A 12 A0 FE E3 95 75 63 \
+ 85 77 A1 16 E0 DA 02 71 A1 77 A8 32 05 97 71 7B \
+ 32 02 97 71 9A 06 E1 D2 01 71 9A 06 E3 67 93 75 \
+ 9A 32 03 97 71 A8 32 04 97 75 A1 06 E2 D2 07 71 \
+ A1 77 A8 12 80 F8 15 1A 00 57 32 0E 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57 '" # sdk56800c.hex
+
+if $?goldwing "local ledcode '\
+ E0 28 60 F3 D2 10 75 0E 67 3B 67 94 77 12 67 94 \
+ 67 3B 06 F3 80 D2 14 74 01 86 F4 12 F2 85 05 D2 \
+ 0F 71 25 52 00 12 F1 85 05 D2 1F 71 2F 52 00 12 \
+ F0 85 05 D2 05 71 39 52 00 3A 50 32 00 97 75 47 \
+ 12 A8 FE F3 02 0A 50 32 01 97 75 53 12 BC FE F3 \
+ 02 0A 50 12 BC FE F3 95 75 65 85 12 A8 FE F3 95 \
+ 75 C0 85 77 77 12 A8 FE F3 95 75 6F 85 77 B9 16 \
+ F0 DA 02 71 B9 77 C0 06 F3 12 94 F8 15 02 02 C1 \
+ 74 8E 02 04 C1 74 8E 02 08 C1 74 8E 77 B2 C6 F4 \
+ 74 C0 77 B9 06 F3 67 AB 75 B2 32 04 75 B2 32 03 \
+ 97 71 C0 06 F2 D2 07 71 B9 77 C0 12 80 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 '" # sdk56580.hex
+
+if $?humv && $?lm "local ledcode '\
+ 02 04 28 D2 08 74 0A F2 02 28 32 07 67 29 75 11 \
+ D7 87 60 E4 67 30 06 E4 60 E4 67 4C 06 E4 32 08 \
+ D7 87 80 D2 12 74 02 3A 30 12 80 F8 15 1A 00 57 \
+ 06 E4 12 94 F8 15 02 10 C1 70 42 12 D2 FE E4 02 \
+ 0A 50 12 D2 FE E4 95 75 6D 85 77 68 06 E4 12 94 \
+ F8 15 02 20 C1 70 5E 12 C0 FE E4 02 0A 50 12 C0 \
+ FE E4 95 75 6D 85 77 68 32 0E D7 87 57 32 0F D7 \
+ 87 57 '" # lm12p56802.hex
+
+
+if $?raptor "local ledcode '\
+ 02 06 28 60 FF 67 64 67 93 06 FF 80 D2 36 74 02 \
+ 02 04 28 60 FF 67 BB 75 1E 32 0E 87 77 21 32 0F \
+ 87 67 7D 06 FF 80 D2 06 74 12 02 01 28 60 FF 67 \
+ BB 75 38 32 0E 87 77 3B 32 0F 87 67 7D 06 FF 80 \
+ D2 03 74 2C 12 FE 85 05 D2 0F 71 4E 52 00 12 FD \
+ 85 05 D2 1F 71 58 52 00 12 FC 85 05 D2 05 71 62 \
+ 52 00 3A C8 32 01 97 75 76 32 00 97 75 C9 16 FC \
+ DA 02 71 C9 77 D0 32 00 97 75 C2 77 D0 32 00 97 \
+ 75 86 32 0E 87 57 32 01 97 75 8F 32 0E 87 57 32 \
+ 0F 87 57 32 05 97 71 A3 32 02 97 71 C2 06 FD D2 \
+ 01 71 C2 06 FF 67 BB 75 C2 32 03 97 71 D0 32 04 \
+ 97 75 C9 06 FE D2 07 71 C9 77 D0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" # sdk56018.hex
+
+if $?raptor && $?rap24_ref "local ledcode '\
+ 02 06 60 E1 67 48 67 31 06 E1 80 D2 1E 71 02 02 \
+ 05 60 E1 67 48 67 31 06 E1 90 D2 03 74 11 02 02 \
+ 60 E1 67 48 67 31 06 E1 90 D2 00 74 20 86 E0 3A \
+ 38 06 E1 67 50 75 57 28 32 00 32 01 B7 97 75 57 \
+ 16 E0 CA 05 74 5B 77 57 06 E1 67 50 75 57 77 5B \
+ 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00'" # sdk56214.hex
+
+if $?raven_eb_48p "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 71 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024p48ref.hex
+
+if $?BCM956024R50T "local ledcode '\
+ 02 06 28 60 C3 67 30 67 6C 06 C3 80 D2 1E 74 02 \
+ 12 C2 85 05 D2 0F 71 1A 52 00 12 C1 85 05 D2 1F \
+ 71 24 52 00 12 C0 85 05 D2 05 71 2E 52 00 3A 60 \
+ 32 00 97 75 3C 12 C0 FE C3 02 0A 50 32 01 97 75 \
+ 48 12 E0 FE C3 02 0A 50 12 E0 FE C3 95 75 5A 85 \
+ 12 C0 FE C3 95 75 A9 85 77 9B 12 C0 FE C3 95 75 \
+ 64 85 77 A2 16 C0 DA 02 71 A2 77 A9 32 05 97 75 \
+ 7C 32 02 97 71 9B 06 C1 D2 01 71 9B 06 C3 67 94 \
+ 75 9B 32 03 97 71 A9 32 04 97 75 A2 06 C2 D2 07 \
+ 71 A2 77 A9 12 A0 F8 15 1A 00 57 32 0E 87 32 0E \
+ 87 57 32 0E 87 32 0F 87 57 32 0F 87 32 0E 87 57'" #bcm956024r50t.hex
+
+if $?scorpion || $?conqueror "local ledcode '\
+ 02 18 28 60 E1 67 12 06 E1 90 D2 00 74 02 86 E0 \
+ 3A 18 67 2D 75 34 28 32 00 32 01 B7 97 75 38 16 \
+ E0 CA 05 74 38 77 34 67 2D 75 34 77 38 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 \
+ 00 00 00'" #sdk56820.hex
+
+if $?scorpion && $?BCM956820R24XG "local ledcode '\
+ 02 01 28 67 D0 02 02 28 67 D6 67 D0 02 01 28 67 \
+ D6 02 04 28 67 D0 02 03 28 67 D6 67 D0 02 04 28 \
+ 67 D6 02 05 28 67 D0 02 06 28 67 D6 67 D0 02 05 \
+ 28 67 D6 02 07 28 67 D0 02 08 28 67 D6 67 D0 02 \
+ 07 28 67 D6 02 09 28 67 D0 02 0A 28 67 D6 67 D0 \
+ 02 09 28 67 D6 02 0C 28 67 D0 02 0B 28 67 D6 67 \
+ D0 02 0C 28 67 D6 02 0D 28 67 D0 02 0E 28 67 D6 \
+ 67 D0 02 0D 28 67 D6 02 0F 28 67 D0 02 10 28 67 \
+ D6 67 D0 02 0F 28 67 D6 02 11 28 67 D0 02 12 28 \
+ 67 D6 67 D0 02 11 28 67 D6 02 14 28 67 D0 02 13 \
+ 28 67 D6 67 D0 02 14 28 67 D6 02 15 28 67 D0 02 \
+ 16 28 67 D6 67 D0 02 15 28 67 D6 02 17 28 67 D0 \
+ 02 18 28 67 D6 67 D0 02 17 28 67 D6 86 E0 3A 30 \
+ 67 F1 75 F8 77 FC 67 F1 75 F8 28 32 00 32 01 B7 \
+ 97 75 F8 16 E0 CA 05 74 FC 77 F8 67 F1 75 F8 77 \
+ FC 12 A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 \
+ '" #bcm956820r24xg.hex
+
+if $?valkyrie "local ledcode '\
+ 02 02 67 A9 67 94 02 03 67 A9 67 94 02 05 67 A9 \
+ 67 94 02 04 67 A9 67 94 02 06 67 A9 67 94 02 07 \
+ 67 A9 67 94 02 12 67 A9 67 94 02 13 67 A9 67 94 \
+ 02 0E 67 A9 67 94 02 0F 67 A9 67 94 02 11 67 A9 \
+ 67 94 02 10 67 A9 67 94 02 1A 67 A9 67 94 02 20 \
+ 67 A9 67 94 02 21 67 A9 67 94 02 22 67 A9 67 94 \
+ 02 23 67 A9 67 94 02 24 67 A9 67 94 02 2F 67 A9 \
+ 67 94 02 2E 67 A9 67 94 02 1B 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56680.hex
+
+if $?valkyrie2 "local ledcode '\
+ 02 1E 67 A9 67 94 02 1F 67 A9 67 94 02 21 67 A9 \
+ 67 94 02 20 67 A9 67 94 02 22 67 A9 67 94 02 23 \
+ 67 A9 67 94 02 24 67 A9 67 94 02 25 67 A9 67 94 \
+ 02 26 67 A9 67 94 02 27 67 A9 67 94 02 29 67 A9 \
+ 67 94 02 28 67 A9 67 94 02 2A 67 A9 67 94 02 2B \
+ 67 A9 67 94 02 2C 67 A9 67 94 02 2D 67 A9 67 94 \
+ 02 2E 67 A9 67 94 02 2F 67 A9 67 94 02 31 67 A9 \
+ 67 94 02 30 67 A9 67 94 02 32 67 A9 67 94 02 33 \
+ 67 A9 67 94 02 34 67 A9 67 94 02 35 67 A9 67 94 \
+ 86 E0 3A 30 67 AF 75 B6 28 32 00 32 01 B7 97 75 \
+ B6 16 E0 CA 05 74 BA 77 B6 67 AF 75 B6 77 BA 12 \
+ A0 F8 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 \
+ 00'" #sdk56685.hex
+
+if $?hawkeye_p24 "local ledcode '\
+ 02 01 28 60 E3 67 43 67 1C 06 E3 80 D2 19 74 02 \
+ 12 E0 85 05 D2 03 71 1A 52 00 3A 60 32 00 32 01 \
+ B7 97 75 2B 12 E4 FE E3 02 01 50 12 E4 FE E3 95 \
+ 75 3B 85 06 E3 67 55 75 6A 77 5C 16 E0 DA 01 71 \
+ 6A 77 5C 06 E3 67 55 75 6A 32 03 97 71 5C 32 04 \
+ 97 75 6A 77 63 12 A0 F8 15 1A 00 57 32 0E 87 32 \
+ 0F 87 57 32 0F 87 32 0E 87 57 32 0F 87 32 0F 87 \
+ 57'" #bcm953314p24ref.hex
+
+if $?hawkeye_k24 "local ledcode '\
+ 02 01 28 60 E1 67 3D 67 1C 06 E1 80 D2 19 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 30 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 50 16 E0 DA 02 71 4C 77 50 06 E1 67 \
+ 45 75 50 77 4C 12 A0 F8 15 1A 00 57 32 0E 87 57 \
+ 32 0F 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #bcm953314k24.hex
+
+if !"expr $pcidev + 0 == 0xb624" "local ledcode '\
+ 02 1C 28 67 18 02 1D 28 67 18 02 1E 28 67 18 02 \
+ 1F 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56624.hex
+
+if !"expr $pcidev + 0 == 0xb626" "local ledcode '\
+ 02 1A 28 67 22 02 1B 28 67 22 02 1C 28 67 22 02 \
+ 1D 28 67 22 02 1E 28 67 22 02 1F 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56626.hex
+
+if !"expr $pcidev + 0 == 0xb628" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56628.hex
+
+if !"expr $pcidev + 0 == 0xb629" "local ledcode '\
+ 02 02 28 67 2C 02 0E 28 67 2C 02 1A 28 67 2C 02 \
+ 1B 28 67 2C 02 1C 28 67 2C 02 1D 28 67 2C 02 1E \
+ 28 67 2C 02 1F 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56629.hex
+
+if !"expr $pcidev + 0 == 0xb634" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb630" "local ledcode '\
+ 02 1A 28 67 18 02 1B 28 67 18 02 1C 28 67 18 02 \
+ 1D 28 67 18 86 E0 3A 08 67 3B 75 20 67 46 77 24 \
+ 67 42 77 42 28 32 00 32 01 B7 97 75 42 16 E0 CA \
+ 05 74 46 77 42 67 3B 75 42 77 46 12 A0 F8 15 1A \
+ 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00 00 00'" #sdk56634.hex
+
+if !"expr $pcidev + 0 == 0xb636" "local ledcode '\
+ 02 2A 28 67 22 02 32 28 67 22 02 1A 28 67 22 02 \
+ 1B 28 67 22 02 1C 28 67 22 02 1D 28 67 22 86 E0 \
+ 3A 08 67 3D 75 44 28 32 00 32 01 B7 97 75 48 16 \
+ E0 CA 05 74 48 77 44 67 3D 75 44 77 48 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 00 00 00 00'" #sdk56636.hex
+
+if !"expr $pcidev + 0 == 0xb638" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56638.hex
+
+if !"expr $pcidev + 0 == 0xb639" "local ledcode '\
+ 02 1E 28 67 2C 02 26 28 67 2C 02 2A 28 67 2C 02 \
+ 32 28 67 2C 02 1A 28 67 2C 02 1B 28 67 2C 02 1C \
+ 28 67 2C 02 1D 28 67 2C 86 E0 3A 08 67 47 75 4E \
+ 28 32 00 32 01 B7 97 75 52 16 E0 CA 05 74 52 77 \
+ 4E 67 47 75 4E 77 52 12 A0 F8 15 1A 00 57 32 0F \
+ 87 57 32 0E 87 57 00 00 00 00 00 00 00 00 00 00'" #sdk56639.hex
+
+if !"expr $pcidev + 0 == 0xb334" "local ledcode '\
+ 02 02 28 60 E1 67 3D 67 1C 06 E1 80 D2 1E 74 02 \
+ 12 E0 85 05 D2 05 71 1A 52 00 3A 38 32 00 32 01 \
+ B7 97 75 2B 12 E2 FE E1 02 0A 50 12 E2 FE E1 95 \
+ 75 35 85 77 4C 16 E0 DA 02 71 50 77 4C 06 E1 67 \
+ 45 75 4C 77 50 12 A0 F8 15 1A 00 57 32 0F 87 57 \
+ 32 0E 87 57 00 00 00 00 00 00 00 00 00 00 00 00'" #sdk56334.hex
+
+if $?apollo "local ledcode '\
+ 02 1E 28 60 E0 67 58 67 73 06 E0 80 28 60 E0 67 \
+ 73 67 58 06 E0 80 D2 36 74 02 02 1A 28 60 E0 67 \
+ 9B 75 29 67 B0 67 58 77 31 32 0E 87 32 08 87 67 \
+ A2 06 E0 80 D2 1E 74 1C 12 E2 85 05 D2 0F 71 42 \
+ 52 00 12 E1 85 05 D2 1F 71 4C 52 00 12 E3 85 05 \
+ D2 05 71 56 52 00 3A 70 32 00 97 75 64 32 01 97 \
+ 71 6B 77 B0 32 01 97 71 A9 77 A2 16 E3 DA 02 71 \
+ A9 77 B0 32 05 97 75 83 32 02 97 71 A2 06 E1 D2 \
+ 01 71 A2 06 E0 67 9B 75 A2 32 03 97 71 B0 32 04 \
+ 97 75 A9 06 E2 D2 07 71 A9 77 B0 12 A0 F8 15 1A \
+ 00 57 32 0E 87 32 0E 87 57 32 0E 87 32 0F 87 57 \
+ 32 0F 87 32 0E 87 57 00 00 00 00 00 00 00 00 00'" #sdk56524.hex
+
+if $?tomahawk || $?tomahawk_plus "local ledcode '\
+ 02 00 28 60 E1 67 25 67 14 06 E1 80 D2 40 74 02 \
+ 86 E0 3A FC 28 32 00 32 01 B7 97 75 37 16 E0 CA \
+ 05 74 3E 77 37 67 2B 75 37 77 45 12 A0 F8 15 1A \
+ 00 57 28 32 07 97 57 32 0E 87 32 0E 87 57 32 0F \
+ 87 32 0E 87 57 32 0E 87 32 0F 87 57 00 00 00 00'" #sdk56960.hex
+
+if $?trident2plus "local ledcode '\
+ 02 01 28 60 E1 67 31 67 20 06 E1 80 D2 31 74 02 \
+ 86 E0 3A C0 67 37 75 1C 67 51 77 20 67 43 77 43 \
+ 28 32 00 32 01 B7 97 75 43 16 E0 CA 05 74 4A 77 \
+ 43 67 37 75 43 77 51 12 A0 F8 15 1A 00 57 28 32 \
+ 07 97 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 \
+ 57 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00'" #sdk56860.hex
+
+if $?apache "local ledcode '\
+ 02 00 67 24 67 0F 80 D2 24 74 02 86 E0 3A F8 67 \
+ 34 75 16 77 1D 57 67 3C 75 62 77 44 57 67 3C 75 \
+ 4E 77 58 57 67 2C 75 62 77 70 07 57 07 12 A0 F8 \
+ 15 1A 00 57 07 12 A0 F8 15 1A 04 57 07 12 A0 F8 \
+ 15 1A 05 57 16 E0 CA 1E 74 69 77 62 07 57 16 E0 \
+ CA 1E 74 70 77 62 07 57 16 E0 CA 1E 74 69 77 70 \
+ 07 57 32 0E 87 32 0E 87 57 32 0F 87 32 0E 87 57 \
+ 32 0E 87 32 0F 87 57 00 00 00 00 00 00 00 00 00'" #sdk56560.hex
+
+if $?generic8led "local ledcode '\
+ 06 E1 D2 40 71 11 E0 60 E1 16 E3 DA 01 71 15 60 \
+ E3 67 5D 75 2B 12 01 61 E3 67 71 28 67 32 86 E0 \
+ 16 E2 81 61 E2 DA 1E 75 2B 3A 08 E9 61 E2 86 E1 \
+ 77 00 67 5D 75 38 77 3C 67 64 77 64 67 41 67 4F \
+ 57 28 32 01 97 75 64 16 E0 CA 05 74 68 77 64 28 \
+ 32 00 97 75 64 16 E0 CA 05 74 68 77 64 12 A0 F8 \
+ 15 1A 00 57 32 0F 87 57 32 0E 87 57 09 75 64 77 \
+ 68 12 05 67 6C 12 04 67 6C 12 03 67 6C 12 02 67 \
+ 6C 12 01 67 6C 12 00 67 6C 57 00 00 00 00 00 00'" #generic8led.hex
+
+# Download LED code into LED processor and enable (if applicable).
+
+if $?feature_led_proc && $?ledcode && !$?simulator \
+ "led prog $ledcode; \
+ led auto on; led start"
+
+# Setup Greyhound LED processor
+if $?greyhound \
+ "rcload gh_ledup.soc"
+
+# Setup Hurricane3 LED processor
+if $?hurricane3 \
+ "rcload hr3_led.soc"
+
+# Setup Tomahawk LED processor
+if $?tomahawk && !$?simulator \
+ "led 1 prog $ledcode; \
+ led 1 auto on; led 1 start; \
+ led 2 prog $ledcode; \
+ led 2 auto on; led 2 start"
+
+# Setup Tomahawk+ LED processor
+if $?tomahawk_plus && !$?simulator \
+ "led 1 prog $ledcode; \
+ led 1 auto on; led 1 start; \
+ led 2 prog $ledcode; \
+ led 2 auto on; led 2 start"
+
+# If loading multiple rc.soc, upon loading the last unit, restart
+# all LED processors so any common blinking is in sync.
+
+if !"expr $?feature_led_proc && !$?simulator && $unit == $units - 1" \
+ "*:led stop; *:led start"
+
+# Run counter DMA task 4 times per second to achieve better
+# ctr_xaui_activity.
+if $?bradley_any \
+ "ctr interval=250000"
+
+# Initialize Hercules UC modid 0 entry to point to the CPU
+if $?herc_any \
+ "w uc 0 1 1"
+
+# Additional configuration for 48-port in Stacking mode.
+# On the 48-port platform, rc.soc is run twice; once on unit 0 and
+# then once on unit 1. The turbo port on unit N is geN.
+# All turbo port traffic must be tagged; see vlan add below.
+# See $SDK/doc/48-port.txt for more information including how
+# to configure IPG values for line rate operation.
+
+if $?p48 && $?unit0 \
+ "local turbo_port 0; local my_modid 1;"
+
+if $?p48 && $?unit1 \
+ "local turbo_port 1; local my_modid 2;"
+
+if $?p48 \
+ "m config st_is_mirr=0 st_module=1 st_mcnt=1 st_simplex=0 st_link=0; \
+ m config.g$turbo_port st_link=1; \
+ m gmacc2.ge$turbo_port ipgt=8 mclkfq=1; \
+ m fe_maxf maxfr=1560; \
+ m maxfr maxfr=1568; \
+ m config2 my_modid=$my_modid; \
+ port ge$turbo_port speed=2500; \
+ vlan add 1 pbm=ge$turbo_port ubm=none"
+
+if !$?no_bcm && $?drac_any \
+ "m modport_7_0 port_for_mod1=0xc"
+if !$?no_bcm && $?lynx_any \
+ "m modport_7_0 port_for_mod1=0x1"
+if !$?no_bcm && $?tucana \
+ "stkmode modid=0;"
+if !$?no_bcm && $?tucana && !$?magnum && !$?tucana_nohg \
+ "m modport_7_0 port_for_mod2=0x38; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=0 port_for_mod2=0x38; \
+ stkmode modid=0"
+if !$?no_bcm && $?xgs_switch && !$?rcpu_only\
+ "stkmode modid=0; \
+ s CMIC_COS_CTRL_RX CH0_COS_BMP=0,CH1_COS_BMP=0xff, \
+ CH2_COS_BMP=0,CH3_COS_BMP=0"
+
+# Back-to-back Draco setup.
+
+# Draco chips must run at 127MHz. Some older versions
+# are not set to this frequency.
+
+if $?draco_stk && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+# Applies to SDK Baseboard with either internal or external Higigs,
+# as well as the Galahad reference design.
+
+if $?draco_b2b && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if !$?simulator && $?draco_b2b && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_b2b && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Merlin, White Knight, Black Knight setup.
+# Draco unit 1 is on Herc port 8
+# Draco unit 2 is on Herc port 1
+
+if $?draco_herc4 && $?unit0 \
+ "w uc.hpic7 0 1 0x0; \
+ w uc.hpic7 1 1 0x2; \
+ w uc.hpic0 0 1 0x100; \
+ w uc.hpic0 1 1 0x0"
+
+if !$?simulator && $?draco_herc4 && $?unit0 \
+ "i2c probe quiet; bb clock Ref125 127"
+
+if $?draco_herc4 && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12"
+
+if $?draco_herc4 && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0"
+
+# Lancelot setup
+# (enabled by adding the property "lancelot=1")
+# Notes:
+# Draco unit 1 is on Herc port 7
+# Draco unit 2 is on Herc port 8
+# Draco unit 3 is on Herc port 1
+# Draco unit 4 is on Herc port 2
+
+if $?lancelot && $?unit0 \
+ "w uc.hpic6 0 1 0x0; \
+ w uc.hpic6 1 1 0x100; \
+ w uc.hpic6 2 1 0x2; \
+ w uc.hpic6 3 1 0x4; \
+ w uc.hpic7 0 1 0x80; \
+ w uc.hpic7 1 1 0x0; \
+ w uc.hpic7 2 1 0x2; \
+ w uc.hpic7 3 1 0x4; \
+ w uc.hpic0 0 1 0x80; \
+ w uc.hpic0 1 1 0x100; \
+ w uc.hpic0 2 1 0x0; \
+ w uc.hpic0 3 1 0x4; \
+ w uc.hpic1 0 1 0x80; \
+ w uc.hpic1 1 1 0x100; \
+ w uc.hpic1 2 1 0x2; \
+ w uc.hpic1 3 1 0x0"
+
+if !$?simulator && $?lancelot && $?unit0 \
+ "i2c probe quiet; bb clock Draco_Core 127"
+
+if $?lancelot && $?unit1 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit2 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=0 \
+ port_for_mod2=12 port_for_mod3=12"
+
+if $?lancelot && $?unit3 \
+ "stkmode modid=2; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=0 port_for_mod3=12"
+
+if $?lancelot && $?unit4 \
+ "stkmode modid=3; \
+ m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=0"
+
+# Lynx SDK (TwoLynx) setup
+# (enabled by adding the property "twolynx=1")
+
+if $?twolynx && $?unit0 \
+ "stkmode modid=0; \
+ m modport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ m imodport_7_0 port_for_mod0=0 port_for_mod1=1; \
+ "
+
+if $?twolynx && $?unit1 \
+ "stkmode modid=1; \
+ m modport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ m imodport_7_0 port_for_mod0=1 port_for_mod1=0; \
+ "
+# HercuLynx setup
+# (enabled by adding the property "herculynx=1")
+# Notes:
+# Lynx unit 1 is on Herc port 1
+# Lynx unit 2 is on Herc port 2
+# Lynx unit 3 is on Herc port 3
+# Lynx unit 4 is on Herc port 4
+# Lynx unit 5 is on Herc port 5
+# Lynx unit 6 is on Herc port 6
+# Lynx unit 7 is on Herc port 7
+# Lynx unit 8 is on Herc port 8
+
+if $?herculynx && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x008; \
+ w uc.hpic0 3 1 0x010; \
+ w uc.hpic0 4 1 0x020; \
+ w uc.hpic0 5 1 0x040; \
+ w uc.hpic0 6 1 0x080; \
+ w uc.hpic0 7 1 0x100; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x008; \
+ w uc.hpic1 3 1 0x010; \
+ w uc.hpic1 4 1 0x020; \
+ w uc.hpic1 5 1 0x040; \
+ w uc.hpic1 6 1 0x080; \
+ w uc.hpic1 7 1 0x100; \
+ ; \
+ w uc.hpic2 0 1 0x002; \
+ w uc.hpic2 1 1 0x004; \
+ w uc.hpic2 2 1 0x008; \
+ w uc.hpic2 3 1 0x010; \
+ w uc.hpic2 4 1 0x020; \
+ w uc.hpic2 5 1 0x040; \
+ w uc.hpic2 6 1 0x080; \
+ w uc.hpic2 7 1 0x100; \
+ ; \
+ w uc.hpic3 0 1 0x002; \
+ w uc.hpic3 1 1 0x004; \
+ w uc.hpic3 2 1 0x008; \
+ w uc.hpic3 3 1 0x010; \
+ w uc.hpic3 4 1 0x020; \
+ w uc.hpic3 5 1 0x040; \
+ w uc.hpic3 6 1 0x080; \
+ w uc.hpic3 7 1 0x100; \
+ ; \
+ w uc.hpic4 0 1 0x002; \
+ w uc.hpic4 1 1 0x004; \
+ w uc.hpic4 2 1 0x008; \
+ w uc.hpic4 3 1 0x010; \
+ w uc.hpic4 4 1 0x020; \
+ w uc.hpic4 5 1 0x040; \
+ w uc.hpic4 6 1 0x080; \
+ w uc.hpic4 7 1 0x100; \
+ ; \
+ w uc.hpic5 0 1 0x002; \
+ w uc.hpic5 1 1 0x004; \
+ w uc.hpic5 2 1 0x008; \
+ w uc.hpic5 3 1 0x010; \
+ w uc.hpic5 4 1 0x020; \
+ w uc.hpic5 5 1 0x040; \
+ w uc.hpic5 6 1 0x080; \
+ w uc.hpic5 7 1 0x100; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x008; \
+ w uc.hpic6 3 1 0x010; \
+ w uc.hpic6 4 1 0x020; \
+ w uc.hpic6 5 1 0x040; \
+ w uc.hpic6 6 1 0x080; \
+ w uc.hpic6 7 1 0x100; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x008; \
+ w uc.hpic7 3 1 0x010; \
+ w uc.hpic7 4 1 0x020; \
+ w uc.hpic7 5 1 0x040; \
+ w uc.hpic7 6 1 0x080; \
+ w uc.hpic7 7 1 0x100; \
+ ; \
+ "
+
+if $?herculynx && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?herculynx && $?unit1 \
+ "stkmode modid=0"
+
+if $?herculynx && $?unit2 \
+ "stkmode modid=1"
+
+if $?herculynx && $?unit3 \
+ "stkmode modid=2"
+
+if $?herculynx && $?unit4 \
+ "stkmode modid=3"
+
+if $?herculynx && $?unit5 \
+ "stkmode modid=4"
+
+if $?herculynx && $?unit6 \
+ "stkmode modid=5"
+
+if $?herculynx && $?unit7 \
+ "stkmode modid=6"
+
+if $?herculynx && $?unit8 \
+ "stkmode modid=7"
+
+# LynxaLot setup
+# (enabled by adding the property "lynxalot=1")
+# Notes:
+# Lynx unit 0 is on Herc port 3 (hg2/hpic2) (mod 0)
+# Lynx unit 1 is on Herc port 4 (hg3/hpic3) (mod 1)
+# Higig conn 0 is on Herc port 5 (hg4/hpic4)
+# Higig conn 1 is on Herc port 6 (hg5/hpic5)
+# Draco unit 3 is on Herc port 7 (hg6/hpic6) (mod 2)
+# Draco unit 4 is on Herc port 8 (hg7/hpic7) (mod 3)
+# Draco unit 5 is on Herc port 1 (hg0/hpic0) (mod 4)
+# Draco unit 6 is on Herc port 2 (hg1/hpic1) (mod 5)
+
+if $?lynxalot && $?unit2 \
+ " \
+ w uc.hpic0 0 1 0x008; \
+ w uc.hpic0 1 1 0x010; \
+ w uc.hpic0 2 1 0x080; \
+ w uc.hpic0 3 1 0x100; \
+ w uc.hpic0 4 1 0x002; \
+ w uc.hpic0 5 1 0x004; \
+ ; \
+ w uc.hpic1 0 1 0x008; \
+ w uc.hpic1 1 1 0x010; \
+ w uc.hpic1 2 1 0x080; \
+ w uc.hpic1 3 1 0x100; \
+ w uc.hpic1 4 1 0x002; \
+ w uc.hpic1 5 1 0x004; \
+ ; \
+ w uc.hpic2 0 1 0x008; \
+ w uc.hpic2 1 1 0x010; \
+ w uc.hpic2 2 1 0x080; \
+ w uc.hpic2 3 1 0x100; \
+ w uc.hpic2 4 1 0x002; \
+ w uc.hpic2 5 1 0x004; \
+ ; \
+ w uc.hpic3 0 1 0x008; \
+ w uc.hpic3 1 1 0x010; \
+ w uc.hpic3 2 1 0x080; \
+ w uc.hpic3 3 1 0x100; \
+ w uc.hpic3 4 1 0x002; \
+ w uc.hpic3 5 1 0x004; \
+ ; \
+ w uc.hpic6 0 1 0x008; \
+ w uc.hpic6 1 1 0x010; \
+ w uc.hpic6 2 1 0x080; \
+ w uc.hpic6 3 1 0x100; \
+ w uc.hpic6 4 1 0x002; \
+ w uc.hpic6 5 1 0x004; \
+ ; \
+ w uc.hpic7 0 1 0x008; \
+ w uc.hpic7 1 1 0x010; \
+ w uc.hpic7 2 1 0x080; \
+ w uc.hpic7 3 1 0x100; \
+ w uc.hpic7 4 1 0x002; \
+ w uc.hpic7 5 1 0x004; \
+ ; \
+ "
+
+if $?lynxalot && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?lynxalot && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?lynxalot && $?unit0 \
+ "stkmode modid=0"
+
+if $?lynxalot && $?unit1 \
+ "stkmode modid=1"
+
+if $?lynxalot && $?unit3 \
+ "stkmode modid=2"
+
+if $?lynxalot && $?unit4 \
+ "stkmode modid=3"
+
+if $?lynxalot && $?unit5 \
+ "stkmode modid=4"
+
+if $?lynxalot && $?unit6 \
+ "stkmode modid=5"
+
+# guenevere setup
+# (enabled by adding the property "guenevere=1")
+# Notes:
+# hgX mapping based on pbmp_valid.0=0x1b7
+# Draco unit 1 is on Herc port 1 (hg0/hpic0) (mod 0)
+# Draco unit 2 is on Herc port 2 (hg1/hpic1) (mod 1)
+# Lynx unit 3 is on Herc port 8 (hg5/hpic7) (mod 2)
+# Lynx unit 4 is on Herc port 7 (hg4/hpic6) (mod 3)
+# Higig conn 0 is on Herc port 4 (hg2/hpic3)
+# Higig conn 1 is on Herc port 5 (hg3/hpic4)
+# Herc port 3 - Unused (hpic2)
+# Herc port 6 - Unused (hpic5)
+if $?guenevere && $?unit0 \
+ " \
+ w uc.hpic0 0 1 0x002; \
+ w uc.hpic0 1 1 0x004; \
+ w uc.hpic0 2 1 0x100; \
+ w uc.hpic0 3 1 0x080; \
+ ; \
+ w uc.hpic1 0 1 0x002; \
+ w uc.hpic1 1 1 0x004; \
+ w uc.hpic1 2 1 0x100; \
+ w uc.hpic1 3 1 0x080; \
+ ; \
+ w uc.hpic7 0 1 0x002; \
+ w uc.hpic7 1 1 0x004; \
+ w uc.hpic7 2 1 0x100; \
+ w uc.hpic7 3 1 0x080; \
+ ; \
+ w uc.hpic6 0 1 0x002; \
+ w uc.hpic6 1 1 0x004; \
+ w uc.hpic6 2 1 0x100; \
+ w uc.hpic6 3 1 0x080; \
+ ; \
+ "
+
+if $?guenevere && $?lynx_any \
+ "m modport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ m imodport_7_0 \
+ port_for_mod0=1 port_for_mod1=1 \
+ port_for_mod2=1 port_for_mod3=1 \
+ port_for_mod4=1 port_for_mod5=1 \
+ port_for_mod6=1 port_for_mod7=1; \
+ "
+
+if $?guenevere && $?drac_any \
+ "m modport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ m imodport_7_0 port_for_mod0=12 port_for_mod1=12 \
+ port_for_mod2=12 port_for_mod3=12 \
+ port_for_mod4=12 port_for_mod5=12 \
+ port_for_mod6=12 port_for_mod7=12; \
+ "
+
+if $?guenevere && $?unit1 \
+ "stkmode modid=0"
+
+if $?guenevere && $?unit2 \
+ "stkmode modid=1"
+
+if $?guenevere && $?unit3 \
+ "stkmode modid=2"
+
+if $?guenevere && $?unit4 \
+ "stkmode modid=3"
+
+# felix48 setup
+# (enabled by adding the property "felix48=1")
+# Notes:
+# BCM56102 unit-0 higig port (port 26) is connected
+# to BCM56102 Unit-1 higig port (port 26)
+#
+
+if $?felix48 && $?unit0 \
+ "stkmode modid=0 ; \
+ m IEGR_PORT MY_MODID=0; \
+ m XPORT_CONFIG MY_MODID=0; \
+ w MODPORT_MAP 1 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+
+if $?felix48 && $?unit1 \
+ "stkmode modid=1 ; \
+ m IEGR_PORT MY_MODID=1; \
+ m XPORT_CONFIG MY_MODID=1; \
+ w MODPORT_MAP 0 1 HIGIG_PORT_BITMAP=0x4 ; \
+ "
+# fbpoe setup
+# (enabled by adding the property "fbpoe=1")
+# Notes:
+# BCM56504 unit-0 higig port (port 27,28) is connected
+# to BCM56504 Unit-1 higig port (port 27,28)
+#
+
+if $?unit0 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+if $?unit1 && $?firebolt_any && $?fbpoe \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0x4; \
+ m HIGIG_TRUNK_GROUP HIGIG_TRUNK_RTAG1=3 \
+ HIGIG_TRUNK_ID1_PORT0=2 \
+ HIGIG_TRUNK_ID1_PORT1=3 \
+ HIGIG_TRUNK_ID1_PORT2=2 \
+ HIGIG_TRUNK_ID1_PORT3=3; \
+ m HIGIG_TRUNK_CONTROL HIGIG_TRUNK_ID2=1 \
+ HIGIG_TRUNK2=1 \
+ HIGIG_TRUNK_ID3=1 \
+ HIGIG_TRUNK3=1 \
+ HIGIG_TRUNK_BITMAP1=0xc \
+ ACTIVE_PORT_BITMAP=0xf"
+
+# Dual Raptor/Raven boards
+if $?raven_eb_48p || $?rap24_ref \
+ "local rcpu_system 1"
+if $?unit0 && $?rcpu_system \
+ "stkmode modid=0"
+if $?unit1 && $?rcpu_system \
+ "stkmode modid=1"
+
+# LM fb48 platform setup
+# (enabled by adding the property "lm48p=1")
+#
+if $?unit0 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=0"
+
+if $?unit1 && $?firebolt_any && $?lm48p || $?lm48p_D \
+ "stkmode modid=1"
+
+# Set Firebolt POE power level 170(total) - 110(switch) = 60
+if $?fbpoe \
+ "local poepower 60"
+
+# Set Draco15 POE power level 170(total) - 80(switch) = 90
+if $?drac15\
+ "local poepower 90"
+
+# Hurricane3 BCM956160R setup
+# Notes:
+# BCM56160 unit-0 higig port (port 29,30) is connected
+# to BCM56160 Unit-1 higig port (port 26,27)
+#
+
+if $?bcm956160r && $?unit0 \
+ "stkmode modid=0; \
+ w modport_map 1 1 HIGIG_PORT_BITMAP=0x60000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+if $?bcm956160r && $?unit1 \
+ "stkmode modid=1; \
+ w modport_map 0 1 HIGIG_PORT_BITMAP=0xc000000; \
+ trunk add id=128 r=3 pbm=hg0-hg1"
+
+# if enable_poe is set, then enable the POE processor for
+# either Firebolt or Draco15 platform
+if $?unit0 && $?enable_poe && $?fbpoe || $?drac15 \
+ "$echo rc: Enabling POE ...; \
+ poesel reset; \
+ i2c probe quiet; \
+ xpoe verbose off; \
+ xpoe power $poepower; \
+ xpoe verbose on; \
+ poesel enable"
+
+# mark this unit so that subsequent rc runs are quiet
+setenv rc$unit 1
+
+if $?macsec '\
+ macsec sync; \
+ $echo "rc: MACSEC CLI Enabled"'
+
+# cache a copy of rc.soc in memory
+rccache addq rc.soc
+
+# setup chassis if requested
+if !"expr $?autochassis2 && $unit == $units - 1" \
+ "setenv chassis2_no_rc 1; \
+ rcload c2switch.soc; \
+ setenv chassis2_no_rc; \
+ "
+
+# start stacking if requested
+if !"expr $?autostack && $unit == $units - 1" \
+ "rcload stk.soc"
+
+if !"expr $?aedev + 0" && !"expr $unit == $units - 1" \
+ "aedev init"
+
+# hurricane 48p FE platform LED setup for 56146_A0 and 56147_A0 board
+# (enabled by adding the property "fe_hu_48p=1")
+#
+if $?fe_hu_48p && $?BCM56146 || $?BCM56147 \
+ "phy fe0 0x1f 0x008b; \
+ phy fe0 0x1a 0x3f09;\
+ phy fe8 0x1f 0x008b; \
+ phy fe8 0x1a 0x3f09; \
+ phy fe16 0x1f 0x008b; \
+ phy fe16 0x1a 0x3f09"
+
+# enable LED matrix mode for PHY54292 on BCM953411K/R
+if $?bcm953411 \
+ "rcload gh_bcm953411x.soc"
+
+if $?simulator \
+ 'echo -n "Chip init finishes at: ";date'
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/reload.soc b/bal_release/3rdparty/bcm-sdk/rc/svk4/reload.soc
new file mode 100644
index 0000000..f48a50e
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/reload.soc
@@ -0,0 +1,8 @@
+#
+# $Id: reload-dune.soc,v 1.1 2011/12/13 15:37:13 assaf Exp $
+#
+# $Copyright: (c) 2006 Broadcom Corp.
+# All Rights Reserved.$
+
+setenv warmboot 1
+rcload rc.soc
diff --git a/bal_release/3rdparty/bcm-sdk/rc/svk4/start_ing.sh b/bal_release/3rdparty/bcm-sdk/rc/svk4/start_ing.sh
new file mode 100755
index 0000000..6f79fb3
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/rc/svk4/start_ing.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+/broadcom/mk_bcm_node.sh
+/broadcom/bcm.user
+
diff --git a/bal_release/3rdparty/bcm-sdk/sdk-bal-6.5.7.patch b/bal_release/3rdparty/bcm-sdk/sdk-bal-6.5.7.patch
new file mode 100644
index 0000000..43f8f01
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/sdk-bal-6.5.7.patch
@@ -0,0 +1,1394 @@
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/include/appl/diag/bal_cmd.h sdk-all-6.5.7/include/appl/diag/bal_cmd.h
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/include/appl/diag/bal_cmd.h 1970-01-01 02:00:00.000000000 +0200
++++ sdk-all-6.5.7/include/appl/diag/bal_cmd.h 2017-01-26 11:24:18.251278489 +0200
+@@ -0,0 +1,22 @@
++/******************************************************************************
++ *
++ * Copyright 2016 - Broadcom Corporation
++ *
++ ******************************************************************************/
++
++#ifndef BAL_CMD_H
++#define BAL_CMD_H
++
++#include <appl/diag/shell.h>
++
++static char cmd_bal_usage[] =
++ "bal [cmd]\n\t"
++ "Commands:\n\t"
++ " trap_target <target_ip:port> - Set a remote ip and port to receive local cpu trapped packets\n\t"
++ " trap_receive <sender_ip:port> - Set a local port to receive remote sender_ip messages \n\t"
++ "\n\t"
++ "When called with no parameters, initialize the BAL BCM Api and enter the bal sub-shell.\n";
++
++cmd_result_t cmd_bal(int unit, args_t *args);
++
++#endif
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/include/bcm/rx.h sdk-all-6.5.7/include/bcm/rx.h
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/include/bcm/rx.h 2016-12-01 05:15:05.000000000 +0200
++++ sdk-all-6.5.7/include/bcm/rx.h 2017-01-26 11:30:12.960122166 +0200
+@@ -1789,5 +1789,18 @@
+ bcm_rx_cosq_mapping_t *rx_cosq_mapping);
+
+ #endif /* BCM_HIDE_DISPATCHABLE */
++
++/*
++ * BAL patch to allow RPC register packet receive callback
++ */
++typedef void (*dpp_rx_cb_f) (
++ int unit,
++ int port,
++ int reason,
++ unsigned char *pkt,
++ int pkt_len);
++
++extern
++void dpp_dft_tx_cb(int unit, int port, int reason, unsigned char *payload, int payload_len);
+
+ #endif /* __BCM_RX_H__ */
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Make.config sdk-all-6.5.7/make/Make.config
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Make.config 2016-12-01 05:16:16.000000000 +0200
++++ sdk-all-6.5.7/make/Make.config 2017-01-26 11:34:39.553494599 +0200
+@@ -32,6 +32,13 @@
+ # }
+ endif
+
++ifeq (${BUILD_ING_AS_LIB},1)
++CFGFLAGS += -DBUILD_ING_AS_LIB -DNO_CTRL_C
++endif
++ifeq (${CONFIG_SWITCH_RPC},y)
++CFGFLAGS += -DCONFIG_SWITCH_RPC
++endif
++
+ #
+ # Set a default target if one is not set. If override-target is set,
+ # then the target will become override-target and a warning is printed
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Make.local.bal sdk-all-6.5.7/make/Make.local.bal
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Make.local.bal 1970-01-01 02:00:00.000000000 +0200
++++ sdk-all-6.5.7/make/Make.local.bal 2017-01-26 11:36:43.722735752 +0200
+@@ -0,0 +1,30 @@
++#FEATURE_LIST := CINT L3 I2C MEM_SCAN EDITLINE TEST BCM_SAL_PROFILE CUSTOMER CHASSIS RCPU ATPTRANS_SOCKET DUNE_UI INTR APIMODE PTP KBP
++FEATURE_LIST := CINT L3 I2C MEM_SCAN EDITLINE TEST BCM_SAL_PROFILE CHASSIS RCPU ATPTRANS_SOCKET DUNE_UI INTR APIMODE PTP
++
++DEBUG_CFLAGS=-Wdeclaration-after-statement
++
++BCM_PTL_SPT=1
++
++ALL_DPP_CHIPS = 1
++ALL_DFE_CHIPS = 1
++
++# Includes XML library and enables use of "diag pp dump" utility for PP import/export facilities
++DATAIO_SUPPORT = 1
++KERN_VER=3.7.10
++
++CFGFLAGS += -DSTATIC=static
++CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT
++CFGFLAGS += -DBCM_WARM_BOOT_SUPPORT_SW_DUMP
++CFGFLAGS += -DBCM_EASY_RELOAD_WB_COMPAT_SUPPORT
++CFGFLAGS += -DBCM_CONTROL_API_TRACKING
++CFGFLAGS += -D__DUNE_LINUX_BCM_CPU_PCIE__
++CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS -DSAL_BDE_32BIT_USER_64BIT_KERNEL
++CFGFLAGS += -D_SIMPLE_MEMORY_ALLOCATION_=0 -DUSE_LINUX_BDE_MMAP=1
++CFGFLAGS += -DSCACHE_CRC_CHECK
++
++CFGFLAGS += -DBROADCOM_SVK
++
++#KBP_DEVICE := KBP_ALG
++
++VENDOR_LIST=CUSTOMER78 BROADCOM DNX
++
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux sdk-all-6.5.7/make/Makefile.unix-linux
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux 2016-12-01 05:16:17.000000000 +0200
++++ sdk-all-6.5.7/make/Makefile.unix-linux 2017-01-26 13:16:35.035828648 +0200
+@@ -47,7 +47,7 @@
+
+
+ # Linux
+-LIBS= -lnsl -lpthread -lm -lrt
++LIBS= -lnsl -pthread -lm -lrt
+ CFGFLAGS += -DBCM_PLATFORM_STRING=\"unix-linux\"
+
+ # For GCC 4.2.x, add -Wno-address
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux-64 sdk-all-6.5.7/make/Makefile.unix-linux-64
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux-64 2016-12-01 05:16:17.000000000 +0200
++++ sdk-all-6.5.7/make/Makefile.unix-linux-64 2017-01-26 13:17:35.959446054 +0200
+@@ -48,7 +48,7 @@
+ FEATURE_EXCLUDE_LIST = $(sort $(_FEATURE_EXCLUDE_LIST))
+
+ # Linux
+-LIBS= -lnsl -lpthread -lm -lrt
++LIBS= -lnsl -pthread -lm -lrt
+
+ CFGFLAGS += -DBCM_PLATFORM_STRING=\"unix-linux-64\"
+
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux~ sdk-all-6.5.7/make/Makefile.unix-linux~
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-linux~ 1970-01-01 02:00:00.000000000 +0200
++++ sdk-all-6.5.7/make/Makefile.unix-linux~ 2017-01-26 13:16:34.973829038 +0200
+@@ -0,0 +1,60 @@
++# $Id: Makefile.unix-linux,v 1.11 Broadcom SDK $
++# $Copyright: (c) 2016 Broadcom.
++# Broadcom Proprietary and Confidential. All rights reserved.$
++#
++# Build rules for Linux/x86 (Little Endian) with PLI support
++
++include ${SDK}/make/Makefile.unix-common
++
++# When using GDB on Linux, you may want to use "setenv GDB 1" to disable
++# editline. For best results put "set environment GDB 1" in your .gdbinit.
++
++# Linux-specific Configuration Flags
++
++ENDIAN_DEF = -DLE_HOST=1
++
++# Notes on AMD Athlon 64-bit
++#
++# Compiles on x86_64 default to 32-bit emulation unless 64-bit mode
++# is specifically requested in Make.local by uncommenting the two defines
++# for PTRS_ARE_64BITS and LONGS_ARE_64BITS.
++#
++# Note that the code base will compile in 64-bit mode, but will not run
++# correctly because malloc() can return values >32 bits and the PLISIM
++# protocol only supports 32-bit addresses.
++
++ifeq ($(shell uname -m),x86_64)
++ ifeq (,$(findstring -DPTRS_ARE_64BITS,$(CFGFLAGS)))
++ CC = ${HCC} -m32
++ CXX = g++ -m32
++ else
++ CC = ${HCC}
++ CXX = g++
++ endif
++endif
++
++LD = ld
++AR = ar
++ARFLAGS = -rc
++STRIP = strip
++RANLIB = ranlib
++
++# Filter out features that cannot or should not be supported in Linux
++ifdef ESW_CHIPS
++_FEATURE_EXCLUDE_LIST += OOB_RCPU
++endif
++FEATURE_EXCLUDE_LIST = $(sort $(_FEATURE_EXCLUDE_LIST))
++
++
++# Linux
++LIBS= -lnsl -lpthread -lm -lrt
++CFGFLAGS += -DBCM_PLATFORM_STRING=\"unix-linux\"
++
++# For GCC 4.2.x, add -Wno-address
++GCC_MAJOR_VER = $(shell echo |$(CC) -dM -E -| grep __GNUC__ | cut -d' ' -f3)
++GCC_MINOR_VER = $(shell echo |$(CC) -dM -E -| grep __GNUC_MINOR__ | cut -d' ' -f3)
++ifeq (${GCC_MAJOR_VER}, 4)
++ifeq (${GCC_MINOR_VER}, 2)
++BCM_EXTRA_CC_CFLAGS = -Wno-address
++endif
++endif
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-netbsd sdk-all-6.5.7/make/Makefile.unix-netbsd
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-netbsd 2016-12-01 05:16:17.000000000 +0200
++++ sdk-all-6.5.7/make/Makefile.unix-netbsd 2017-01-26 13:13:03.884156251 +0200
+@@ -27,7 +27,7 @@
+ FEATURE_EXCLUDE_LIST = $(sort $(_FEATURE_EXCLUDE_LIST))
+
+ # NetBSD
+-LIBS= -lpthread -lm -lsem
+++LIBS= -pthread -lm -lsem
+
+ CFGFLAGS += -DBCM_PLATFORM_STRING=\"unix-netbsd\"
+
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-user sdk-all-6.5.7/make/Makefile.unix-user
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/make/Makefile.unix-user 2016-12-01 05:16:17.000000000 +0200
++++ sdk-all-6.5.7/make/Makefile.unix-user 2017-01-26 13:14:29.289618967 +0200
+@@ -42,7 +42,7 @@
+ OSTYPE = LINUX
+
+ # Linux
+-LIBS= -lnsl -lpthread -lm -lrt
++LIBS= -lnsl -pthread -lm -lrt
+
+ #
+ # ORIGIN is used to Optionally select different CFLAGS. It is used to import
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/bal_cmd.c sdk-all-6.5.7/src/appl/diag/bal_cmd.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/bal_cmd.c 1970-01-01 02:00:00.000000000 +0200
++++ sdk-all-6.5.7/src/appl/diag/bal_cmd.c 2017-01-26 11:38:20.574144410 +0200
+@@ -0,0 +1,837 @@
++/******************************************************************************
++ *
++ * Copyright 2015- Broadcom Corporation
++ * This program is the proprietary software of Broadcom Corporation
++ * and/or its licensors, and may only be used, duplicated, modified or
++ * distributed pursuant to the terms and conditions of a separate,
++ * written license agreement executed between you and Broadcom (an
++ * "Authorized License"). Except as set forth in an Authorized License,
++ * Broadcom grants no license (express or implied), right to use, or
++ * waiver of any kind with respect to the Software, and Broadcom
++ * expressly reserves all rights in and to the Software and all
++ * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED
++ * LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND
++ * SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE
++ * SOFTWARE.
++ *
++ * Except as expressly set forth in the Authorized License,
++ *
++ * 1. This program, including its structure, sequence and organization,
++ * constitutes the valuable trade secrets of Broadcom, and you shall use
++ * all reasonable efforts to protect the confidentiality thereof, and to
++ * use this information only in connection with your use of Broadcom
++ * integrated circuit products.
++ *
++ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
++ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
++ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
++ * OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
++ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
++ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
++ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
++ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
++ * OF USE OR PERFORMANCE OF THE SOFTWARE.
++ *
++ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
++ * OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
++ * INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
++ * RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
++ * BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
++ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
++ * ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
++ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
++ * REMEDY.
++ *
++ ******************************************************************************/
++
++/**
++ * @file bal_cmd.c_
++ * @brief BAL ING CLI commands support SDK access that is not supported by regular CLI
++ * The BAL CLI command line interface is implemented by the CLI
++ * module. The CLI module can be used as the configuration and management
++ * interface for the BAL Switch Util. BAL Switch Util configuration can be specified
++ * using a series of BAL CLI commands. The main purpose of the CLI is to provide
++ * ING API access that are not normally available through public API, such as RPC
++ * access to ING features that are deep in SDK stack.
++ *
++ **/
++
++ /*@{*/
++
++/* --- system includes --- */
++
++#include <unistd.h>
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <appl/diag/shell.h>
++#include <appl/diag/parse.h>
++#include <sal/appl/sal.h>
++#include <sal/appl/editline/editline.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <bcm/rx.h>
++#include <bcm/error.h>
++#include <bcm/stack.h>
++
++#define BAL_CLI_VERSION "1.0"
++
++/* --- project includes --- */
++extern int start_trap_service(char *ip_port);
++extern int start_host_listener(char *ip_port);
++
++/* --- local static constants ---*/
++#define BAL_SWITCH_CLI_IP_LEN 128
++typedef struct bal_switch_cli_cfg_t
++{
++ char trap_target[BAL_SWITCH_CLI_IP_LEN]; /* remote ip:port address where the trapped packet sent */
++ char trap_receive[BAL_SWITCH_CLI_IP_LEN]; /* remote ip where the local port receive message */
++}bal_switch_cli_cfg_t;
++
++static bal_switch_cli_cfg_t g_cur_ctx;
++
++static bal_switch_cli_cfg_t *gp_cur_ctx = &g_cur_ctx;
++
++enum
++{
++ BAL_REASON_SEND_TO_NNI = 1,
++ BAL_REASON_SEND_TO_PON
++};
++
++/**
++ * * @brief Maximum number of arguments supported by the 'bal' CLI command
++ * */
++#define MAX_ARGS 10
++
++/**
++ ** @brief BAL CLI help text
++ **/
++#define HELP \
++"exit - Exit the BAL sub-shell\n" \
++"show - Show current settings\n" \
++"trap_target - register callback and send CPU trapped packets to remote IP:PORT\n" \
++"trap_receive - Start a receiving thread to listen on PORT for messages from remote IP \n" \
++
++
++/**
++ ** @brief BAL Switch App help text specific to 'show' commands
++ **/
++#define SHOW_HELP \
++"show config - Display the BAL CLI configuration\n" \
++"show version - Display the BAL BCM SDK version\n" \
++
++
++/**
++ * @brief CLI prompt string
++ * */
++static char g_bal_cli_prompt[8];
++
++
++/*
++ * @brief BAL Switch App help text
++ *
++ * @return char* A string containing the prompt to display
++ **/
++static char *bal_set_prompt()
++{
++ sprintf(g_bal_cli_prompt, "bal>");
++ return g_bal_cli_prompt;
++}
++
++/**
++ * @brief Parse a line of input into a POSIX-like argument list
++ *
++ ** @param parsed_input Unparsed line of CLI input
++ ** @param argc Pointer to the number of arguments in the list
++ ** @param argv Pointer to the argument list
++ ** @return int Number of argument that has been successfully parsed
++ **/
++int bal_parse_input (char *parsed_input, int *argc, char **argv)
++{
++ char *s;
++ int largc;
++
++ largc = 0;
++ s = parsed_input;
++ while ((largc < MAX_ARGS) && (s != NULL) && (*s != 0))
++ {
++ /* Skip leading whitespace */
++ s += strspn (s, " \t");
++
++ /* Non-whitespace found */
++ if (*s != 0)
++ {
++ /* Add the string to the argument list */
++ argv[largc++] = s;
++
++ /* Find the trailing whitespace (if any...) */
++ s = strpbrk (s, " \t");
++ if (s != NULL)
++ {
++ /* Found some white space, null out the first white
++ space character. */
++ if (largc < MAX_ARGS)
++ {
++ *s++ = 0;
++ }
++
++ /* Otherwise, don't null the last param, to pass it on
++ * command to parse themselves
++ */
++ }
++ }
++ }
++
++ *argc = largc;
++
++ return largc;
++}
++
++ /* BAL packet_in function and definitions */
++ typedef struct
++ {
++ int socket;
++ struct sockaddr_in addr;
++ }trap_target_t;
++ static trap_target_t s_target_device;
++ static int target_init = 0;
++ #define DEFAULT_SOP_ADJ 2
++ #define DEFAULT_REASON_ADJ 4
++
++ bcm_rx_t trap_service_cb(int unit, bcm_pkt_t *pkt, void *cookie)
++ {
++
++ uint8 *p_payload;
++ int dpp_hdr_len, payload_len, n_sent;
++ trap_target_t *p_target_device = (trap_target_t *)cookie;
++ uint16 *p_src_port, def_sop;
++ uint32 *p_reason, def_reason;
++ /* skip the dpp header - 19 bytes */
++ p_payload = pkt->_pkt_data.data;
++ dpp_hdr_len = pkt->tot_len - pkt->pkt_len + 0;
++ payload_len = pkt->tot_len - dpp_hdr_len;
++ p_payload += dpp_hdr_len;
++
++ /*
++ * replace SOP_ADJ bytes with source port info before send
++ * assuming DEFAULT_SOP_ADJ is always 2 bytes
++ * replace SOP_REASON bytes with trap reason - TBD
++ */
++ p_src_port = (uint16 *)(p_payload - DEFAULT_SOP_ADJ);
++ /* save the original info */
++ def_sop = *(p_src_port);
++ /* replace 2 bytes with ingress port info */
++ *p_src_port = htons(pkt->src_port & 0xff); /* pkt->src_port is 1 byte long */
++
++ p_reason = (uint32 *)(p_payload - DEFAULT_SOP_ADJ - DEFAULT_REASON_ADJ);
++ /* save the original info */
++ def_reason = *(p_reason);
++ /* replace 4 bytes with reason code */
++ *p_reason = htonl(pkt->rx_trap_data);
++
++ n_sent = sendto(p_target_device->socket,
++ p_payload-DEFAULT_SOP_ADJ-DEFAULT_REASON_ADJ,
++ payload_len+DEFAULT_SOP_ADJ+DEFAULT_REASON_ADJ, 0,
++ (struct sockaddr *) &(p_target_device->addr),
++ sizeof(struct sockaddr_in));
++
++ /* put back the original values */
++ *p_src_port = def_sop;
++ *p_reason = def_reason;
++
++ if (n_sent > 0)
++ return BCM_RX_HANDLED;
++ else
++ return BCM_RX_NOT_HANDLED;
++ }
++
++ int start_trap_service( char *ip_port)
++ {
++ int ret, port;
++ char ip[80], *col;
++
++ if(target_init == 0)
++ {
++ if((s_target_device.socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
++ {
++ return -1;
++ }
++ target_init = 1;
++ }
++ /* fill in traget device info - ip_port has the format of ip:port, so look for ":" for separation */
++ col = strstr(ip_port, ":");
++ port = atoi(col+1);
++ /* terminate the string at the end of IP address */
++ *col = 0;
++ strcpy(ip, ip_port);
++
++ s_target_device.addr.sin_family = AF_INET;
++ s_target_device.addr.sin_port = htons(port);
++ s_target_device.addr.sin_addr.s_addr = inet_addr(ip);
++
++ ret = bcm_rx_register(0, "Cpu Traps", trap_service_cb, 50, (void *)&s_target_device, BCM_RCO_F_ALL_COS);
++ return ret;
++ }
++
++/**
++ ** @brief CLI parser and handler for 'trap_target' commands
++ **
++ ** This routine handles the 'bal trap_target [args]' CLI app configuration
++ ** commands.
++ **
++ ** @param argc Pointer to the number of arguments in the list
++ ** @param argv Pointer to the argument list
++ * */
++void bal_bcm_cli_trap_target(int argc, char **argv)
++{
++
++ if (argc != 1)
++ {
++ printf("Invalid arguments\n");
++ return;
++ }
++
++ {
++ strcpy(gp_cur_ctx->trap_target, argv[0]);
++ /* Configure the trap target with the specified setting. */
++ if (start_trap_service(argv[0]) != 0)
++ {
++ printf("Error, failed to start trap service on '%s'\n",
++ argv[0]);
++ }
++ }
++}
++
++typedef struct
++{
++ int udp_port;
++ sal_thread_t threadid;
++ dpp_rx_cb_f callback;
++}trap_context_t;
++
++ static trap_context_t trap_ctx = {0};
++ static int listener_init = 0;
++
++#define MAX_RX_PACKET_SIZE (2000)
++
++static void host_receive(void *p_user_data)
++{
++ int rc;
++ int sUDPSocket;
++ unsigned char cBuffer[MAX_RX_PACKET_SIZE];
++ int nBytesRecv = 0;
++ int nBufSize = MAX_RX_PACKET_SIZE;
++ socklen_t nReceiveAddrSize = 0;
++ int maxfd;
++ fd_set read_fds;
++ struct timeval tv;
++ uint16 *p_dst_port, dst_port;
++ trap_context_t *p_trap_ctx = (trap_context_t *)p_user_data;
++ uint32 *p_reason, reason;
++ struct sockaddr_in sReceiveFromAddr;
++
++ /* Create a connectionless socket */
++ sUDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
++ /* Check to see if we have a valid socket */
++ if(sUDPSocket < 0)
++ {
++ printf(" host_receive:create socket failed\n");
++ return;
++ }
++
++ /* Setup a bind on the socket, telling us what port and
++ * adapter to receive datagrams on.
++ * NOTE: we accept UDP packets from any sender as long
++ * as they arrive on the specified port.
++ */
++ memset(&sReceiveFromAddr, 0, sizeof(struct sockaddr_in));
++
++ sReceiveFromAddr.sin_family = AF_INET;
++ sReceiveFromAddr.sin_port = htons(p_trap_ctx->udp_port);
++ sReceiveFromAddr.sin_addr.s_addr = htonl(INADDR_ANY);
++
++ rc = bind(sUDPSocket, (struct sockaddr *)&sReceiveFromAddr,
++ sizeof(struct sockaddr_in));
++ if (rc < 0)
++ {
++ printf("host_receive:bind failed\n");
++ return;
++ }
++
++ // Receive a datagram from another device
++ while(1)
++ {
++ FD_ZERO(&read_fds);
++ FD_SET(sUDPSocket, &read_fds);
++ maxfd = sUDPSocket;
++ /* Set the timeout */
++ tv.tv_sec = 1;
++ tv.tv_usec = 0; /* 1 seconds */
++ rc = select(maxfd + 1, &read_fds, NULL, NULL, &tv);
++
++ if (rc < 0)
++ {
++ printf(" host_receive:select failed err = %d\n", rc);
++ break;
++ }
++ if (rc == 0)
++ {
++ fflush(stdout);
++ continue;
++ }
++ // Get the datagram
++ nBytesRecv = recvfrom(sUDPSocket, cBuffer, nBufSize, 0,
++ (struct sockaddr *) &sReceiveFromAddr,
++ &nReceiveAddrSize);
++ printf("Got %d bytes message \n", nBytesRecv);
++ /* the first 4 bytes are reason */
++ p_reason = (uint32 *)(cBuffer);
++ reason = ntohl(*p_reason);
++
++ /* the next 2 bytes are destination port */
++ p_dst_port = (uint16 *)(cBuffer + DEFAULT_REASON_ADJ);
++ dst_port = ntohs(*p_dst_port);
++
++ /* call the register callback here - set unit to 0 as it is don't care */
++ if(p_trap_ctx->callback)
++ {
++ p_trap_ctx->callback(0,
++ dst_port,
++ reason,
++ cBuffer+DEFAULT_SOP_ADJ+DEFAULT_REASON_ADJ,
++ nBytesRecv-DEFAULT_SOP_ADJ-DEFAULT_REASON_ADJ);
++ }
++ }
++ close(sUDPSocket);
++
++ return;
++}
++
++
++void dpp_dft_tx_cb(int unit, int dst_port, int reason, unsigned char *payload, int payload_len)
++{
++
++ int i;
++ bcm_pkt_t *tx_pkt;
++ uint8_t tx_pkt_dune_header[6];
++ uint32_t tx_pkt_offset = 0;
++ bcm_gport_t sys_gport;
++ bcm_gport_t local_gport;
++ bcm_port_t sysport = 0;
++ bcm_gport_t local_cpu_port = 0;
++ int sdk_rc;
++
++ printf("Msg from core:\n");
++ printf(" dst port:%d, rcv reason: 0x%x, ", dst_port, reason);
++
++ /* dump out first 32 bytes */
++ printf("payload (first 12 bytes): ");
++ for(i=0; i<12; i++)
++ {
++ if(i%6 == 0 && i) printf(" ");
++ printf("%02x", payload[i]);
++ }
++ printf("\n");
++
++
++ /* Map the local port number to a CPU "system" port. */
++ local_gport = dst_port;
++ sdk_rc = bcm_stk_gport_sysport_get(unit, local_gport, &sys_gport);
++ if (sdk_rc != BCM_E_NONE)
++ {
++ /* Error */
++ printf("%s(): [PacketOut] bcm_stk_gport_sysport_get returned with failure code '%s'\n",
++ __FUNCTION__, bcm_errmsg(sdk_rc));
++ return;
++ }
++
++ sysport = sys_gport & 0xff;
++
++ /* Get the local CPU port */
++ sdk_rc = bcm_port_local_get(unit, BCM_GPORT_LOCAL_CPU, &local_cpu_port);
++ if (sdk_rc != BCM_E_NONE)
++ {
++ /* Error */
++ printf("%s(): [PacketOut] bcm_port_local_get returned with failure code '%s'\n",
++ __FUNCTION__, bcm_errmsg(sdk_rc));
++ return;
++ }
++
++ /* Allocate a packet structure */
++ sdk_rc = bcm_pkt_alloc(unit, payload_len+sizeof(tx_pkt_dune_header), 0, &tx_pkt);
++
++ if (sdk_rc != BCM_E_NONE)
++ {
++ /* Error */
++ printf("%s(): [PacketOut] bcm_pkt_alloc returned with failure code '%s'\n",
++ __FUNCTION__, bcm_errmsg(sdk_rc));
++ return;
++ }
++
++ /* Set up the packet for a single block */
++ tx_pkt->call_back = 0;
++ tx_pkt->blk_count = 1;
++ tx_pkt->unit = unit;
++
++ /* Dune TM header */
++ tx_pkt->_dpp_hdr[3] = 0x00; /* channel num */
++ tx_pkt->_dpp_hdr[2] = 0x00;
++ tx_pkt->_dpp_hdr[1] = 0x00;
++ tx_pkt->_dpp_hdr[0] = 0x00;
++
++ tx_pkt->_dpp_hdr_type = 1; /* DPP_HDR_itmh_base */
++
++ /* PTCH */
++ tx_pkt_dune_header[0] = 0x50;
++ tx_pkt_dune_header[1] = local_cpu_port;
++
++ /* ITMH */
++ tx_pkt_dune_header[2] = 0x01;
++ tx_pkt_dune_header[3] = 0x00;
++ tx_pkt_dune_header[4] = (sysport & 0xff); /* Destination port */
++ tx_pkt_dune_header[5] = 0x00;
++
++ /* Insert the DUNE header into the packet */
++ bcm_pkt_memcpy (tx_pkt, tx_pkt_offset, tx_pkt_dune_header, sizeof(tx_pkt_dune_header));
++ tx_pkt_offset += sizeof(tx_pkt_dune_header);
++
++ /* Insert the payload into the packet */
++ bcm_pkt_memcpy (tx_pkt, tx_pkt_offset, payload, payload_len);
++ tx_pkt_offset += payload_len;
++
++ printf("%s(): [PacketOut] transmitting a %d length packet, "
++ "sys_gport:0x%X, sysport: %d\n",
++ __FUNCTION__,
++ payload_len,
++ sys_gport,
++ sysport);
++
++ /* Transmit the packet */
++ sdk_rc = bcm_tx(unit, tx_pkt, NULL);
++ if (sdk_rc != BCM_E_NONE)
++ {
++ /* Error */
++ printf( "%s(): bcm_tx returned with failure code '%s'\n",
++ __FUNCTION__, bcm_errmsg(sdk_rc));
++ }
++
++ /* Cleanup */
++ bcm_pkt_free(unit, tx_pkt);
++
++ return;
++}
++
++void dpp_dft_msg_cb(int unit, int dst_port, int reason, unsigned char *payload, int payload_len)
++{
++
++ int i, len;
++
++ printf("Msg from core:\n");
++ printf(" dst port:%d, rcv reason: 0x%x, ", dst_port, reason);
++
++ len = (payload_len > 32)? 32: payload_len;
++
++ /* dump out first 32 bytes */
++ printf("payload (first %d bytes): ", len);
++ for(i=0; i<len; i++)
++ {
++ if(i%8 == 0 && i) printf(" ");
++ printf("%02x", payload[i]);
++ }
++ printf("\n");
++
++ return;
++}
++
++void dpp_dft_host_cb(int unit, int dst_port, int reason, unsigned char *payload, int payload_len)
++{
++ switch(reason)
++ {
++ case BAL_REASON_SEND_TO_NNI:
++ case BAL_REASON_SEND_TO_PON:
++ dpp_dft_tx_cb(unit, dst_port, reason, payload, payload_len);
++ break;
++ default:
++ dpp_dft_msg_cb(unit, dst_port, reason, payload, payload_len);
++ break;
++ }
++ return;
++}
++
++
++
++
++
++
++
++
++
++
++/*
++ * This is the function that is called to start a thread to listen for
++ * packets sent from BAL to bcm.user for injection into the switch.
++ *
++ * This happens when the user includes the trap_receive identifier in
++ * the rpc.soc file that is co-resident with the bcm.user executable.
++ *
++ ** An example line in the rpc.soc file might be:
++ *
++ * dune "sand trap_receive 10.3.2.2:50003"
++ *
++ * This line specifies to listen on port 50003 and that messages will
++ * arrive from IP 10.3.2.2 (although the IP address is not respected
++ * in this code).
++ *
++ * */
++int start_host_listener(char *ip_port)
++ {
++
++ char *col;
++
++ if(listener_init != 0)
++ {
++ return 0;
++ }
++
++ /* fill in host listener info - ip_port has the format of ip:port, so look for ":" for separation */
++ col = strstr(ip_port, ":");
++ trap_ctx.udp_port = atoi(col+1);
++
++ /* register a default handler */
++ trap_ctx.callback = dpp_dft_host_cb;
++
++ /* spawn a thread to listen to socket */
++ trap_ctx.threadid = sal_thread_create("trap_rx", 8192, 50, host_receive, &trap_ctx);
++
++ if (trap_ctx.threadid == SAL_THREAD_ERROR)
++ {
++ return -2;
++ }
++
++ listener_init = 1;
++ return 0;
++ }
++
++/**
++ ** @brief CLI parser and handler for 'trap_receive' commands
++ **
++ ** This routine handles the 'bal trap_receive [args]' CLI app configuration
++ ** commands.
++ **
++ ** @param argc Pointer to the number of arguments in the list
++ ** @param argv Pointer to the argument list
++ * */
++void bal_bcm_cli_trap_receive(int argc, char **argv)
++{
++
++ if (argc != 1)
++ {
++ printf("Invalid arguments\n");
++ return;
++ }
++
++ {
++ strcpy(gp_cur_ctx->trap_receive, argv[0]);
++ /* Configure the msg receiver with the specified setting. */
++ if (start_host_listener(argv[0]) != 0)
++ {
++ printf("Error, failed to start trap listener on '%s'\n",
++ argv[0]);
++ }
++ }
++}
++
++/**
++ ** @brief Handler for the 'bal show version' command
++ **
++ ** This routine handles the 'bal show version' CLI command
++ ** and show version information on the console.
++ **
++ **/
++void bal_bcm_show_version(void)
++{
++
++ /* Print out the software revision information */
++ printf("Broadcom Software, Broadband Abstraction Layer, CLI Version %s \n",
++ BAL_CLI_VERSION);
++}
++
++
++/**
++ ** @brief CLI parser and handler for 'show' commands
++ **
++ ** This routine handles the 'bal show [args]' CLI app commands.
++ **
++ ** @param argc Pointer to the number of arguments in the list
++ ** @param argv Pointer to the argument list
++ **/
++void bal_bcm_cli_show(int argc, char **argv)
++{
++ char *show_cmd;
++
++ show_cmd = argv[0];
++
++ if (argc == 0)
++ {
++ printf("Error: missing show sub-command.\n");
++ printf("%s", SHOW_HELP);
++ return;
++ }
++
++ show_cmd = argv[0];
++
++ if (sal_strcasecmp(show_cmd, "config") == 0)
++ {
++ printf("BAL BCM App Configuration:\n");
++ printf("--------------------------------\n");
++ printf("trap_target ip_port = %s\n", gp_cur_ctx->trap_target);
++ printf("trap_receive ip_port = %s\n", gp_cur_ctx->trap_receive);
++ }
++ else if (sal_strcasecmp(show_cmd, "version") == 0)
++ {
++ bal_bcm_show_version();
++ }
++ else if (sal_strcasecmp(show_cmd, "help") == 0 ||
++ sal_strcasecmp(show_cmd, "?") == 0)
++ {
++ printf("%s", SHOW_HELP);
++ }
++ else
++ {
++ printf("Error: unknown show command '%s'.\n", show_cmd);
++ }
++}
++
++/**
++ ** @brief Executes a command as specified by a single line of CLI input
++ **
++ ** @param argc Pointer to the number of arguments in the list
++ ** @param argv Pointer to the argument list
++ **/
++void DoCmd(int argc, char **argv)
++{
++ char *cmd;
++
++ if (argc == 0 || argv[0] == NULL)
++ {
++ return;
++ }
++
++ cmd = argv[0];
++
++ printf("CLI executing command '%s'\n", cmd);
++
++ if (sal_strcasecmp(cmd, "trap_target") == 0)
++ {
++ bal_bcm_cli_trap_target(argc-1, &argv[1]);
++ }
++ else if (sal_strcasecmp(cmd, "trap_receive") == 0)
++ {
++ bal_bcm_cli_trap_receive(argc-1, &argv[1]);
++ }
++ else if (sal_strcasecmp(cmd, "show") == 0)
++ {
++ bal_bcm_cli_show(argc-1, &argv[1]);
++ }
++ else if (sal_strcasecmp(cmd, "help") == 0 ||
++ sal_strcasecmp(cmd, "?") == 0)
++ {
++ /* Display help */
++ printf("%s", HELP);
++ }
++ else if (sal_strcasecmp(cmd, "exit") == 0)
++ {
++ return;
++ }
++ else
++ {
++ printf("Unknown command '%s'\n", cmd);
++ }
++}
++
++/**
++ * * @brief Main processing loop for the CLI
++ * *
++ * * @param args Pointer to an BCM SDK formatted argument list
++ * */
++void bal_cli_shell(args_t *args)
++{
++ char *cmd;
++ int argc = 0;
++ char *argv[MAX_ARGS];
++ static int initialized = 0;
++
++ if (initialized == 0)
++ {
++ bal_set_prompt();
++ initialized = 1;
++ }
++
++ if (args->a_argc > 1)
++ {
++
++ DoCmd(args->a_argc-1, &args->a_argv[1]);
++ }
++ else
++ {
++
++ printf("CLI running in interactive mode\n");
++
++ for (;;)
++ {
++ /* use ING editline library, DONT free pointer "cmd" as Linux man readline
++ suggested, it will cause a crash */
++ cmd = readline(g_bal_cli_prompt);
++ if (*cmd != '\0')
++ {
++ add_history(cmd);
++ }
++ else
++ {
++ continue;
++ }
++
++ if ((sal_strcasecmp(cmd, "exit") == 0) || (sal_strcasecmp(cmd, "quit") == 0))
++ {
++ printf ("exiting bal shell.\n");
++ break;
++ }
++
++ bal_parse_input(cmd, &argc, argv);
++
++ DoCmd(argc, argv);
++
++ }
++ }
++
++ /* "Consume" all of the command line arguments so the bcm.user shell
++ * does not complain.
++ */
++ args->a_arg = args->a_argc;
++}
++
++/**
++ * @brief The cmdlist hook for the BAL BCM App CLI command
++ *
++ * This file contains the function to "hook" into the main bcm.user
++ * CLI.
++ *
++ * @param unit SDK unit number
++ * @param args Pointer to an BCM SDK formatted argument list
++ *
++ * @return cmd_result_t
++ *
++ * */
++cmd_result_t cmd_bal(int unit, args_t *args)
++{
++ /* char *subcmd = ARG_GET(args); */
++
++ bal_cli_shell(args);
++
++ return CMD_OK;
++}
++/*@}*/
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/cmdlist.c sdk-all-6.5.7/src/appl/diag/cmdlist.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/cmdlist.c 2016-12-01 05:16:25.000000000 +0200
++++ sdk-all-6.5.7/src/appl/diag/cmdlist.c 2017-01-26 12:04:04.992722758 +0200
+@@ -57,6 +57,7 @@
+
+ #include <appl/diag/diag.h>
+ #include <appl/diag/cmdlist.h>
++#include <appl/diag/bal_cmd.h>
+
+ cmd_t *cur_cmd_list[SOC_MAX_NUM_DEVICES];
+ int cur_cmd_cnt[SOC_MAX_NUM_DEVICES];
+@@ -98,6 +99,9 @@
+ "Attach SOC device(s)" },
+ {"BackGround", sh_bg, sh_bg_usage,
+ "Execute a command in the background."},
++ /* BAL ING API support */
++ {"BAL", cmd_bal, cmd_bal_usage,
++ "Run a BAL ING Api command."},
+ #if defined(INCLUDE_BCMX_DIAG)
+ {"BCM", cmd_mode_bcm, shell_bcm_usage,
+ "Set shell mode to BCM."},
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/ctrans.c sdk-all-6.5.7/src/appl/diag/ctrans.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/ctrans.c 2016-12-01 05:16:25.000000000 +0200
++++ sdk-all-6.5.7/src/appl/diag/ctrans.c 2017-01-26 12:23:48.883393220 +0200
+@@ -1016,6 +1016,7 @@
+ return rv;
+ }
+
++#define BAL_CMD_LEN 128
+
+ bcm_rx_t
+ ab_echo_cb(cpudb_key_t src_key,
+@@ -1033,6 +1034,8 @@
+ int mode;
+ int len;
+ CallbackOptions *options = (CallbackOptions *)cookie;
++ char bal_cmd[BAL_CMD_LEN];
++ int bal_cmd_len;
+
+ if (payload == NULL) { /* Just use first segment for string */
+ if (pkt == NULL) {
+@@ -1085,6 +1088,9 @@
+ _send_echo_pkt(client_id, payload, len, depth - 1,
+ pkt_flags, mode, options->verbose, src_key, NULL);
+ }
++ bal_cmd_len = ((len-offset) >= BAL_CMD_LEN)? BAL_CMD_LEN-1: len-offset;
++ memcpy(bal_cmd, &payload[offset], bal_cmd_len);
++ bal_cmd[bal_cmd_len] = 0;
+
+ if (async_free) {
+ rv = BCM_RX_HANDLED_OWNED;
+@@ -1093,6 +1099,13 @@
+ rv = BCM_RX_HANDLED;
+ }
+
++ /** if string has special cli prefix !>, execute the cli command */
++ if(bal_cmd[0] == '!' && bal_cmd[1] == '>')
++ {
++ cli_out("Execute BAL CLI cmd -> %s\n", &bal_cmd[2]);
++ sh_process_command(0, &bal_cmd[2]);
++ }
++
+ return rv;
+ }
+
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/shell.c sdk-all-6.5.7/src/appl/diag/shell.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/shell.c 2016-12-01 05:16:25.000000000 +0200
++++ sdk-all-6.5.7/src/appl/diag/shell.c 2017-01-26 12:31:49.873427400 +0200
+@@ -214,10 +214,15 @@
+ var_unset("ihost_mode", FALSE, TRUE, FALSE);
+ var_unset("num_ucs", FALSE, TRUE, FALSE);
+ }
++
++#ifdef CONFIG_SWITCH_RPC
++ cli_out("Running with remote hardware, skip setting unit variable\n");
++ return;
++#endif
+
+ if (new_unit >= 0) {
+- uint16 dev_id;
+- uint8 rev_id;
++ uint16 dev_id;
++ uint8 rev_id;
+ char *chip_string;
+ uint16 dev_id_driver;
+ uint8 rev_id_driver;
+@@ -466,7 +471,9 @@
+ /* Not attached, print out error */
+ if (override_unit)
+ return TRUE;
++#ifndef BUILD_ING_AS_LIB
+ cli_out("%s: Error: Unit %d not attached\n", pfx, u);
++#endif
+ return(FALSE);
+ }
+ return(TRUE);
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/system.c sdk-all-6.5.7/src/appl/diag/system.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/appl/diag/system.c 2016-12-01 05:16:25.000000000 +0200
++++ sdk-all-6.5.7/src/appl/diag/system.c 2017-01-26 12:35:45.001982454 +0200
+@@ -2379,7 +2379,13 @@
+ DISPLAY_MEM_PRINTF(("%s(): Just before BCM shell\r\n",__FUNCTION__)) ;
+
+ while (1) {
++
++#ifndef BUILD_ING_AS_LIB
+ sh_process(-1, "BCM", TRUE);
++#else
++ return;
++#endif
++
+ #ifdef NO_SAL_APPL
+ return;
+ #else
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/dpp/alloc_mngr_cosq.c sdk-all-6.5.7/src/bcm/dpp/alloc_mngr_cosq.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/dpp/alloc_mngr_cosq.c 2016-12-01 05:16:47.000000000 +0200
++++ sdk-all-6.5.7/src/bcm/dpp/alloc_mngr_cosq.c 2017-01-26 12:43:50.511008400 +0200
+@@ -3644,6 +3644,7 @@
+ if (flow_type == SOC_TMC_AM_SCH_FLOW_TYPE_CONNECTOR) {
+ region = _BCM_DPP_AM_COSQ_GET_REGION_INDEX_FROM_FLOW_INDEX(*flow_id);
+ if (nof_remote_cores != SOC_DPP_CONFIG(unit)->arad->region_nof_remote_cores[core][region]) {
++ printf(" nof_remote_cores %d != %d at core %d region %d\n", nof_remote_cores, SOC_DPP_CONFIG(unit)->arad->region_nof_remote_cores[core][region], core, region);
+ BCMDNX_ERR_EXIT_MSG(BCM_E_PARAM,(_BSL_BCM_MSG("Requested region doesn't support requested number of remote cores")));
+ }
+ }
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/pack.c sdk-all-6.5.7/src/bcm/rpc/pack.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/pack.c 2016-12-01 05:17:00.000000000 +0200
++++ sdk-all-6.5.7/src/bcm/rpc/pack.c 2017-01-26 12:52:51.016711143 +0200
+@@ -9975,6 +9975,9 @@
+ uint8 *
+ _bcm_pack_rx_trap_config(uint8 *buf, bcm_rx_trap_config_t *var)
+ {
++ uint8 zero_8 = 0;
++ uint32 zero_32 = 0;
++
+ BCM_PACK_U32(buf, var->flags);
+ BCM_PACK_U32(buf, var->dest_port);
+ BCM_PACK_U32(buf, var->dest_group);
+@@ -9989,12 +9992,32 @@
+ BCM_PACK_U32(buf, var->forwarding_type);
+ BCM_PACK_U32(buf, var->forwarding_header);
+ BCM_PACK_U32(buf, var->encap_id);
+- BCM_PACK_U32(buf, var->mirror_cmd->flags);
+- BCM_PACK_U8(buf, var->mirror_cmd->forward_strength);
+- BCM_PACK_U8(buf, var->mirror_cmd->copy_strength);
+- BCM_PACK_U32(buf, var->mirror_cmd->recycle_cmd);
+- BCM_PACK_U32(buf, var->core_config_arr->dest_port);
+- BCM_PACK_U32(buf, var->core_config_arr->encap_id);
++
++ if(var->mirror_cmd)
++ {
++ BCM_PACK_U32(buf, var->mirror_cmd->flags);
++ BCM_PACK_U8(buf, var->mirror_cmd->forward_strength);
++ BCM_PACK_U8(buf, var->mirror_cmd->copy_strength);
++ BCM_PACK_U32(buf, var->mirror_cmd->recycle_cmd);
++ }
++ else
++ {
++ BCM_PACK_U32(buf, zero_32);
++ BCM_PACK_U8(buf, zero_8);
++ BCM_PACK_U8(buf, zero_8);
++ BCM_PACK_U32(buf, zero_32);
++ }
++ if(var->core_config_arr)
++ {
++ BCM_PACK_U32(buf, var->core_config_arr->dest_port);
++ BCM_PACK_U32(buf, var->core_config_arr->encap_id);
++ }
++ else
++ {
++ BCM_PACK_U32(buf, zero_32);
++ BCM_PACK_U32(buf, zero_32);
++ }
++
+ BCM_PACK_U32(buf, var->core_config_arr_len);
+ BCM_PACK_U32(buf, var->qos_map_id);
+ BCM_PACK_U32(buf, var->tunnel_termination_trap_strength);
+@@ -10005,6 +10028,9 @@
+ uint8 *
+ _bcm_unpack_rx_trap_config(uint8 *buf, bcm_rx_trap_config_t *var)
+ {
++ uint8 var_8, temp;
++ uint32 var_32;
++
+ BCM_UNPACK_U32(buf, var->flags);
+ BCM_UNPACK_U32(buf, var->dest_port);
+ BCM_UNPACK_U32(buf, var->dest_group);
+@@ -10019,12 +10045,40 @@
+ BCM_UNPACK_U32(buf, var->forwarding_type);
+ BCM_UNPACK_U32(buf, var->forwarding_header);
+ BCM_UNPACK_U32(buf, var->encap_id);
+- BCM_UNPACK_U32(buf, var->mirror_cmd->flags);
+- BCM_UNPACK_U8(buf, var->mirror_cmd->forward_strength);
+- BCM_UNPACK_U8(buf, var->mirror_cmd->copy_strength);
+- BCM_UNPACK_U32(buf, var->mirror_cmd->recycle_cmd);
+- BCM_UNPACK_U32(buf, var->core_config_arr->dest_port);
+- BCM_UNPACK_U32(buf, var->core_config_arr->encap_id);
++
++ if(var->mirror_cmd)
++ {
++ BCM_UNPACK_U32(buf, var->mirror_cmd->flags);
++ BCM_UNPACK_U8(buf, var->mirror_cmd->forward_strength);
++ BCM_UNPACK_U8(buf, var->mirror_cmd->copy_strength);
++ BCM_UNPACK_U32(buf, var->mirror_cmd->recycle_cmd);
++ }
++ else
++ {
++ BCM_UNPACK_U32(buf, var_32);
++ BCM_UNPACK_U8(buf, var_8);
++ BCM_UNPACK_U8(buf, var_8);
++ BCM_UNPACK_U32(buf, var_32);
++ /* make compiler happy : unsed-but-set */
++ temp = var_8;
++ var_8 = var_32;
++ var_32 = temp;
++ }
++ if(var->core_config_arr)
++ {
++ BCM_UNPACK_U32(buf, var->core_config_arr->dest_port);
++ BCM_UNPACK_U32(buf, var->core_config_arr->encap_id);
++ }
++ else
++ {
++ BCM_UNPACK_U32(buf, var_32);
++ BCM_UNPACK_U32(buf, var_32);
++ /* make compiler happy : unsed-but-set */
++ temp = var_8;
++ var_8 = var_32;
++ var_32 = temp;
++ }
++
+ BCM_UNPACK_U32(buf, var->core_config_arr_len);
+ BCM_UNPACK_U32(buf, var->qos_map_id);
+ BCM_UNPACK_U32(buf, var->tunnel_termination_trap_strength);
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/server.c sdk-all-6.5.7/src/bcm/rpc/server.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/server.c 2016-12-01 05:17:00.000000000 +0200
++++ sdk-all-6.5.7/src/bcm/rpc/server.c 2017-01-26 12:59:00.779462885 +0200
+@@ -111294,11 +111294,19 @@
+ r_p_config = NULL;
+ } else {
+ r_p_config = &config;
++ bcm_rx_trap_config_t_init(r_p_config);
+ (void) _bcm_unpack_rx_trap_config(r_pp, r_p_config);
+ }
+ bcm_rpc_free(r_pkt, r_cookie);
+
+- r_ret = bcm_rx_trap_set(unit, trap_id, r_p_config);
++ if(r_p_config)
++ {
++ r_ret = bcm_rx_trap_set(unit, trap_id, r_p_config);
++ }
++ else
++ {
++ r_ret = BCM_E_EMPTY;
++ }
+
+ r_pkt = bcm_rpc_setup('S', (uint32 *)0, 4, r_seq, r_ret);
+ r_pp = r_pkt + BCM_RPC_HLEN+4;
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/systems/linux/user/common/socdiag.c sdk-all-6.5.7/systems/linux/user/common/socdiag.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/systems/linux/user/common/socdiag.c 2016-12-01 05:18:40.000000000 +0200
++++ sdk-all-6.5.7/systems/linux/user/common/socdiag.c 2017-01-26 13:02:16.000246446 +0200
+@@ -177,7 +177,11 @@
+ /*
+ * Main loop.
+ */
+-int main(int argc, char *argv[])
++#ifndef BUILD_ING_AS_LIB
++ int main(int argc, char *argv[])
++#else
++ int socdiag_main(int argc, char *argv[])
++#endif
+ {
+ int i, len;
+ char *envstr;
+@@ -260,8 +264,10 @@
+ #endif
+
+ diag_shell();
+-
++
++#ifndef BUILD_ING_AS_LIB
+ linux_bde_destroy(bde);
++#endif
+ #ifdef MEMLOG_SUPPORT
+ if (memlog_lock) {
+ sal_mutex_destroy(memlog_lock);
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/systems/sim/socdiag.c sdk-all-6.5.7/systems/sim/socdiag.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/systems/sim/socdiag.c 2016-12-01 05:18:41.000000000 +0200
++++ sdk-all-6.5.7/systems/sim/socdiag.c 2017-01-26 13:09:21.033560205 +0200
+@@ -31,11 +31,16 @@
+ /*
+ * Main loop.
+ */
+-int main(int argc, char *argv[])
++#ifndef BUILD_ING_AS_LIB
++ int main(int argc, char *argv[])
++#else
++ int socdiag_main(int argc, char *argv[])
++#endif
+ {
+ char *socrc = SOC_INIT_RC;
+ char *config_file = NULL, *config_temp = NULL;
+ int len = 0;
++ FILE *fp;
+
+ if ((config_file = getenv("BCM_CONFIG_FILE")) != NULL) {
+ len = sal_strlen(config_file);
+@@ -56,6 +61,12 @@
+ exit(1);
+ }
+
++ if ((fp = sal_fopen("rc.soc", "r")) != NULL)
++ {
++ setenv("SOC_BOOT_SCRIPT", "rc.soc", 0);
++ sal_fclose(fp);
++ }
++
+ #ifdef DEBUG_STARTUP
+ debugk_select(DEBUG_STARTUP);
+ #endif
+
+diff -Naur /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/rpc.c sdk-all-6.5.7/src/bcm/rpc/rpc.c
+--- /projects/NTSW_SW_PRJS/ExternalReleases/BCM/6.5.7/ga/sdk-all-6.5.7/src/bcm/rpc/rpc.c 2016-11-30 22:17:00.000000000 -0500
++++ sdk-all-6.5.7/src/bcm/rpc/rpc.c 2017-01-27 08:27:37.656186371 -0500
+@@ -268,7 +268,7 @@
+
+ bp = buf;
+ BCM_PACK_U32(bp, seq);
+-
++/*************** IL 2017-01-26 WHY ADD these check?? not in 6.5.6 *********
+ if (!BCM_UNIT_VALID(unit) || (BCM_CONTROL(unit)->drv_control == NULL)) {
+ _bcm_rpc_unlink_request(req);
+ sal_sem_destroy(req->sem);
+@@ -276,7 +276,7 @@
+ sal_free((void *)req);
+ return BCM_E_MEMORY;
+ }
+-
++**************************************************************************/
+ cpu = *(cpudb_key_t *)BCM_CONTROL(unit)->drv_control;
+ #ifdef BCM_RPC_ATP_TX_CALLBACK
+ /*
+
diff --git a/bal_release/3rdparty/bcm-sdk/sh/bal_switch_app.sh b/bal_release/3rdparty/bcm-sdk/sh/bal_switch_app.sh
new file mode 100755
index 0000000..e1461c7
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/sh/bal_switch_app.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+while [[ $# > 1 ]]
+do
+key="$1"
+
+case $key in
+ -Ca)
+ CORE_IPUDP="$2"
+ shift # past argument
+ ;;
+ -S)
+ SWITCH_IPUDP="$2"
+ shift # past argument
+ ;;
+ *)
+ # unknown option
+ echo "Unknown Options - ${key}"
+ ;;
+esac
+shift # past argument or value
+done
+
+
+CORE_IP=${CORE_IPUDP%%:*}
+CORE_UDP=${CORE_IPUDP##*:}
+SWITCH_IP=${SWITCH_IPUDP%%:*}
+SWITCH_UDP=${SWITCH_IPUDP##*:}
+
+cd /opt/bcm56450
+
+if [ ! -z "${SWITCH_IP}" ]; then
+sed -i "s/.*app.ip.*/bal set app.ip ${SWITCH_IP}/" ./bal.soc
+fi
+
+if [ ! -z "${SWITCH_UDP}" ]; then
+sed -i "s/.*app.udp_port.*/bal set app.udp_port ${SWITCH_UDP}/" ./bal.soc
+fi
+
+if [ ! -z "${CORE_IP}" ]; then
+sed -i "s/.*app.peer_ip.*/bal set app.peer_ip ${CORE_IP}/" ./bal.soc
+fi
+
+if [ ! -z "${CORE_UDP}" ]; then
+sed -i "s/.*app.peer_port.*/bal set app.peer_port ${CORE_UDP}/" ./bal.soc
+fi
+
+./kt2_init.sh
+
diff --git a/bal_release/3rdparty/bcm-sdk/sh/kt2_init.sh.svk3 b/bal_release/3rdparty/bcm-sdk/sh/kt2_init.sh.svk3
new file mode 100644
index 0000000..bb0ef4c
--- /dev/null
+++ b/bal_release/3rdparty/bcm-sdk/sh/kt2_init.sh.svk3
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+PCI_KT2_BUS=0000:05:00.0
+
+mknod /dev/linux-user-bde c 126 0
+sleep 1
+
+if [ "$1" == "--setup_only" ]; then
+ exit
+fi
+
+echo "Waiting for KT2 out of reset"
+
+while [ ! -d /sys/bus/pci/devices/$PCI_KT2_BUS ]
+do
+ sleep 1
+done
+
+sleep 1
+
+echo "Start bcm.user ..."
+./bcm.user
diff --git a/bal_release/3rdparty/linenoise b/bal_release/3rdparty/linenoise
new file mode 120000
index 0000000..7b1d087
--- /dev/null
+++ b/bal_release/3rdparty/linenoise
@@ -0,0 +1 @@
+maple/sdk/host_reference/linenoise
\ No newline at end of file
diff --git a/bal_release/3rdparty/maple/Makefile b/bal_release/3rdparty/maple/Makefile
new file mode 100644
index 0000000..4715e92
--- /dev/null
+++ b/bal_release/3rdparty/maple/Makefile
@@ -0,0 +1,45 @@
+# This dummy Makefile doesn't build anything.
+# It just adds paths to Maple SDK header files and libraries
+#
+MOD_NAME = maple_sdk
+MOD_TYPE = lib
+
+MOD_INC_DIRS = $(SRC_DIR)/sdk/host_driver/api
+MOD_INC_DIRS += $(SRC_DIR)/sdk/host_driver/host_api
+
+ifeq ("$(ENABLE_CLI)", "y")
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_customized/embedded_cli
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_customized/os_abstraction/os_cli
+endif
+
+ifneq ("$(BOARD)", "")
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_customized/board/$(BOARD)
+endif
+
+MOD_INC_DIRS += $(SRC_DIR)/sdk/host_driver/transport
+MOD_INC_DIRS += $(SRC_DIR)/sdk/host_driver/model
+MOD_INC_DIRS += $(SRC_DIR)/sdk/host_driver/common_gpon
+MOD_INC_DIRS += $(SRC_DIR)/sdk/host_driver/sw_version
+
+MOD_LIBS = -L$(SRC_DIR)/sdk/build/output
+MOD_LIBS += -lmodel
+MOD_LIBS += -lcommon_api
+MOD_LIBS += -ltransport
+MOD_LIBS += -ldevice_selector
+ifneq ("$(BOARD)", "")
+ MOD_LIBS += -lbcm_board
+endif
+
+ifeq ("$(SIMULATION_BUILD)", "y")
+ MOD_LIBS += -ltr_plugin_udp
+else
+ MOD_LIBS += -ltr_plugin_mux -ltr_plugin_raw -ltr_plugin_raw_ud
+endif
+
+ifeq ("$(ENABLE_CLI)", "y")
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_reference/api_dev_log
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_reference/api_cli
+ MOD_INC_DIRS += $(SRC_DIR)/sdk/host_reference/device_selector
+ MOD_LIBS += -lapi_cli
+ MOD_LIBS += -lapi_dev_log
+endif
diff --git a/bal_release/3rdparty/maple/cur b/bal_release/3rdparty/maple/cur
new file mode 120000
index 0000000..04c86ce
--- /dev/null
+++ b/bal_release/3rdparty/maple/cur
@@ -0,0 +1 @@
+../../../bcm68620_release
\ No newline at end of file
diff --git a/bal_release/COPYRIGHT b/bal_release/COPYRIGHT
new file mode 100644
index 0000000..98c99f9
--- /dev/null
+++ b/bal_release/COPYRIGHT
@@ -0,0 +1,26 @@
+<:copyright-BRCM:2017:DUAL/GPL:standard
+
+ Copyright (c) 2017 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
diff --git a/bal_release/Makefile b/bal_release/Makefile
new file mode 100644
index 0000000..5fa6488
--- /dev/null
+++ b/bal_release/Makefile
@@ -0,0 +1,425 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+# Central Makefile
+#
+
+# Identify whether it is customer or development build
+ifneq ("$(wildcard .release_build)","")
+ RELEASE_BUILD=y
+ export RELEASE_BUILD
+endif
+
+DOCS_SUBSYSTEM := core
+ifeq ("$(BUILD_OF_AGENT)", "y")
+ ifneq ("$(findstring core,$(MAKECMDGOALS))", "")
+ $(error Setting BUILD_OF_AGENT=$(BUILD_OF_AGENT) in incompatible with one of make targets "$(MAKECMDGOALS)"")
+ endif
+ # Backward compatibility
+ ifeq ("$(MAKECMDGOALS)", "clean")
+ OVEERIDE_GOAL = clean_agent
+ endif
+ ifeq ("$(MAKECMDGOALS)", "")
+ OVEERIDE_GOAL = sdn_agent
+ endif
+ DOCS_SUBSYSTEM := agent
+endif
+ifeq ("$(BUILD_OF_AGENT)", "n")
+ ifneq ("$(findstring agent,$(MAKECMDGOALS))", "")
+ $(error Setting BUILD_OF_AGENT=$(BUILD_OF_AGENT) in incompatible with one of make targets "$(MAKECMDGOALS)"")
+ endif
+ # Backward compatibility
+ ifeq ("$(MAKECMDGOALS)", "clean")
+ OVEERIDE_GOAL = clean_core
+ endif
+ ifeq ("$(MAKECMDGOALS)", "")
+ OVEERIDE_GOAL = core
+ endif
+endif
+ifneq ("$(findstring agent,$(MAKECMDGOALS))", "")
+ BUILD_OF_AGENT = y
+endif
+
+BUILD_NC_AGENT ?= y
+
+export BUILD_OF_AGENT
+export BUILD_NC_AGENT
+
+PLATFORM ?= maple
+TOP_DIR=$(shell pwd)
+export PLATFORM
+export TOP_DIR
+
+MAKE_DIR=$(TOP_DIR)/mk
+MAKE_DEVICE_DIR=$(MAKE_DIR)/$(DEVICE)
+export MAKE_DIR
+export MAKE_DEVICE_DIR
+
+TOP_SRC_DIR=$(TOP_DIR)/src
+export TOP_SRC_DIR
+
+include $(MAKE_DIR)/Makefile.initial_config
+include $(TOP_DIR)/branch.info
+
+OUT_DIR ?= $(TOP_DIR)/build
+OUT_DOCS_DIR ?= $(OUT_DIR)/doc
+
+export OUT_DIR
+export OUT_DOCS_DIR
+
+# List of all modules, all library modules and all application modules
+export ALL_MODULES
+export ALL_LIB_MODULES
+export ALL_APP_MODULES
+
+# Current board
+export BOARD
+ifneq ("$(BOARD)", "")
+ BOARD_DIR ?= $(TOP_DIR)/3rdparty/maple/boards/cur/$(BOARD)
+ export BOARD_DIR
+endif
+
+# Location of Maple SDK dir
+MAPLE_SDK_DIR ?= $(TOP_DIR)/3rdparty/maple/cur
+
+LOCAL_MAPLE_SDK_DIR = 3rdparty/maple/sdk
+export MAPLE_SDK_DIR
+export LOCAL_MAPLE_SDK_DIR
+MAPLE_BOARD ?= $(BOARD)
+ifneq ("$(MAPLE_BOARD)", "")
+ MAPLE_BOARD_DIR ?= $(MAPLE_SDK_DIR)/../boards/cur/$(MAPLE_BOARD)
+else
+ MAPLE_BOARD_DIR = $(shell cat $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/.maple_board_dir 2> /dev/null)
+ tmp = $(shell ; rm -f $(OUT_DIR)/.maple_board_dir)
+endif
+
+ING_SDK_VER ?= 6.5.7
+ING_SDK ?= sdk-all-$(ING_SDK_VER)
+ING_SDK_PATCH ?=sdk-bal-$(ING_SDK_VER).patch
+ING_SDK_TOP_DIR ?= $(TOP_DIR)/3rdparty/bcm-sdk
+ifeq ("$(BOARD)", "")
+ ING_SDK_DEFAULT_DIR := $(ING_SDK_TOP_DIR)/build/$(ING_SDK)
+else
+ ING_SDK_DEFAULT_DIR := $(ING_SDK_TOP_DIR)/build-$(BOARD)/$(ING_SDK)
+endif
+ING_SDK_DIR ?= $(ING_SDK_DEFAULT_DIR)
+export ING_SDK_VER
+export ING_SDK
+export ING_SDK_PATCH
+export ING_SDK_TOP_DIR
+export ING_SDK_DIR
+
+SWITCH ?= qax
+export SWITCH
+
+TMP_BAL_VERSION_H=${MAKE_DIR}/bal_version.tmp
+BAL_VERSION_H:=${TOP_DIR}/src/common/include/bal_version.h
+
+# NOTE: BUILD_INFO is set and exported by Jenkins when built by that tool
+export JENKINS_BUILD
+ifeq ("$(JENKINS_BUILD)", "y")
+ PERFORCE_REVISION:=$(P4_CHANGELIST)
+else ifneq ("$(RELEASE_BUILD), "y")
+ PERFORCE_REVISION:=$(shell p4 changes -m 1 //$(DEPOT)/$(BRANCH)/...\#have | cut -d " " -f 2)
+ BUILD_INFO="Developer build \("${USER}"@"${PWD}"\)"
+ export BUILD_INFO
+else
+ BUILD_INFO="Customer Release Build \("${USER}"@"${PWD}"\)"
+ export BUILD_INFO
+endif
+
+
+RELEASE_TYPE:=${RELEASE_TYPE}
+BUILD_USER:=${USER}
+BUILD_TOPDIR:=${TOP_DIR}
+BUILD_PERFORCE_REVISION:=$(PERFORCE_REVISION)
+BUILD_VERSION_PREFIX:=$(RELEASE_TYPE)$(MAJOR).$(MINOR).$(PATCH)
+BUILD_VERSION:=$(BUILD_VERSION_PREFIX).${BUILD_PERFORCE_REVISION}
+BUILD_DATE:=`date +%m-%d-%Y-%H%M%S`
+export BUILD_VERSION
+export BUILD_PERFORCE_REVISION
+export SRC_RELEASE_FILE_PREFIX ?= release.src.$(BUILD_VERSION_PREFIX)
+export INCLUDE_MAPLE_SDK_RELEASE ?= y
+
+V ?= 0
+ifeq (x"$(V)", x"0")
+ SILENT = -s
+ export SILENT
+ SILENT_BUILD=@
+endif
+
+# Include board support file
+# It exports variables such as CROSS_COMPILE
+ifneq ("$(BOARD)", "")
+ -include mk/boards/$(BOARD)/board.config
+endif
+
+ifneq ("$(OVEERIDE_GOAL)", "")
+all: $(OVEERIDE_GOAL)
+else
+all: print_maple_dir core sdn_agent
+endif
+
+clean: clean_core clean_agent clean_ocs_omci
+ $(SILENT_BUILD)rm -fr $(OUT_DIR)
+
+help_general:
+ @echo "make parameters:"
+ @echo " BOARD - board to build for"
+ @echo " BOARD_DIR - board directory"
+ @echo " V=<output_level> - =1-verbose command output, =2-makefile debug output"
+ @echo " EXTRA_TYPES - Low-level option. Space-delimited list of extra types without bcmolt_ prefix"
+ @echo " ENABLE_CLI - =n-exclude CLI support. Included by default"
+ @echo "make targets:"
+ @echo " all - build all subsystems. This is the default target"
+ @echo " core - build core subsystem (BAL standalone)"
+ @echo " sdn_agent - build agent subsystem (BAL SDN agent)"
+ @echo " maple_sdk_dir - create 3rdparty/maple/sdk"
+ @echo " maple_sdk - build maple sdk. Please set BOARD=<board> parameter"
+ @echo " maple_sdk_clean - clean maple sdk"
+ @echo " ing_sdk_dir - create 3rdparty/bcm-sdk/build"
+ @echo " ing_sdk - build 3rdparty/bcm-sdk/build"
+ @echo " ing_sdk_clean - clean 3rdparty/bcm-sdk/build"
+ @echo " ing_bcm_user - build the bcm_user binary (toolchains paths must be set correctly first)"
+ @echo " clean - clean everything"
+ @echo " clean_core - clean core subsystem"
+ @echo " clean_sdn_agent - clean SDN agent"
+ @echo " clean_ocs_omci - clean OCS OMCI stack"
+ @echo " clean_bcm_omci - clean Broadcom OMCI stack"
+ @echo " docs - generate reference document in html format"
+ @echo " docs_pdf - generate reference document in pdf format"
+ @echo " docs_clean - clean documents"
+ @echo " version_file - builds BAL version file"
+ @echo " bin_release_core - create BAL core binary release archive"
+ @echo " bin_release_sdn_agent - create BAL SDN agent binary release archive"
+ @echo " bin_release - create BAL core and SDN agent binary release archives"
+ @echo " src_release - create all BAL source release archives"
+ @echo ""
+ @echo "Optional make arguments:"
+ @echo ""
+ @echo " BUILD_NC_AGENT=n - do NOT build NETCONF agent into bcm_sdn_agent. Used with make target \"sdn_agent\""
+ @echo " TEST_SW_UTIL_LOOPBACK=y - stub out the switch utils"
+ @echo ""
+
+
+help: help_general help_core
+
+.PHONY: version_file
+
+version_file:
+ @echo " Generating $@"
+ @echo "/*************************************************************" > $(TMP_BAL_VERSION_H)
+ @echo " * DO NOT EDIT! THIS FILE WAS AUTO GENERATED. DO NOT EDIT! *" >> $(TMP_BAL_VERSION_H)
+ @echo " *************************************************************/" >> $(TMP_BAL_VERSION_H)
+ @echo " wrote header..."
+ @$(BUILD_TOPDIR)/tools/copyright_tools/insert_copyright.pl -t c -l $(BUILD_TOPDIR)/COPYRIGHT >> $(TMP_BAL_VERSION_H)
+ @echo "#if !defined(BAL_VERSION_H)" >> $(TMP_BAL_VERSION_H)
+ @echo "#define BAL_VERSION_H" >> $(TMP_BAL_VERSION_H)
+ @echo "" >> $(TMP_BAL_VERSION_H)
+ @echo "#define BAL_VERSION \"${BUILD_VERSION}\"" >> $(TMP_BAL_VERSION_H)
+ @echo "#define BAL_VERSION_STR_LEN (`echo ${BUILD_VERSION} | wc -c`)" >> $(TMP_BAL_VERSION_H)
+ @echo "" >> $(TMP_BAL_VERSION_H)
+ @echo "#define BAL_BUILD_DATE \"`date`\"" >> $(TMP_BAL_VERSION_H)
+ @echo "#define BAL_BUILD_INFO \"${BUILD_INFO}\"" >> $(TMP_BAL_VERSION_H)
+ @echo "" >> $(TMP_BAL_VERSION_H)
+ @echo "#endif /* BAL_VERSION_H */" >> $(TMP_BAL_VERSION_H)
+ @diff $(TMP_BAL_VERSION_H) $(BAL_VERSION_H) > /dev/null; \
+ if [ $$? -ne 0 ]; then \
+ mv -f $(TMP_BAL_VERSION_H) $(BAL_VERSION_H); \
+ fi
+
+.PHONY: overlay_bal_maple_scripts
+
+overlay_bal_maple_scripts:
+ @echo "Creating and Overlaying BAL-specific svk_init.sh and trx_init.sh onto maple fs"
+ @echo "(in $(LOCAL_MAPLE_SDK_DIR)/build/fs/)"
+ @cp -f $(LOCAL_MAPLE_SDK_DIR)/host_customized/board/wrx/fs/svk_init.sh ~/svk_init.sh
+ @cat ~/svk_init.sh | sed s/".\/bcm_user_appl"/'.\/bcm_user_appl < trx_init.sh \&\& .\/bcm_user_appl'/g > ~/svk_init_for_bal.sh
+ @cat ~/svk_init.sh | sed s/".\/bcm_user_appl"/'.\/bcm_user_appl < trx_init.sh'/g > ~/svk_init_for_bal_startup.sh
+ @mkdir -p $(LOCAL_MAPLE_SDK_DIR)/build/fs/
+ @mv -f ~/svk_init_for_bal.sh $(LOCAL_MAPLE_SDK_DIR)/build/fs/svk_init.sh
+ @mv -f ~/svk_init_for_bal_startup.sh $(LOCAL_MAPLE_SDK_DIR)/build/fs/svk_init_startup.sh
+ @chmod 755 $(LOCAL_MAPLE_SDK_DIR)/build/fs/svk_init.sh
+ @chmod 755 $(LOCAL_MAPLE_SDK_DIR)/build/fs/svk_init_startup.sh
+ @cp -f $(TOP_DIR)/scripts/trx_init.sh $(LOCAL_MAPLE_SDK_DIR)/build/fs/.
+ @rm ~/svk_init.sh
+
+.PHONY:
+
+.PHONY: sdn_agent
+sdn_agent: version_file build_sdn_agent
+
+.PHONY: build_sdn_agent
+build_sdn_agent: build_agent
+ $(SILENT_BUILD)mv $(TOP_DIR)/build/agent/3rdparty/indigo/ofpal_of_agent $(TOP_DIR)/build/agent/bcm_sdn_agent
+ $(SILENT_BUILD)mk/create_artifacts.sh
+
+.PHONY: ing_bcm_user
+
+ing_bcm_user:
+ @echo "Building ING bcm.user"
+ @pushd 3rdparty/bcm-sdk/build/sdk-all-6.4.4/systems/linux/user/gto-2_6 && make && popd
+
+
+# The following variables are only set if they have not been set
+# previously or passed in.
+
+.PHONY: docs
+docs: docs_$(DOCS_SUBSYSTEM)
+
+docs_pdf: docs_$(DOCS_SUBSYSTEM)
+ $(SILENT_BUILD)$(MAKE) -C $(OUT_DOCS_DIR)/latex
+
+docs_clean:
+ $(SILENT_BUILD)$(BOLD_PRINT) "Cleaning docs"
+ $(SILENT_BUILD)rm -fr $(OUT_DOCS_DIR)
+
+clobber: clean docs_clean
+
+.PHONY: print_maple_dir
+
+print_maple_dir:
+ @echo "Using MAPLE from $(MAPLE_SDK_DIR) copied to $(LOCAL_MAPLE_SDK_DIR)"
+
+core: version_file build_core
+ $(SILENT_BUILD)export BUILD_NC_AGENT=n;\
+ export BUILD_OF_AGENT=n;\
+ mk/create_artifacts.sh
+
+%_core:
+ $(SILENT_BUILD)$(MAKE) $(SILENT) SUBSYSTEM=core -f $(MAKE_DIR)/Makefile.main BUILD_NC_AGENT=n $@
+
+agent: version_file build_agent
+
+%_agent:
+ $(SILENT_BUILD)$(MAKE) $(SILENT) SUBSYSTEM=agent -f $(MAKE_DIR)/Makefile.main $@
+
+.PHONY: bin_release_sdn_agent
+bin_release_sdn_agent: bin_release_agent
+
+.PHONY: bin_release
+bin_release: bin_release_core bin_release_agent
+
+.PHONY: maple_sdk_devel_to_release
+
+maple_sdk_devel_to_release:
+ifneq ("$(RELEASE_BUILD)", "y")
+ $(SILENT_BUILD)if [ ! -f $(MAPLE_SDK_DIR)/build/maple/host/fs/bcm68620_boot.bin ]; then \
+ echo !!! Build maple first;\
+ echo make -C $(MAPLE_SDK_DIR) BOARD=wrx;\
+ exit -1;\
+ fi
+ $(SILENT_BUILD)cd $(MAPLE_SDK_DIR) && rm -fr release && scripts/rel_delivery.sh $(MAPLE_REL_DELIVERY_PREFIX)
+ $(SILENT_BUILD)rm -fr $(LOCAL_MAPLE_SDK_DIR)
+endif
+ $(SILENT_BUILD)mkdir -p $(LOCAL_MAPLE_SDK_DIR)
+ $(SILENT_BUILD)cp -ar $(MAPLE_SDK_DIR)/release/* $(LOCAL_MAPLE_SDK_DIR)/
+ifneq ("$(RELEASE_BUILD)", "y")
+ $(SILENT_BUILD)cp $(MAPLE_SDK_DIR)/make/bcm68620/lint.sh $(LOCAL_MAPLE_SDK_DIR)/make/bcm68620/
+endif
+
+.PHONY: maple_sdk_dir
+maple_sdk_dir: maple_sdk_devel_to_release
+ $(SILENT_BUILD)if [ ! -f $(LOCAL_MAPLE_SDK_DIR)/embedded_binaries/bcm68620_boot.bin ]; then \
+ echo !!! $(LOCAL_MAPLE_SDK_DIR)/embedded_binaries/bcm68620_boot.bin is absent;\
+ echo !!! Please copy BCM68620 SDK release to $(LOCAL_MAPLE_SDK_DIR);\
+ exit -1;\
+ fi
+ $(SILENT_BUILD)mkdir -p src/common/os_abstraction
+ $(SILENT_BUILD)rm -fr src/common/os_abstraction/*
+ $(SILENT_BUILD)cd src/common/os_abstraction && ln -s ../../../$(LOCAL_MAPLE_SDK_DIR)/host_customized/os_abstraction/* .
+ $(SILENT_BUILD)rm -f src/common/os_abstraction/bcmos_platform.h
+
+src_release:
+ $(SILENT_BUILD)$(MAKE_DIR)/src_release.sh
+
+.PHONY: maple_sdk
+maple_sdk: maple_sdk_build overlay_bal_maple_scripts
+
+maple_sdk_build:
+ $(SILENT_BUILD)rm -fr $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/output/*
+ $(SILENT_BUILD)cd $(LOCAL_MAPLE_SDK_DIR) && \
+ unset OUT_DIR && \
+ BOARD=$(MAPLE_BOARD) BOARD_DIR=$(MAPLE_BOARD_DIR) $(MAKE) $(SILENT)
+ifeq ("$(BOARD)", "")
+ $(SILENT_BUILD)mkdir -p $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/output/
+ $(SILENT_BUILD)find $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR) -name 'lib*.a' -exec ln -s \{\} $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/output/ 2> /dev/null \;
+ $(SILENT_BUILD)rm -f $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/.maple_board_dir
+else
+ $(SILENT_BUILD)echo $(MAPLE_BOARD_DIR) > $(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/.maple_board_dir
+endif
+
+maple_sdk_clean:
+ $(SILENT_BUILD)OUT_DIR=$(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build OUT_DIR_BASE=$(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build \
+ BOARD_DIR=$(MAPLE_BOARD_DIR) $(MAKE) $(SILENT) -C $(LOCAL_MAPLE_SDK_DIR) TOP_DIR=$(TOP_DIR)/3rdparty/maple/sdk \
+ BOARD=$(MAPLE_BOARD) clean
+
+ing_sdk_dir:
+ $(SILENT_BUILD)$(ING_SDK_TOP_DIR)/make_ing_dir.sh
+
+ing_sdk:
+ $(SILENT_BUILD)$(MAKE) -C $(ING_SDK_TOP_DIR) -f Makefile.sdk sdk
+
+ing_sdk_clean:
+ifeq ($(ING_SDK_DEFAULT_DIR), $(ING_SDK_DIR))
+ $(SILENT_BUILD)rm -fr $(ING_SDK_DIR)
+else
+ $(SILENT_BUILD)$(MAKE) -C $(ING_SDK_DIR) clean
+endif
+
+clean_ocs_omci:
+ $(SILENT_BUILD)$(MAKE) -C $(TOP_DIR)/3rdparty/ocs_omci clean
+
+#clean_bcm_omci:
+# $(SILENT_BUILD)$(MAKE) -C $(TOP_DIR)/3rdparty/ocs_omci clean
+
+.PHONY: clean_sdn_agent
+clean_sdn_agent: clean_agent
+
+print-% : ; @echo $* = $($*)
+
diff --git a/bal_release/README_HOW_TO_BUILD_BAL b/bal_release/README_HOW_TO_BUILD_BAL
new file mode 100644
index 0000000..d93ecf2
--- /dev/null
+++ b/bal_release/README_HOW_TO_BUILD_BAL
@@ -0,0 +1,39 @@
+This file contains instructions of how to extract BAL source release package and compile it.
+It is assumed that switch (Qumran) SDK is obtained from its relevant repository and it is not part of BAL source release package.
+
+Here are the steps needed to extract and compile the source code:
+
+1. Create a directory into which you want to extract the package. In the following steps we use /tmp/bal_src_release as an example.
+
+ mkdir -p /tmp/bal_src_release
+
+2. Unzip (extract) the combined Maple SDK and BAL package into the location you selected:
+
+ unzip <path_to_release_zip>/SW-BCM68620_<revision>.zip -d /tmp/bal_src_release
+
+3. Obtain switch (Qumran) SDK from its repository.
+
+4. Copy switch (Qumran) SDK to /tmp/bal_src_release/bal_release/3rdparty/bcm-sdk.
+
+ cp /<path_to_switch_sdk>/sdk-all-<revision>.tar.gz /tmp/bal_src_release/bal_release/3rdparty/bcm-sdk
+
+5. Change directory to the selected location.
+
+ cd /tmp/bal_src_release/bal_release
+
+6. Compile Maple SDK
+
+ make maple_sdk_dir
+ make maple_sdk
+
+7. Compile switch (Qumran) SDK
+
+ make ing_sdk_dir
+ make ing_sdk
+
+8. Compile BAL:
+
+ make core
+
+9. When the build ends successfully, bal_core executable (build/core/src/core/main/bal_core) should be created.
+
diff --git a/bal_release/README_HOW_TO_BUILD_SDN_PAL b/bal_release/README_HOW_TO_BUILD_SDN_PAL
new file mode 100644
index 0000000..08bf6dd
--- /dev/null
+++ b/bal_release/README_HOW_TO_BUILD_SDN_PAL
@@ -0,0 +1,47 @@
+This file contains instructions of how to extract BAL/SDN-PAL source release packages and compile them.
+It is assumed that switch (Qumran) SDK is obtained from its relevant repository and it is not part of SDN-PAL source release package.
+
+Here are the steps needed to extract and compile the source code:
+
+1. Create a directory into which you want to extract the package. In the following steps we use /tmp/bal_src_release as an example.
+
+ mkdir -p /tmp/bal_src_release
+
+2. Unzip (extract) the combined Maple SDK and BAL package into the location you selected:
+
+ unzip <path_to_release_zip>/SW-BCM68620_<revision>.zip -d /tmp/bal_src_release
+
+3. Extract SDN-PAL:
+
+ tar --strip-components=1 -C /tmp/bal_src_release/bal_release -xvzf <path_to_sdn_pal_tarball>/sdn_pal.<suffix>.tar.gz
+
+4. In case OMCI is also required, you should extract OMCI:
+
+ tar --strip-components=1 -C /tmp/bal_src_release/bal_release -xvzf <path_to_omci_tarball>/omci.<suffix>.tar.gz
+
+5. Obtain switch (Qumran) SDK from its repository.
+
+6. Copy switch (Qumran) SDK to /tmp/bal_src_release/bal_release/3rdparty/bcm-sdk.
+
+ cp /<path_to_switch_sdk>/sdk-all-<revision>.tar.gz /tmp/bal_src_release/bal_release/3rdparty/bcm-sdk
+
+7. Change directory to the selected location.
+
+ cd /tmp/bal_src_release/bal_release
+
+8. Compile Maple SDK
+
+ make maple_sdk_dir
+ make maple_sdk
+
+9. Compile switch (Qumran) SDK
+
+ make ing_sdk_dir
+ make ing_sdk
+
+10. Compile SDN-PAL:
+
+ make sdn_agent
+
+11. When the build ends successfully, bal_core executable (build/core/src/core/main/bal_core) and SDN agent executable (build/agent/bcm_sdn_agent) should be created.
+
diff --git a/bal_release/branch.info b/bal_release/branch.info
new file mode 100644
index 0000000..49e8f18
--- /dev/null
+++ b/bal_release/branch.info
@@ -0,0 +1,58 @@
+###############################################################################
+#
+# Copyright 2008-2017 Broadcom Corporation
+#
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified or
+# distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom (an
+# "Authorized License"). Except as set forth in an Authorized License,
+# Broadcom grants no license (express or implied), right to use, or
+# waiver of any kind with respect to the Software, and Broadcom
+# expressly reserves all rights in and to the Software and all
+# intellectual property rights therein. IF YOU HAVE NO AUTHORIZED
+# LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND
+# SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE
+# SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+# "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+# OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+# OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+# OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
+# RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
+# BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+# ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
+# ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+# NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
+# REMEDY.
+#
+###############################################################################
+#
+# This is the release information for "current" branch.
+#
+###############################################################################
+
+DEPOT=xpon_co
+BRANCH=bal/cur
+RELEASE_TYPE=R
+MAJOR=02
+MINOR=02
+PATCH=01
+PERFORCE_REVISION=139177
diff --git a/bal_release/doxygen/DoxygenLayout.xml b/bal_release/doxygen/DoxygenLayout.xml
new file mode 100644
index 0000000..a4ad5bb
--- /dev/null
+++ b/bal_release/doxygen/DoxygenLayout.xml
@@ -0,0 +1,188 @@
+<doxygenlayout version="1.0">
+ <!-- Generated by doxygen 1.8.6 -->
+ <!-- Navigation index tabs for HTML output -->
+ <navindex>
+ <tab type="mainpage" visible="yes" title=""/>
+ <tab type="pages" visible="yes" title="" intro=""/>
+ <tab type="modules" visible="yes" title="API Reference" intro=""/>
+ <tab type="namespaces" visible="yes" title="">
+ <tab type="namespacelist" visible="yes" title="" intro=""/>
+ <tab type="namespacemembers" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="classes" visible="no" title="">
+ <tab type="classlist" visible="no" title="" intro=""/>
+ <tab type="classindex" visible="no" title=""/>
+ <tab type="hierarchy" visible="no" title="" intro=""/>
+ <tab type="classmembers" visible="no" title="" intro=""/>
+ </tab>
+ <tab type="files" visible="no" title="">
+ <tab type="filelist" visible="yes" title="" intro=""/>
+ <tab type="globals" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="examples" visible="yes" title="" intro=""/>
+ </navindex>
+
+ <!-- Layout definition for a class page -->
+ <class>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <inheritancegraph visible="$CLASS_GRAPH"/>
+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+ <memberdecl>
+ <nestedclasses visible="yes" title=""/>
+ <publictypes title=""/>
+ <publicslots title=""/>
+ <signals title=""/>
+ <publicmethods title=""/>
+ <publicstaticmethods title=""/>
+ <publicattributes title=""/>
+ <publicstaticattributes title=""/>
+ <protectedtypes title=""/>
+ <protectedslots title=""/>
+ <protectedmethods title=""/>
+ <protectedstaticmethods title=""/>
+ <protectedattributes title=""/>
+ <protectedstaticattributes title=""/>
+ <packagetypes title=""/>
+ <packagemethods title=""/>
+ <packagestaticmethods title=""/>
+ <packageattributes title=""/>
+ <packagestaticattributes title=""/>
+ <properties title=""/>
+ <events title=""/>
+ <privatetypes title=""/>
+ <privateslots title=""/>
+ <privatemethods title=""/>
+ <privatestaticmethods title=""/>
+ <privateattributes title=""/>
+ <privatestaticattributes title=""/>
+ <friends title=""/>
+ <related title="" subtitle=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <memberdef>
+ <inlineclasses title=""/>
+ <functions title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <constructors title=""/>
+ <related title=""/>
+ <variables title=""/>
+ <properties title=""/>
+ <events title=""/>
+ </memberdef>
+ <allmemberslink visible="no"/>
+ <usedfiles visible="$SHOW_USED_FILES"/>
+ <authorsection visible="yes"/>
+ </class>
+
+ <!-- Layout definition for a namespace page -->
+ <namespace>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <memberdecl>
+ <nestednamespaces visible="yes" title=""/>
+ <functions title=""/>
+ <classes visible="yes" title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <memberdef>
+ <inlineclasses title=""/>
+ <functions title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </namespace>
+
+ <!-- Layout definition for a file page -->
+ <file>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <includegraph visible="$INCLUDE_GRAPH"/>
+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+ <sourcelink visible="yes"/>
+ <memberdecl>
+ <functions title=""/>
+ <classes visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <memberdef>
+ <inlineclasses title=""/>
+ <functions title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection/>
+ </file>
+
+ <!-- Layout definition for a group page -->
+ <group>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <groupgraph visible="$GROUP_GRAPHS"/>
+ <memberdecl>
+ <nestedgroups visible="yes" title=""/>
+ <functions title=""/>
+ <dirs visible="yes" title=""/>
+ <files visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+ <classes visible="yes" title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <enumvalues title=""/>
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <memberdef>
+ <pagedocs/>
+ <functions title=""/>
+ <inlineclasses title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <enumvalues title=""/>
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </group>
+
+ <!-- Layout definition for a directory page -->
+ <directory>
+ <briefdescription visible="yes"/>
+ <detaileddescription title=""/>
+ <directorygraph visible="yes"/>
+ <memberdecl>
+ <dirs visible="yes"/>
+ <files visible="yes"/>
+ </memberdecl>
+ </directory>
+</doxygenlayout>
diff --git a/bal_release/doxygen/Makefile b/bal_release/doxygen/Makefile
new file mode 100644
index 0000000..0ef21da
--- /dev/null
+++ b/bal_release/doxygen/Makefile
@@ -0,0 +1,94 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+#
+# Makefile for building doxygen for bal source code
+#
+###############################################################################
+
+PROJECT_NUMBER=$(shell ./genProjectNumber.sh)
+TMP_FILE=cfg.tmp
+OUTPUT_FILE=doxygen_output.txt
+WARNINGS_FILE=doxygen_warnings.txt
+
+GEN_GRAPHS ?= NO
+
+.PHONY: docs
+docs:
+ @if [ "$(GEN_GRAPHS)" != "YES" ]; then \
+ echo "#####################################################################" ; \
+ echo "# Graphs will NOT be generated #" ; \
+ echo "# Type 'make GEN_GRAPHS=YES' to instruct doxygen to generate graphs #" ; \
+ echo "#####################################################################" ; \
+ sleep 3 ; \
+ fi
+ $(call gen_doc_cmd,$(OUT_DOCS_DIR)/bal_internal,bal.doxy)
+ $(call gen_doc_cmd,$(OUT_DOCS_DIR)/bal_public,bal_public.doxy)
+ $(call gen_doc_cmd,$(OUT_DOCS_DIR)/sdn_pal,sdn_pal.doxy)
+ $(call gen_doc_cmd,$(OUT_DOCS_DIR)/omcisvc,omcisvc.doxy)
+
+define gen_doc_cmd
+ rm -fr $1
+ mkdir -p $1
+ sed -e 's@%OUT_DOCS_DIR@$1@g' \
+ -e 's@%SRC_DIR@$(TOP_SRC_DIR)@g' \
+ -e 's@%PROJECT_NUMBER@$(PROJECT_NUMBER)@g' \
+ -e 's@%HAVE_DOT@$(GEN_GRAPHS)@g' \
+ -e 's@%MODEL_DIR@$(OUT_DIR_BASE)/src/common/include@g' \
+ -e 's@%OMCI_MODEL_DIR@$(OUT_DIR_BASE)/src/lib/libomcisvc@g' \
+ $2 > $1/Doxyfile
+ rm -fr $1/$(OUTPUT_FILE) $1/$(WARNINGS_FILE)
+ cd $1 && doxygen 2>$1/$(WARNINGS_FILE) | tee $1/$(OUTPUT_FILE)
+ @echo ""
+ @echo "############################################"
+ @echo "# Checking doxygen output for warnings... #"
+ @echo "############################################"
+ @cat $1/$(WARNINGS_FILE)
+ @test -s $1/$(WARNINGS_FILE) && echo -ne "\n!!! WARNINGS WERE FOUND!!!\n\nPlease see warnings listed above and check $1/$(WARNINGS_FILE) for more information\n\n" && exit -1 || echo "Done."
+ rm -fr $1/$(OUTPUT_FILE) $1/$(WARNINGS_FILE) $1/Doxyfile
+endef
diff --git a/bal_release/doxygen/bal.doxy b/bal_release/doxygen/bal.doxy
new file mode 100644
index 0000000..7b4e8ca
--- /dev/null
+++ b/bal_release/doxygen/bal.doxy
@@ -0,0 +1,1841 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "Broadband Adaption Layer"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = %PROJECT_NUMBER
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO = "%SRC_DIR/../doxygen/broadcom.png"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = %OUT_DOCS_DIR
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = "TABLE_HDR2{2}=<tr><th>\1</th><th>\2</th></tr>" \
+ "TABLE_ROW2{2}=<tr><td>\1</td><td>\2</td></tr>" \
+ "TABLE_HDR3{3}=<tr><th>\1</th><th>\2</th><th>\3</th></tr>" \
+ "TABLE_ROW3{3}=<tr><td>\1</td><td>\2</td><td>\3</td></tr>" \
+ "TABLE_HDR4{4}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th></tr>" \
+ "TABLE_ROW4{4}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td></tr>" \
+ "TABLE_HDR5{5}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th></tr>" \
+ "TABLE_ROW5{5}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td></tr>" \
+ "TABLE_HDR6{6}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th></tr>" \
+ "TABLE_ROW6{6}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td></tr>" \
+ "TABLE_HDR7{7}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th><th>\7</th></tr>" \
+ "TABLE_ROW7{7}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td><td>\7</td></tr>"
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = %SRC_DIR/../doxygen/DoxygenLayout.xml
+
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = %SRC_DIR/lib/libbalapi/bal_api.dox \
+ %MODEL_DIR/model.dox \
+ %SRC_DIR/lib/libbalapi/bal_api.h \
+ %SRC_DIR/lib/libbalapi/bal_api.c \
+ %MODEL_DIR/bal_model_ids.h \
+ %MODEL_DIR/bal_model_types.h \
+ %SRC_DIR
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c *.h *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = %SRC_DIR/common/os_abstraction \
+ %SRC_DIR/common/db_engine \
+ %SRC_DIR/common/cli \
+ %SRC_DIR/common/dev_log \
+ %SRC_DIR/common/utils \
+ %SRC_DIR/common/config \
+ %SRC_DIR/core/util/oam/epon_oam_cli \
+ %SRC_DIR/core/util/oam/epon_oam \
+ %SRC_DIR/core/util/oam/common_epon_oam \
+ %SRC_DIR/core/util/oam/eon \
+ %SRC_DIR/common/model \
+ %SRC_DIR/lib/libomcisvc \
+ %SRC_DIR/lib/libomcistack \
+ %SRC_DIR/ofpal/loci
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */test/* \
+ *Examples*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER = %SRC_DIR/../doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = %SRC_DIR/../doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = www.broadcom.com
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = www.broadcom.com
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Broadcom Limited
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = __attribute__(x)= \
+ __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = %HAVE_DOT
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 200
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/bal_release/doxygen/bal_public.doxy b/bal_release/doxygen/bal_public.doxy
new file mode 100644
index 0000000..8fbe34e
--- /dev/null
+++ b/bal_release/doxygen/bal_public.doxy
@@ -0,0 +1,1828 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "Broadband Adaption Layer"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = %PROJECT_NUMBER
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO = "%SRC_DIR/../doxygen/broadcom.png"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = %OUT_DOCS_DIR
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = "TABLE_HDR2{2}=<tr><th>\1</th><th>\2</th></tr>" \
+ "TABLE_ROW2{2}=<tr><td>\1</td><td>\2</td></tr>" \
+ "TABLE_HDR3{3}=<tr><th>\1</th><th>\2</th><th>\3</th></tr>" \
+ "TABLE_ROW3{3}=<tr><td>\1</td><td>\2</td><td>\3</td></tr>" \
+ "TABLE_HDR4{4}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th></tr>" \
+ "TABLE_ROW4{4}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td></tr>" \
+ "TABLE_HDR5{5}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th></tr>" \
+ "TABLE_ROW5{5}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td></tr>" \
+ "TABLE_HDR6{6}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th></tr>" \
+ "TABLE_ROW6{6}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td></tr>" \
+ "TABLE_HDR7{7}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th><th>\7</th></tr>" \
+ "TABLE_ROW7{7}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td><td>\7</td></tr>"
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = %SRC_DIR/../doxygen/DoxygenLayout.xml
+
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = %SRC_DIR/lib/libbalapi/bal_api.dox \
+ %SRC_DIR/lib/libbalapi/bal_api.h \
+ %MODEL_DIR/model.dox \
+ %SRC_DIR/common/include/bal_obj.h \
+ %SRC_DIR/common/include/bal_objs.h \
+ %MODEL_DIR/bal_model_ids.h \
+ %MODEL_DIR/bal_model_types.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c *.h *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */test/* \
+ *Examples*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER = %SRC_DIR/../doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = %SRC_DIR/../doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = www.broadcom.com
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = www.broadcom.com
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Broadcom Limited
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = __attribute__(x)= \
+ __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = NO
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = %HAVE_DOT
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 200
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/bal_release/doxygen/broadcom.png b/bal_release/doxygen/broadcom.png
new file mode 100644
index 0000000..1c7480c
--- /dev/null
+++ b/bal_release/doxygen/broadcom.png
Binary files differ
diff --git a/bal_release/doxygen/footer.html b/bal_release/doxygen/footer.html
new file mode 100644
index 0000000..c01529b
--- /dev/null
+++ b/bal_release/doxygen/footer.html
@@ -0,0 +1,21 @@
+<!-- HTML footer for doxygen 1.8.3.1-->
+<!-- start footer part -->
+<!--BEGIN GENERATE_TREEVIEW-->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ $navpath
+ <li class="footer">
+ <a href="http://www.broadcom.com">
+ <img class="footer" alt="BAL: Broadcom Adaptation Layer"/></a> $projectnumber </li>
+ </ul>
+</div>
+<!--END GENERATE_TREEVIEW-->
+<!--BEGIN !GENERATE_TREEVIEW-->
+<hr class="footer"/><address class="footer"><small>
+$generatedby  <a href="http://www.broadcom.com">
+<img class="footer" alt="BAL Object Model"/>
+</a> $projectnumber
+</small></address>
+<!--END !GENERATE_TREEVIEW-->
+</body>
+</html>
diff --git a/bal_release/doxygen/genProjectNumber.sh b/bal_release/doxygen/genProjectNumber.sh
new file mode 100755
index 0000000..93b24ce
--- /dev/null
+++ b/bal_release/doxygen/genProjectNumber.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+
+#Get the absolute path of version file.
+#
+#!!! This script MUST be put in bal/cur/doxygen directory !!!
+#
+PROJROOT=$PWD/..
+BRANCH_INFO=${PROJROOT}/branch.info
+if [ ! -f ${BRANCH_INFO} ]; then
+ echo "Unknown"
+ exit
+fi
+
+RELEASE_TYPE=`cat ${BRANCH_INFO} | grep RELEASE_TYPE | sed 's%.*=%%'`
+MAJOR=`cat ${BRANCH_INFO} | grep MAJOR | sed 's%.*=%%'`
+MINOR=`cat ${BRANCH_INFO} | grep MINOR | sed 's%.*=%%'`
+PATCH=`cat ${BRANCH_INFO} | grep PATCH | sed 's%.*=%%'`
+
+echo ${RELEASE_TYPE}${MAJOR}.${MINOR}.${PATCH}
diff --git a/bal_release/doxygen/header.html b/bal_release/doxygen/header.html
new file mode 100644
index 0000000..2d397b5
--- /dev/null
+++ b/bal_release/doxygen/header.html
@@ -0,0 +1,55 @@
+<!-- HTML header for doxygen 1.8.3.1-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Broadcom Limited"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <!--BEGIN PROJECT_LOGO-->
+ <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
+ <!--END PROJECT_LOGO-->
+ <!--BEGIN PROJECT_NAME-->
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">$projectname
+ <!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
+ </div>
+ <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
+ </td>
+ <!--END PROJECT_NAME-->
+ <!--BEGIN !PROJECT_NAME-->
+ <!--BEGIN PROJECT_BRIEF-->
+ <td style="padding-left: 0.5em;">
+ <div id="projectbrief">$projectbrief</div>
+ </td>
+ <!--END PROJECT_BRIEF-->
+ <!--END !PROJECT_NAME-->
+ <!--BEGIN DISABLE_INDEX-->
+ <!--BEGIN SEARCHENGINE-->
+ <td>$searchbox</td>
+ <!--END SEARCHENGINE-->
+ <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/bal_release/doxygen/omcisvc.doxy b/bal_release/doxygen/omcisvc.doxy
new file mode 100644
index 0000000..7e0eeb1
--- /dev/null
+++ b/bal_release/doxygen/omcisvc.doxy
@@ -0,0 +1,1839 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "Broadcom OMCI Service Layer"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = %PROJECT_NUMBER
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO = "%SRC_DIR/../doxygen/broadcom.png"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = %OUT_DOCS_DIR
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = "TABLE_HDR2{2}=<tr><th>\1</th><th>\2</th></tr>" \
+ "TABLE_ROW2{2}=<tr><td>\1</td><td>\2</td></tr>" \
+ "TABLE_HDR3{3}=<tr><th>\1</th><th>\2</th><th>\3</th></tr>" \
+ "TABLE_ROW3{3}=<tr><td>\1</td><td>\2</td><td>\3</td></tr>" \
+ "TABLE_HDR4{4}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th></tr>" \
+ "TABLE_ROW4{4}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td></tr>" \
+ "TABLE_HDR5{5}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th></tr>" \
+ "TABLE_ROW5{5}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td></tr>" \
+ "TABLE_HDR6{6}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th></tr>" \
+ "TABLE_ROW6{6}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td></tr>" \
+ "TABLE_HDR7{7}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th><th>\7</th></tr>" \
+ "TABLE_ROW7{7}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td><td>\7</td></tr>"
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = %SRC_DIR/../doxygen/DoxygenLayout.xml
+
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = %SRC_DIR/lib/libomcisvc/omci_svc_api.dox \
+ %OMCI_MODEL_DIR/omci_model.dox \
+ %SRC_DIR/lib/libomcisvc/omci_svc.h \
+ %SRC_DIR/lib/libomcisvc/omci_svc_sub_term.h \
+ %SRC_DIR/lib/libomcisvc/omci_svc_flow.h \
+ %OMCI_MODEL_DIR/omci_model_ids.h \
+ %OMCI_MODEL_DIR/omci_model_types.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c *.h *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = %SRC_DIR/common/os_abstraction \
+ %SRC_DIR/common/db_engine \
+ %SRC_DIR/common/cli \
+ %SRC_DIR/common/dev_log \
+ %SRC_DIR/common/utils \
+ %SRC_DIR/common/config \
+ %SRC_DIR/core/util/oam/epon_oam_cli \
+ %SRC_DIR/core/util/oam/epon_oam \
+ %SRC_DIR/core/util/oam/common_epon_oam \
+ %SRC_DIR/core/util/oam/eon \
+ %SRC_DIR/common/model \
+ %SRC_DIR/ofpal/loci
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */test/* \
+ *Examples*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER = %SRC_DIR/../doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = %SRC_DIR/../doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = www.broadcom.com
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = www.broadcom.com
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Broadcom Limited
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = __attribute__(x)= \
+ __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = %HAVE_DOT
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 200
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/bal_release/doxygen/omcisvc/omcisvc.dox b/bal_release/doxygen/omcisvc/omcisvc.dox
new file mode 100644
index 0000000..7e28611
--- /dev/null
+++ b/bal_release/doxygen/omcisvc/omcisvc.dox
@@ -0,0 +1,17 @@
+/*
+ * OLayer Software Developer's Guide - main page
+ */
+
+/** \mainpage OMCI Service Layer Software Deveoper's Guide
+
+\section intro Introduction
+OMCI Service Layer and OMCI atack is BAL / SDN-PAL add-on package. It is designed for managing xPON ONUs using service-oriented requests.
+OMCI Service Layer performs the following functions:
+- Converts service oriented requests into OMCI ME requests
+- Applies OMCI MEs in the correct order using built-in FSMs
+- Handles ONU activation and MIB upload. Identifies ONU type based on the OMCI MIB upload results
+*/
+
+/** \page omcisvc_api OMCI Service Layer API
+ See \ref omcisvc_api in API Reference chapter
+*/
diff --git a/bal_release/doxygen/sdn_pal.doxy b/bal_release/doxygen/sdn_pal.doxy
new file mode 100644
index 0000000..d31e25d
--- /dev/null
+++ b/bal_release/doxygen/sdn_pal.doxy
@@ -0,0 +1,1833 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "SDN PAL - SDN PON Adaptation Layer"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = %PROJECT_NUMBER
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO = "%SRC_DIR/../doxygen/broadcom.png"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = %OUT_DOCS_DIR
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = "TABLE_HDR2{2}=<tr><th>\1</th><th>\2</th></tr>" \
+ "TABLE_ROW2{2}=<tr><td>\1</td><td>\2</td></tr>" \
+ "TABLE_HDR3{3}=<tr><th>\1</th><th>\2</th><th>\3</th></tr>" \
+ "TABLE_ROW3{3}=<tr><td>\1</td><td>\2</td><td>\3</td></tr>" \
+ "TABLE_HDR4{4}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th></tr>" \
+ "TABLE_ROW4{4}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td></tr>" \
+ "TABLE_HDR5{5}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th></tr>" \
+ "TABLE_ROW5{5}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td></tr>" \
+ "TABLE_HDR6{6}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th></tr>" \
+ "TABLE_ROW6{6}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td></tr>" \
+ "TABLE_HDR7{7}=<tr><th>\1</th><th>\2</th><th>\3</th><th>\4</th><th>\5</th><th>\6</th><th>\7</th></tr>" \
+ "TABLE_ROW7{7}=<tr><td>\1</td><td>\2</td><td>\3</td><td>\4</td><td>\5</td><td>\6</td><td>\7</td></tr>"
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = %SRC_DIR/../doxygen/DoxygenLayout.xml
+
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = %SRC_DIR/../doxygen/sdn_pal/sdn_pal.dox \
+ %SRC_DIR/ofpal/ofpal.h \
+ %SRC_DIR/ofpal/ofpal_constants.h \
+ %SRC_DIR/ofpal/ofpal_table.h \
+ %SRC_DIR/ofpal/ofpal_flow.h \
+ %SRC_DIR/ofpal/ofpal_group.h \
+ %SRC_DIR/ofpal/ofpal_packet.h \
+ %SRC_DIR/ofpal/ofpal_meter.h \
+ %SRC_DIR/ofpal/ofpal_port.h \
+ %SRC_DIR/ofpal/ofpal_barrier.h \
+ %SRC_DIR/ofpal/ofpal_custom.h \
+ %SRC_DIR/ofpal/ofpal_netconf.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c *.h *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */test/* \
+ *Examples*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = %SRC_DIR/../doxygen/sdn_pal
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER = %SRC_DIR/../doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = %SRC_DIR/../doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "SDN PAL Software Developer's Guide"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = www.broadcom.com
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = www.broadcom.com
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Broadcom Limited
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+#XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = __attribute__(x)= \
+ __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = %HAVE_DOT
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 200
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/bal_release/doxygen/sdn_pal/sdn_pal.dox b/bal_release/doxygen/sdn_pal/sdn_pal.dox
new file mode 100644
index 0000000..1fb72ba
--- /dev/null
+++ b/bal_release/doxygen/sdn_pal/sdn_pal.dox
@@ -0,0 +1,29 @@
+/*
+ * SDN-PAL Software Developer's Guide - main page
+ */
+
+/** \mainpage SDN-PAL Software Deveoper's Guide
+
+\section intro Introduction
+SDN PAL is BAL add-on package. It is designed for managing xPON OLT virtual switch (xPON vOLT) using OpenFlow and/or NETCONF protocols.
+The xPON vOLT consists of xPON line card and subtending ONUs.
+SDN PAL acts as an intermediate layer between OpenFlow and NETCONF agents and the
+s/w stacks managing the line card and ONUs.
+ - xPON line card is managed by BAL
+ - xPON ONUs are managed by OMCI Service Layer
+
+SDN-PAL consists of 2 main components:
+ - OF-PAL - OpenFlow PON Adaptation Layer. It is an SDK intended for integration with OpenFlow agent.
+ - SDN-PAL SDK uses data types generated by loxygen code generator for C (loci). See https://github.com/floodlight/loxigen for details.
+ - SDN-PAL SDK includes a reference integration with indogo OF agent. See http://www.projectfloodlight.org/indigo for details.
+ - xpon-volt.yang model - Yang model for managing xPON vOLT using NETCONF protocol.
+ - This module is implemented as a plugin for open-source libnetconf SDK. See https://github.com/CESNET/libnetconf for details.
+*/
+
+/** \page ofpal_api OF-PAL Public API
+ See \ref ofpal_api in API Reference chapter
+*/
+
+/** \page xpon_volt_yang xpon-volt Yang Model
+ \image html xpon-volt.png
+*/
diff --git a/bal_release/doxygen/sdn_pal/xpon-volt.png b/bal_release/doxygen/sdn_pal/xpon-volt.png
new file mode 100644
index 0000000..2decb53
--- /dev/null
+++ b/bal_release/doxygen/sdn_pal/xpon-volt.png
Binary files differ
diff --git a/bal_release/mk/Makefile.config b/bal_release/mk/Makefile.config
new file mode 100644
index 0000000..169a649
--- /dev/null
+++ b/bal_release/mk/Makefile.config
@@ -0,0 +1,439 @@
+# Common Makefile configuration
+#
+
+# The following variables must be set
+# MOD_NAME - module name. Depending on MOD_TYPE can be encapsulated (e.g., MOD_NAME=os --> libos.a)
+# MOD_TYPE - module type. Supported types currently are "lib", "app", "linux_module", "linux_lib", "shared_lib"
+# Note:
+# For library module it is possible to specify "unitest" target in
+# mk/$(SUBSYSTEM)/modules.core / .apps
+# In this case unitest.c is compiled and linked with its module library.
+# However, MOD_TYPE remains a "lib".
+#
+# The following variables are optional
+# srcs - list of .c source files relative to SRC_DIR
+# as_srcs - list of .s (lower case s) source files relative to SRC_DIR
+# AS_srcs - list of .S (upper case .S) source files relative to SRC_DIR
+# gen_bal_srcs - list of .c that have to be generated as part of the build from bal.objset
+# gen_bal_hdrs - list of .h that have to be generated as part of the build from bal.objset
+# gen_omci_srcs - list of .c that have to be generated as part of the build from omci.objset
+# gen_omci_hdrs - list of .h that have to be generated as part of the build from omci.objset
+# gen_omci_stack_srcs - list of .c that have to be generated as part of the build from omci_me_datamodel.csv
+# gen_omci_stack_hdrs - list of .h that have to be generated as part of the build from omci_me_datamodel.csv
+# MOD_DEPS - list of modules the "current" module depends on. OS abstraction layer dependency
+# (module "os") is always present implicitly. For example, api_cli module's Makefile
+# includes the following line:
+# MOD_DEPS = cli api utils model
+# MOD_DEPS_OPT - similar to MOD_DEPS, but dependencies are optional and might not be present in the source tree.
+# MOD_INC_DIRS - used when module exports includes in directory(s) other than the module directory
+# MOD_DEFS - additional defines, including -D. the defines are added when compiling "this" module
+# and all modules depending on it
+# MOD_LIBS - additional libraries required by the module, including -l and -L
+# MOD_CUSTOM - if set "y", default rule for building the module is NOT provided.
+# In this case the rule for building $(MOD_TARGET) must be provided in module's Makefile
+# MOD_POST_BUILD - optional commands that should be executed after successful module build
+#
+# The following variables are not required in most cases, but supported nonetheless
+# EXTRA_CFLAGS - extra CFLAGS the module requires for compilation
+# EXTRA_INCLUDES - extra include directories the module requires for compilation (with -I)
+# EXTRA_LIBS_PATH - additional library search paths
+# EXTRA_LIBS additional libraries to link with
+#
+# The following variables are pre-set and can be used in module-specific Makefile
+# TOP_DIR - fully qualified top directory
+# MOD_DIR - module directory relative to the top directory
+# OUT_DIR_BASE - output directory base
+# ALL_MODULES - list of all modules in the current subsystem (core/apps)
+# ALL_LIB_MODULES - list of all lib modules in the current subsystem (core/apps)
+# ALL_APP_MODULES - list of all app modules in the current subsystem (core/apps)
+# SIMULATION_BUILD - set "y" for simulation build (CROSS_COMPILE is empty)
+# OS - OS
+# ENABLE_EPON - set "y" if EPON mode is included
+# ENABLE_GPON - set "y" if GPON mode is included
+# ENABLE_XGPON - set "y" if XGPON mode is included
+# ENABLE_GPON_OR_XGPON - set "y" if GPON or XGPON mode is included
+# ENABLE_CLI - set "n" if CLI support is not required
+# ENABLE_LOG - set "n" if logger support is not required
+#
+# USE_CLANG - set "y" to enable CLANG code pass for improved diagnostic
+#
+# The following variables are pre-set and can be used and/or overwritten in module-specific Makefile
+# SRC_DIR - fully-qualified source directory
+# OUT_DIR - module output directory
+# TARGET_LIB - library name for "lib" or "shared_lib" module. By default it is $(MOD_NAME)
+# TARGET_LIB_FNAME - module library file name including path.
+# By default it is $(OUT_DIR)/lib$(TARGET_LIB).a for "lib" module and
+# $(OUT_DIR)/lib$(TARGET_LIB).so for "shared_lib"
+# MOD_TARGET - module target name, including path. By default it is
+# $(OUT_DIR)/$(MOD_NAME) for "app" modules
+# $(TARGET_LIB_FNAME) for "lib" and "shared_lib" modules
+# CODEGEN_OUTPUT_DIR - output directory containing generated files
+
+TOOLCHAIN ?= gcc
+OS ?= posix
+DEBUG ?= y
+BLD_DEP ?= gcc
+USE_CLANG ?= n
+
+export SHELL := /bin/bash
+
+export BOARD
+export TOOLCHAIN
+export OS
+export DEBUG
+export BLD_DEP
+export OS_KERNEL
+
+V ?= 0
+ifeq (x"$(V)", x"0")
+ SILENT_BUILD = @
+endif
+
+SRC_DIR = $(TOP_DIR)/$(MOD_DIR)
+OUT_DIR_BASE ?= $(TOP_DIR)/build/$(SUBSYSTEM)
+OUT_DIR := $(OUT_DIR_BASE)/$(MOD_DIR)
+
+#
+# Compiler warning configuration
+# Some extra warnings are always enabled. Others must be opted in on the module level
+#
+ENABLE_EXTRA_WARNINGS ?= y
+export ENABLE_EXTRA_WARNINGS
+
+ifneq ("$(BUILD_NC_AGENT)", "y")
+ override NC_AGENT := none
+endif
+
+# Include optional subsystem-specific configuration
+-include mk/$(SUBSYSTEM)/Makefile.$(SUBSYSTEM).config
+
+ENABLE_EPON ?= y
+ENABLE_GPON ?= y
+ENABLE_XGPON ?= y
+
+ENABLE_GPON_OR_XGPON = n
+ifeq ("$(ENABLE_GPON)", "y")
+ ENABLE_GPON_OR_XGPON = y
+endif
+ifeq ("$(ENABLE_XGPON)", "y")
+ ENABLE_GPON_OR_XGPON = y
+endif
+export ENABLE_EPON
+export ENABLE_GPON
+export ENABLE_XGPON
+export ENABLE_GPON_OR_XGPON
+
+CONFIG_DIR = src/common/config
+OS_PLATFORM_DIR = src/$(SUBSYSTEM)/platform
+
+# CLI and logger support
+ENABLE_CLI ?= y
+ENABLE_LOG ?= y
+BAL_MONOLITHIC ?= y
+
+export ENABLE_CLI
+export ENABLE_LOG
+export BAL_MONOLITHIC
+
+#
+### Include module Makefile
+# For MOD_CUSTOM only will be included in Makefile.rules second time for propagate custom rules
+#
+include $(SRC_DIR)/Makefile
+
+# Code-generator - related parameters
+CODEGEN_INPUT_DIR = $(SRC_DIR)/codegen_templates
+CODEGEN_OUTPUT_DIR = $(OUT_DIR)
+CODEGEN_DIR = $(TOP_DIR)/src/datamodel/bin/codegen
+CODEGEN_EXE = $(CODEGEN_DIR)/Teknovus.MetaStructure.CodeGenerator.exe
+
+OMCI_STACK_CODEGEN_INPUT_DIR = $(SRC_DIR)/me_codegen
+OMCI_STACK_CODEGEN_EXE = $(OUT_DIR)/omci_me_codegen
+
+BAL_MODEL_FILE = $(TOP_DIR)/src/datamodel/bal.objset
+OMCI_MODEL_FILE = $(TOP_DIR)/src/datamodel/omci.objset
+OMCI_STACK_MODEL_FILE = $(TOP_DIR)/src/datamodel/omci_me_datamodel.csv
+MONO_VER ?= 4.3.2.467
+MONO_PATH ?= /opt/mono-$(MONO_VER)/bin/mono
+
+export SRC_DIR
+export OUT_DIR_BASE
+export OUT_DIR
+export MODEL_OUT_DIR
+
+ifeq ("$(wildcard $(MONO_PATH))", "")
+ # If we can't find Mono installed in the correct path, default to the current PATH version.
+ # In the future, we should always use Mono from a common tools directory.
+ # TODO: change this once the compiler/toolchain paths are better defined.
+ MONO_PATH = mono
+endif
+
+# Treat "yes" and "y" the same
+ifeq ("$(USE_CLANG)", "yes")
+ USE_CLANG := y
+endif
+ifeq ("$(USE_CLANG)", "y")
+ include $(MAKE_DIR)/clang.opts
+endif
+
+# Disable code generation in release build
+ifeq ("$(RELEASE_BUILD)", "y")
+ srcs := $(srcs) $(gen_bal_srcs) $(gen_omci_srcs)
+ gen_bal_hdrs :=
+ gen_bal_srcs :=
+ gen_omci_hdrs :=
+ gen_omci_srcs :=
+ # Disable LINT and CLANG
+ USE_LINT = n
+ USE_CLANG = n
+endif
+
+SRCS = $(strip $(srcs:%=$(SRC_DIR)/%))
+
+# In COMPILE_ALL_IN_ONE_GO mode all .c files of a module are compiled in
+# a single invocation of BLD_CC compiler. In result, objects files are created
+# in OUT_DIR even if module's .c files are spread in sub-directories
+ifeq ("$(COMPILE_ALL_IN_ONE_GO)", "y")
+ srcs_no_dir = $(notdir $(srcs))
+ _OBJS = $(srcs_no_dir:%.c=$(OUT_DIR)/%.o)
+else
+ _OBJS = $(srcs:%.c=$(OUT_DIR)/%.o)
+endif
+
+as_SRCS = $(strip $(as_srcs:%=$(SRC_DIR)/%))
+as_OBJS = $(as_srcs:%.s=$(OUT_DIR)/%.o)
+_OBJS += $(as_OBJS)
+
+AS_SRCS = $(strip $(AS_srcs:%=$(SRC_DIR)/%))
+AS_OBJS = $(AS_srcs:%.S=$(OUT_DIR)/%.o)
+_OBJS += $(AS_OBJS)
+
+ifneq ("$(gen_bal_srcs)", "")
+ GEN_BAL_SRCS = $(strip $(gen_bal_srcs:%=$(CODEGEN_OUTPUT_DIR)/%))
+ _OBJS += $(GEN_BAL_SRCS:%.c=%.o)
+endif
+ifneq ("$(gen_bal_hdrs)", "")
+ GEN_BAL_HDRS = $(strip $(gen_bal_hdrs:%=$(CODEGEN_OUTPUT_DIR)/%))
+endif
+
+ifneq ("$(gen_omci_srcs)", "")
+ GEN_OMCI_SRCS = $(strip $(gen_omci_srcs:%=$(CODEGEN_OUTPUT_DIR)/%))
+ _OBJS += $(GEN_OMCI_SRCS:%.c=%.o)
+endif
+ifneq ("$(gen_omci_hdrs)", "")
+ GEN_OMCI_HDRS = $(strip $(gen_omci_hdrs:%=$(CODEGEN_OUTPUT_DIR)/%))
+endif
+
+ifneq ("$(gen_omci_stack_srcs)", "")
+ GEN_OMCI_STACK_SRCS = $(strip $(gen_omci_stack_srcs:%=$(CODEGEN_OUTPUT_DIR)/%))
+ _OBJS += $(GEN_OMCI_STACK_SRCS:%.c=%.o)
+endif
+ifneq ("$(gen_omci_stack_hdrs)", "")
+ GEN_OMCI_STACK_HDRS = $(strip $(gen_omci_stack_hdrs:%=$(CODEGEN_OUTPUT_DIR)/%))
+endif
+
+OBJS = $(strip $(_OBJS))
+
+GEN_SRCS = $(GEN_BAL_SRCS) $(GEN_OMCI_SRCS) $(GEN_OMCI_STACK_SRCS)
+GEN_HDRS = $(GEN_BAL_HDRS) $(GEN_OMCI_HDRS) $(GEN_OMCI_STACK_HDRS)
+
+# Add default dependency on OS abstraction
+ifeq ("$(MOD_NAME)", "")
+ ifneq (x"$(V)", x"0")
+ $(info MOD_NAME is not set for $(SRC_DIR)/Makefile. Skipping..)
+ endif
+ MOD_TYPE = _skip_
+endif
+
+# Add default dependency on OS abstraction
+ifneq ("$(MOD_SUPPRESS_OS_DEP), "y)
+ ifeq ("$(MOD_TYPE)", "linux_module")
+ _kernel = y
+ endif
+ ifeq ("$(MOD_TYPE)", "linux_lib")
+ _kernel = y
+ endif
+ ifeq ("$(_kernel)", "y")
+ MOD_DEPS := os_linux $(MOD_DEPS)
+ else
+ MOD_DEPS := os $(MOD_DEPS)
+ endif
+endif
+
+# Extra types filter
+ifneq ("$(EXTRA_TYPES)", "")
+ EXTRA_TYPES := $(shell echo -n $(EXTRA_TYPES) | sed -e 's/ /\\|/g')
+ GEN_EXTRA_TYPES := -typeNameFilter=\^\($(EXTRA_TYPES)\)\$$
+endif
+
+OS_KERNEL ?= $(OS)
+UC_PLATFORM = $(shell echo $(PLATFORM) | tr a-z A-Z)
+UC_SUBSYSTEM = $(shell echo $(SUBSYSTEM) | tr a-z A-Z)
+UC_OS = $(shell echo $(OS) | tr a-z A-Z)
+UC_OS_KERNEL = $(shell echo $(OS_KERNEL) | tr a-z A-Z)
+
+EXTRA_DEFINES += -DBCM_SUBSYSTEM_$(UC_SUBSYSTEM) -DBCM_PLATFORM_$(UC_PLATFORM) -DBCM_OS_$(UC_OS)
+EXTRA_DEFINES += -DBCM_SUBSYSTEM_HOST
+EXTRA_DEFINES += -D$(UC_OS_KERNEL)_KERNEL_SPACE
+ifeq ("$(ENABLE_EPON)", "y")
+ EXTRA_DEFINES += -DBCM_EPON
+endif
+ifeq ("$(ENABLE_GPON)", "y")
+ EXTRA_DEFINES += -DBCM_GPON
+endif
+ifeq ("$(ENABLE_XGPON)", "y")
+ EXTRA_DEFINES += -DBCM_XGPON
+endif
+
+ifneq ("$(CONFIG_MAC_RPC)", "n")
+EXTRA_DEFINES += -DCONFIG_MAC_RPC
+endif
+
+ifneq ("$(CONFIG_SWITCH_RPC)", "n")
+EXTRA_DEFINES += -DCONFIG_SWITCH_RPC
+endif
+
+ifneq ("$(BOARD)", "")
+EXTRA_DEFINES += -DBOARD=$(BOARD)
+endif
+
+ifeq ("$(BOARD)", "wrx")
+EXTRA_DEFINES += -DWRX_BUILD
+endif
+
+ifeq ("$(BUILD_OF_AGENT)", "y")
+EXTRA_DEFINES += -DBUILD_OF_AGENT
+endif
+
+ifeq ("$(FORCE_PKTIN_SND)", "y")
+EXTRA_DEFINES += -DFORCE_PKTIN_SND
+endif
+
+# Build unitests for simulation and from Jenkins jobs
+UNITEST ?= n
+
+ifeq ("$(SIMULATION_BUILD)", "y")
+ EXTRA_DEFINES += -DSIMULATION_BUILD
+ UNITEST = y
+endif
+
+ifeq ("$(JENKINS_BUILD)", "y")
+ UNITEST = y
+endif
+
+ifeq ("$(BAL_MONOLITHIC)", "y")
+ EXTRA_DEFINES += -DBAL_MONOLITHIC
+endif
+
+EXTRA_INCLUDES += -I$(SRC_DIR)
+EXTRA_INCLUDES += -I$(TOP_SRC_DIR)/common/include -I$(OUT_DIR_BASE)/src/common/include
+
+OPT_DISABLE_$(UC_SUBSYSTEM) ?=n
+OPT_DISABLE := $(OPT_DISABLE_$(UC_SUBSYSTEM))
+
+ARCH_CFLAGS = $(ARCH_FLAGS)
+ifeq ("$(OPT_DISABLE)", "y")
+ ARCH_CFLAGS += $(DEBUG_O_CFLAGS)
+ EXTRA_LFLAGS += $(DEBUG_O_LFLAGS)
+ EXTRA_ASFLAGS += $(DEBUG_O_ASFLAGS)
+ EXTRA_asFLAGS += $(DEBUG_O_asLAGS)
+else
+ ARCH_CFLAGS += $(RELEASE_O_CFLAGS)
+ EXTRA_LFLAGS += $(RELEASE_O_LFLAGS)
+ EXTRA_ASFLAGS += $(RELEASE_O_ASFLAGS)
+ EXTRA_asFLAGS += $(RELEASE_O_asFLAGS)
+endif
+
+# 3rd party packages install location
+INSTALL_DIR ?= $(OUT_DIR_BASE)
+export INSTALL_DIR
+EXTRA_INCLUDES += -I$(INSTALL_DIR)/include
+
+PATH := $(INSTALL_DIR)/bin:$(PATH)
+export PATH
+
+# Shared library location
+SHARED_LIB_DIR ?= $(INSTALL_DIR)/lib
+export SHARED_LIB_DIR
+
+# Treat lib as shared lib if BUILD_SHARED_LIBS is y
+ifeq ("$(BUILD_SHARED_LIBS)", "y")
+ export BUILD_SHARED_LIBS
+ ifeq ("$(MOD_TYPE)", "lib")
+ MOD_TYPE = shared_lib
+ endif
+ EXTRA_LIBS_PATH += -L$(TOP_DIR)/$(LOCAL_MAPLE_SDK_DIR)/build/shared_libs
+endif
+EXTRA_LIBS_PATH += -L$(SHARED_LIB_DIR)
+
+# Calculate MOD_TARGET based on MOD_TYPE
+ifeq ("$(MOD_TYPE)", "lib")
+ ifneq ("$(OBJS)", "")
+ TARGET_LIB ?= $(MOD_NAME)
+ TARGET_LIB_FNAME ?= $(OUT_DIR)/lib$(TARGET_LIB).a
+ endif
+ MOD_TARGET ?= $(TARGET_LIB_FNAME)
+else ifeq ("$(MOD_TYPE)", "shared_lib")
+ ifneq ("$(OBJS)", "")
+ TARGET_LIB ?= $(MOD_NAME)
+ TARGET_LIB_FNAME ?= $(OUT_DIR)/lib$(TARGET_LIB).so
+ endif
+ MOD_TARGET ?= $(TARGET_LIB_FNAME)
+else ifeq ("$(MOD_TYPE)", "app")
+ MOD_TARGET ?= $(OUT_DIR)/$(MOD_NAME)
+else ifeq ("$(MOD_TYPE)", "linux_module")
+ ifeq ("$(KERNELDIR)", "")
+ $(error KERNELDIR must be set in board profile)
+ endif
+ ifeq ("$(KERNEL_ARCH)", "")
+ $(error KERNEL_ARCH must be set in board profile)
+ endif
+ ifeq ("$(KERNEL_OUTDIR)", "")
+ KERNEL_OUTDIR := $(KERNELDIR)
+ endif
+ MOD_TARGET ?= $(SRC_DIR)/$(MOD_NAME).ko
+else ifeq ("$(MOD_TYPE)", "linux_lib")
+ MOD_TARGET ?= $(OUT_DIR_BASE)/$(MOD_NAME).linuxlib
+else ifeq ("$(MOD_TYPE)", "_skip_")
+ MOD_TARGET = .dummy
+else
+ $(error MOD_TYPE $(MOD_TYPE) is incorrect for module $(MOD_NAME). Must be lib or app)
+endif
+
+ifeq ("$(MOD_TARGET)", "")
+ MOD_TARGET = $(MOD_NAME)
+endif
+
+ifeq ("$(OS)", "posix")
+ EXTRA_DEFINES += -D_XOPEN_SOURCE=600
+ LIBS = -lrt -lpthread -lm
+endif
+
+# Make sure that paths in EXTRA_INCLUDES are absolute
+ifneq ("$(EXTRA_INCLUDES)", "")
+ # Make sure that each directory is an absolute path
+ EXTRA_INCS = $(addprefix -I, $(abspath $(subst -I,,$(subst $(TOP_DIR)/,,$(EXTRA_INCLUDES)))))
+endif
+ifneq ("$(EXTRA_ASINCLUDES)", "")
+ # Make sure that each directory is an absolute path
+ EXTRA_ASINCS = $(addprefix -I, $(abspath $(subst -I,,$(subst $(TOP_DIR)/,,$(EXTRA_ASINCLUDES)))))
+endif
+ifneq ("$(EXTRA_asINCLUDES)", "")
+ # Make sure that each directory is an absolute path
+ EXTRA_asINCS = $(addprefix -I, $(abspath $(subst -I,,$(subst $(TOP_DIR)/,,$(EXTRA_asINCLUDES)))))
+endif
+ifeq ("$(USE_LINT)", "y")
+ USE_LINT := yes
+endif
+ifeq ("$(USE_LINT)", "yes")
+ EXTRA_DEFINES += -DUSE_LINT
+endif
+
+EXTRA_DEFINES += $(USER_EXTRA_DEFINES) $(USER_EXTRA_$(UC_SUBSYSTEM)_DEFINES)
+EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) $(USER_EXTRA_$(UC_SUBSYSTEM)_CFLAGS)
+CFLAGS += $(ARCH_CFLAGS) $(EXTRA_CFLAGS) $(EXTRA_INCS) $(EXTRA_DEFINES)
+ASFLAGS += $(ARCH_FLAGS) $(EXTRA_ASFLAGS) $(EXTRA_ASINCS) $(EXTRA_ASDEFINES)
+asFLAGS += $(ARCH_FLAGS) $(EXTRA_asFLAGS) $(EXTRA_asINCS) $(EXTRA_asDEFINES)
+LFLAGS += $(ARCH_FLAGS) $(EXTRA_LFLAGS)
+DEP_FLAGS += $(EXTRA_CFLAGS) $(EXTRA_INCS) $(EXTRA_DEFINES)
+CLANG_FLAGS += $(EXTRA_CFLAGS) $(EXTRA_INCS) $(EXTRA_DEFINES) $(CLANG_OPTS)
diff --git a/bal_release/mk/Makefile.initial_config b/bal_release/mk/Makefile.initial_config
new file mode 100644
index 0000000..541ec84
--- /dev/null
+++ b/bal_release/mk/Makefile.initial_config
@@ -0,0 +1,6 @@
+ifeq ("$(TERM)", "dumb")
+ BOLD_PRINT := printf "\n---- %s --------------------------------------------------\n"
+else
+ BOLD_PRINT?=printf "[01m%s[0m\n"
+endif
+export BOLD_PRINT
diff --git a/bal_release/mk/Makefile.main b/bal_release/mk/Makefile.main
new file mode 100644
index 0000000..3818766
--- /dev/null
+++ b/bal_release/mk/Makefile.main
@@ -0,0 +1,180 @@
+# It is included from the central Makefile once for each subsystem (e.g., "core" and "agent")
+# PARAMATER: SUBSYSTEM
+
+UC_SUBSYSTEM = $(shell echo $(SUBSYSTEM) | tr a-z A-Z)
+export BUILD_TARGET = $(SUBSYSTEM)
+export BIN_RELEASE_FILE_PREFIX ?= release.bin.$(SUBSYSTEM).$(BUILD_VERSION_PREFIX)
+export OUT_$(UC_SUBSYSTEM)_DIR ?= $(OUT_DIR)/$(SUBSYSTEM)
+
+# Combine modules.$(SUBSYSTEM).bal, modules.$(SUBSYSTEM).sdn_pal and modules.$(SUBSYSTEM).omci into a single file in the subsystem directory
+define combine_modules
+ mkdir -p $(OUT_$(UC_SUBSYSTEM)_DIR); \
+ rm -rf $1; \
+ touch $1; \
+ for mod_file in $2; do cat $$mod_file >> $1; done;
+endef
+
+# Create $(SUBSYSTEM)/modules.$(SUBSYSTEM).omci and $(SUBSYSTEM)/modules.$(SUBSYSTEM).sdn_pal if they doesn't exist, as empty files.
+# This is relevant when compiling from source release package extraction.
+$(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).omci: | phonytarget
+ touch $@
+$(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).sdn_pal: | phonytarget
+ touch $@
+
+phonytarget:
+
+# ORDER IS IMPORTANT - OMCI should come before BAL
+$(OUT_$(UC_SUBSYSTEM)_DIR)/modules.core: $(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).omci $(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).bal
+ $(call combine_modules,$(OUT_$(UC_SUBSYSTEM)_DIR)/modules.core,$^)
+
+# ORDER IS IMPORTANT - SDN_PAL should come after BAL
+$(OUT_$(UC_SUBSYSTEM)_DIR)/modules.agent: $(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).bal $(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).omci $(MAKE_DIR)/$(SUBSYSTEM)/modules.$(SUBSYSTEM).sdn_pal
+ $(call combine_modules,$(OUT_$(UC_SUBSYSTEM)_DIR)/modules.agent,$^)
+
+$(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD): $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM) \
+ $(MAKE_DIR)/Makefile.config $(MAKE_DIR)/Makefile.rules $(MAKE_DIR)/Makefile.template $(MAKE_DIR)/Makefile.main
+ @if ! test -f $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD); then\
+ if ls $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_* 2>/dev/null >/dev/null; then\
+ olddeps=`ls $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_*` ; \
+ old_board=`echo $$olddeps | sed 's@$(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_@@'` ; \
+ $(BOLD_PRINT) "Previous build was for different board $$old_board. cleaning up..";\
+ $(MAKE) -s BOARD=$$old_board V=0 clean_$(SUBSYSTEM); \
+ rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)/build/output/*; \
+ fi;\
+ fi
+ @$(BOLD_PRINT) "Generating list of $(SUBSYSTEM) modules for $(BUILD_TARGET)"
+ @rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_*
+ @rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)
+ @rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)
+ @rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)
+ @mkdir -p $(OUT_$(UC_SUBSYSTEM)_DIR)
+ @touch $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)
+ @touch $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)
+ @touch $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)
+ @for mod_dir in `awk '{print $$1}' $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM)`; do\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ mod_name=`$(MAKE) -s V=0 SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir SKIP_DEPS=yes -f $(MAKE_DIR)/Makefile.template module_name`;\
+ if test "$$mod_name" = "" ; then continue; fi; \
+ mod_name=$${mod_name}_$(SUBSYSTEM);\
+ mod_type=`grep -e '^[[:space:]]*MOD_TYPE[[:space:]]*=' $$mod_dir/Makefile | awk -F= '{sub(/\r/,""); print $$2}' | sed -e 's/^[ \t]*//'`; \
+ echo -n "$$mod_name " >> $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM); \
+ if test "`echo -n $$mod_type | sed -e 's/linux_lib lib/lib/' | sed -e 's/lib linux_lib/lib/'`" = "lib" ; then\
+ echo -n "$$mod_name " >> $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM); \
+ fi;\
+ if test "$$mod_type" = "app" ; then\
+ echo -n "$$mod_name " >> $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM); \
+ fi;\
+ done
+ @touch $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD)
+
+$(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_$(BOARD): $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD)
+ @$(BOLD_PRINT) "Building $(BOARD) board environment for $(BUILD_TARGET)"
+ $(MAKE) SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR) SKIP_DEPS=yes \
+ ALL_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)`" \
+ ALL_LIB_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)`" \
+ ALL_APP_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)`" \
+ -f $(MAKE_DIR)/Makefile.template board_env
+ @$(BOLD_PRINT) "Generating $(SUBSYSTEM) dependencies for $(BUILD_TARGET)"
+ @for mod_dir in `awk '{print $$1}' $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM)`; do\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ mod_name=`$(MAKE) -s V=0 SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir SKIP_DEPS=yes -f $(MAKE_DIR)/Makefile.template module_name`;\
+ if test "$$mod_name" = "" ; then continue; fi; \
+ if ! $(MAKE) $(SILENT) SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR) SKIP_DEPS=yes \
+ ALL_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)`" \
+ ALL_LIB_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)`" \
+ ALL_APP_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)`" \
+ -f $(MAKE_DIR)/Makefile.template moddep; then exit 1;\
+ fi;\
+ done
+ @touch $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_$(BOARD)
+ @echo "$(BOARD_DIR)" > $(OUT_$(UC_SUBSYSTEM)_DIR)/.board_dir
+
+.PHONY:
+
+# Make sure that none of module Makefiles changed.
+# If there is a change - we need to regenerate dependencies
+_deps_$(SUBSYSTEM)_: $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_$(BOARD) .PHONY
+ @cat $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM) | while read -r mod_dir_targ; do\
+ mod_dir=`echo $$mod_dir_targ | awk '{print $$1}'`;\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ if test $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD) -ot $$mod_dir/Makefile; then\
+ echo $$mod_dir/Makefile changed, must regenerate dependencies.;\
+ echo PLEASE RE-RUN make;\
+ rm -f $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_$(BOARD);\
+ exit -1;\
+ fi;\
+ done
+
+build_$(SUBSYSTEM): _deps_$(SUBSYSTEM)_
+ @$(BOLD_PRINT) "Building $(SUBSYSTEM) image for $(BUILD_TARGET)"
+ @cat $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM) | while read -r mod_dir_targ; do\
+ mod_dir=`echo $$mod_dir_targ | awk '{print $$1}'`;\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ mod_targets=`echo $$mod_dir_targ | awk '{print $$2 $$3 $$4 $$5}'`;\
+ if ! $(MAKE) $(SILENT) SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR) \
+ ALL_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)`" \
+ ALL_LIB_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)`" \
+ ALL_APP_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)`" \
+ -f $(MAKE_DIR)/Makefile.template $$mod_targets; then exit 1;\
+ fi;\
+ done
+ @$(BOLD_PRINT) "Finished building $(SUBSYSTEM) image for $(BUILD_TARGET)"
+
+clean_$(SUBSYSTEM): BOARD=$(shell ls $(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_* 2>/dev/null | sed 's@$(OUT_$(UC_SUBSYSTEM)_DIR)/.deps_$(SUBSYSTEM)_list_@@')
+
+clean_$(SUBSYSTEM): $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM)
+ @$(BOLD_PRINT) "Clean $(PLATFORM) $(SUBSYSTEM) BOARD=$(BOARD)"
+ @for mod_dir in `awk '{print $$1}' $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM)`; do\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ $(MAKE) $(SILENT) SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR) SKIP_DEPS=yes \
+ -f $(MAKE_DIR)/Makefile.template clean_module;\
+ done
+ $(SILENT_BUILD)rm -fr $(OUT_$(UC_SUBSYSTEM)_DIR)
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name '*~' -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name '*.ko' -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name '.*.cmd' -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name '*.o' -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name '*.mod.c' -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name modules.order -print0 2>/dev/null | xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name Module.symvers -print0 2>/dev/null| xargs -0 rm -rf
+ $(SILENT_BUILD)find $(SUBSYSTEM) -name .tmp_versions -print0 2>/dev/null | xargs -0 rm -rf
+
+help_$(SUBSYSTEM):
+ @echo "$$PLATFORM $(SUBSYSTEM) modules:"
+ @cat $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM) | while read -r mod_dir_targ; do\
+ mod_dir=`echo $$mod_dir_targ | awk '{print $$1}'`;\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ mod_name=`$(MAKE) -s V=0 SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir SKIP_DEPS=yes -f $(MAKE_DIR)/Makefile.template module_name`;\
+ if test "$$mod_name" = "" ; then continue; fi; \
+ echo " " $${mod_name}_$(SUBSYSTEM);\
+ done
+
+# Targets for building individual $(SUBSYSTEM) module
+%_$(SUBSYSTEM):: _deps_$(SUBSYSTEM)_
+ @while read -r mod_dir_targ; do\
+ mod_dir=`echo $$mod_dir_targ | awk '{print $$1}'`;\
+ if test "$$mod_dir" = "" ; then continue; fi; \
+ mod_name=`$(MAKE) -s V=0 SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir SKIP_DEPS=yes -f $(MAKE_DIR)/Makefile.template module_name`;\
+ if test "$$mod_name" = "" ; then continue; fi; \
+ mod_name=$${mod_name}_$(SUBSYSTEM);\
+ mod_targets=`echo $$mod_dir_targ | awk '{print $$2 $$3 $$4 $$5}'`;\
+ if test "$$mod_name" = "$@" ; then\
+ target_found=y;\
+ $(MAKE) $(SILENT) SUBSYSTEM=$(SUBSYSTEM) MOD_DIR=$$mod_dir OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR) \
+ ALL_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_modules.$(SUBSYSTEM)`" \
+ ALL_LIB_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_lib_modules.$(SUBSYSTEM)`" \
+ ALL_APP_MODULES="`cat $(OUT_$(UC_SUBSYSTEM)_DIR)/all_app_modules.$(SUBSYSTEM)`" \
+ -f $(MAKE_DIR)/Makefile.template $$mod_targets || exit 1;\
+ fi;\
+ done < $(OUT_$(UC_SUBSYSTEM)_DIR)/modules.$(SUBSYSTEM);\
+ if test "$$target_found" != "y" ; then\
+ echo No rule to make target $@;\
+ exit 1;\
+ fi
+
+docs_$(SUBSYSTEM): _deps_$(SUBSYSTEM)_
+ mkdir -p $(OUT_DOCS_DIR)
+ $(SILENT_BUILD)$(MAKE) -C doxygen OUT_DIR_BASE=$(OUT_$(UC_SUBSYSTEM)_DIR)
+
+bin_release_$(SUBSYSTEM): build_$(SUBSYSTEM)
+ $(SILENT_BUILD)$(MAKE_DIR)/bin_release.sh
diff --git a/bal_release/mk/Makefile.rules b/bal_release/mk/Makefile.rules
new file mode 100644
index 0000000..886b22f
--- /dev/null
+++ b/bal_release/mk/Makefile.rules
@@ -0,0 +1,494 @@
+# Common Makefile rules
+#
+
+# For linux_lib we don't build anything. Object files are just added
+# when compiling modules depending on the libs
+
+ifeq ("$(MOD_TYPE)", "linux_lib")
+ # Skip libraries that might have crept in dependencies
+ SKIP_LIB_MODULES = y
+ export SKIP_LIB_MODULES
+endif
+
+ifeq ("$(MOD_TYPE)", "linux_module")
+ # Skip libraries that might have crept in dependencies
+ SKIP_LIB_MODULES = y
+ export SKIP_LIB_MODULES
+endif
+
+ifeq ("$(MOD_TYPE)", "lib")
+ MODULE_IS_A_LIBRARY = y
+else ifeq ("$(MOD_TYPE)", "shared_lib")
+ MODULE_IS_A_LIBRARY = y
+else
+ MODULE_IS_A_LIBRARY = n
+endif
+
+# Include module's own auto-generated Makefile.config.$(MODULE) file if any
+# It in turn includes all dependencies
+ifeq (x"$(V)", x"2")
+ $(info !!!MOD_NAME=$(MOD_NAME) MOD_TYPE=$(MOD_TYPE) MOD_TARGET=$(MOD_TARGET))
+ $(info !!!Including own dependency file: $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME))
+endif
+-include $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+ifeq (x"$(V)", x"2")
+ $(info !!!After include of $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME))
+endif
+
+ifeq (x"$(V)", x"2")
+ $(info !!! Building $(MOD_TYPE) module $(MOD_NAME): depends on $(MOD_DEPS_FILES) SKIP_LIBS=$(SKIP_LIB_MODULES))
+endif
+
+# Skip default rules for custom module
+ifneq ("$(MOD_CUSTOM)", "y")
+
+# Default lib rule
+ifeq ("$(MOD_TYPE)", "lib")
+
+ifeq ("$(SKIP_LIB_MODULES)", "y")
+
+$(MOD_TARGET):
+
+# of ifneq ("$(SKIP_LIB_MODULES)", "y")
+else
+
+# Create library if there are any objects
+$(MOD_TARGET): $(OBJS)
+ifneq ("$(OBJS)", "")
+ $(SILENT_BUILD)$(BLD_AR) $(ARFLAGS) $@ $(OBJS)
+ifeq ("$(MOD_POST_BUILD)", "")
+ @$(BOLD_PRINT) "done: $@"
+endif
+endif
+ifneq ("$(MOD_POST_BUILD)", "")
+ $(SILENT_BUILD)$(MOD_POST_BUILD)
+ @$(BOLD_PRINT) "done: $@"
+endif
+ $(SILENT_BUILD)touch $(OUT_DIR_BASE)/.$(MOD_NAME)
+
+# end of ifeq ("$(SKIP_LIB_MODULES)", "y")
+endif
+
+# end of ifeq ("$(MOD_TYPE)", "lib")
+endif
+
+# Default shared_lib rule
+ifeq ("$(MOD_TYPE)", "shared_lib")
+
+EXTRA_CFLAGS += -fPIC
+
+# Create library if there are any objects
+$(MOD_TARGET): $(OBJS)
+ifneq ("$(OBJS)", "")
+ $(SILENT_BUILD)$(BLD_CC) -shared -o $@ $(OBJS) $(LFLAGS)
+ $(SILENT_BUILD)mkdir -p $(SHARED_LIB_DIR)
+ $(SILENT_BUILD)cp $@ $(SHARED_LIB_DIR)/
+ifeq ("$(MOD_POST_BUILD)", "")
+ @$(BOLD_PRINT) "done: $@"
+endif
+endif
+ifneq ("$(MOD_POST_BUILD)", "")
+ $(SILENT_BUILD)$(MOD_POST_BUILD)
+ @$(BOLD_PRINT) "done: $@"
+endif
+ $(SILENT_BUILD)touch $(OUT_DIR_BASE)/.$(MOD_NAME)
+
+# end of ifeq ("$(MOD_TYPE)", "shared_lib")
+endif
+
+# Default app rule
+ifeq ("$(MOD_TYPE)", "app")
+
+$(MOD_TARGET): $(OBJS) $(MOD_DEPS_FILES)
+ $(SILENT_BUILD)$(BLD_CC) -o $@ $(OBJS) $(LFLAGS) $(EXTRA_LIBS_PATH) $(EXTRA_LIBS_NOREC_BEFORE) $(LIBS_START_MARKER) $(EXTRA_LIBS) $(LIBS_END_MARKER) $(EXTRA_LIBS_NOREC_AFTER) $(LIBS)
+ifneq ("$(MOD_POST_BUILD)", "")
+ $(SILENT_BUILD)$(MOD_POST_BUILD)
+endif
+ $(SILENT_BUILD)touch $(OUT_DIR_BASE)/.$(MOD_NAME)
+ @$(BOLD_PRINT) "done: $(OUT_DIR)/$(MOD_NAME)"
+
+# endif of ifeq ("$(MOD_TYPE)", "app")
+endif
+
+# For linux_lib we don't build anything. Object files are just added
+# when compiling modules depending on the libs
+ifeq ("$(MOD_TYPE)", "linux_lib")
+ LINUX_LIB_OBJECTS := $(srcs:%.c=$(SRC_DIR)/%.o)
+
+$(MOD_TARGET): $(SRCS) $(GEN_SRCS) $(MOD_DEPS_FILES)
+ $(SILENT_BUILD)touch $(MOD_TARGET)
+ $(SILENT_BUILD)touch $(OUT_DIR_BASE)/.$(MOD_NAME)
+
+endif
+
+# Default linux_module$(srcs:%=$(SRC_DIR)/%)
+ifeq ("$(MOD_TYPE)", "linux_module")
+ obj-m += $(MOD_NAME).o
+ $(MOD_NAME)-objs := $(srcs:%.c=%.o)
+ LIB_OBJS_REL_PATH = $(foreach oo,$(ALL_LIB_OBJS),$(shell python -c "import os.path; print os.path.relpath('$(oo)', '$(SRC_DIR)')"))
+
+ _KERNEL_MAKEPARMS = -C $(KERNELDIR) M=$(SRC_DIR) KBUILD_EXTRA_SYMBOLS="$(KBUILD_EXTRA_SYMBOLS)" \
+ O=$(KERNEL_OUTDIR) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) V=$(V) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ obj-m=$(obj-m) $(MOD_NAME)-objs="$($(MOD_NAME)-objs) $(LIB_OBJS_REL_PATH)"
+ KERNEL_MAKEPARMS = $(_KERNEL_MAKEPARMS:%os_abstraction/posix=%os_abstraction/linux)
+
+ # Prevent parallel build
+.NOTPARALLEL:
+
+ # Only build linux module if not already being built by another make thread.
+ # Otherwise, linux build system get confused
+ # Also, remove -s flag using MAKEFLAGS. Otherwise, linux build system will not print names of the files
+ # being compiled
+$(MOD_TARGET): $(SRCS) $(MOD_DEPS_FILES)
+ifneq ("$(SRC_DIR)", "$(TOP_DIR)/$(MOD_DIR)")
+ @cp -f $(TOP_DIR)/$(MOD_DIR)/Makefile $(SRC_DIR)
+endif
+ $(SILENT_BUILD)if [ ! -f $(SRC_DIR)/.$(MOD_NAME)_in_progress ]; then \
+ touch $(SRC_DIR)/.$(MOD_NAME)_in_progress; \
+ MAKEFLAGS= $(MAKE) $(KERNEL_MAKEPARMS) ;\
+ if [[ "$$?" != "0" ]]; then \
+ rm -f $(SRC_DIR)/.$(MOD_NAME)_in_progress;\
+ exit -2;\
+ fi; \
+ mkdir -p $(OUT_DIR_BASE)/linux_modules ;\
+ touch -c $(MOD_TARGET) ;\
+ cp $(SRC_DIR)/$(MOD_NAME).ko $(OUT_DIR_BASE)/linux_modules/ ;\
+ touch $(OUT_DIR_BASE)/.$(MOD_NAME) ;\
+ $(BOLD_PRINT) "done: $(MOD_TARGET)" ;\
+ rm -f $(SRC_DIR)/.$(MOD_NAME)_in_progress ;\
+ fi
+
+# Take care of compiling generated code for linux kernel
+ifneq ("$(SRC_DIR)", "$(TOP_DIR)/$(MOD_DIR)")
+
+$(SRC_DIR)/%.c : $(CODEGEN_OUTPUT_DIR)/../%.c
+ $(SILENT_BUILD)cp -f $(CODEGEN_OUTPUT_DIR)/../*.[c,h] $(SRC_DIR)/
+
+$(SRC_DIR)/%.h : $(CODEGEN_OUTPUT_DIR)/../%.h
+ $(SILENT_BUILD)cp -f $(CODEGEN_OUTPUT_DIR)/../*.[c,h] $(SRC_DIR)/
+
+endif
+
+# End of MOD_TYPE==linux_module
+endif
+
+# else of ifneq ("$(MOD_CUSTOM)", "y")
+else
+
+# only for MOD_CUSTOM include Module Makefile second time for propagate
+# custom rules, first time included in Makefile.config for all modules
+include $(SRC_DIR)/Makefile
+
+# End of ifneq ($(MOD_CUSTOM), y)
+endif
+
+$(OUT_DIR)/%.o: $(SRC_DIR)/%.c $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+ifeq (x"$(V)", x"0")
+ @echo "CC $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_CC) $(CFLAGS) -D__BASENAME__=`basename $<` -c -o $@ $<
+ifeq (x"$(USE_LINT)", x"yes")
+ifeq (x"$(V)", x"0")
+ @echo "LINT $<"
+endif
+ $(SILENT_BUILD)FORCE_LINT=$(FORCE_LINT) $(MAKE_DEVICE_DIR)/lint.sh $(LINT_FLAGS) $(filter -I% -D%, $(CFLAGS)) $< || { rm $@; false; }
+endif
+ifeq (x"$(USE_CLANG)", x"y")
+ifeq (x"$(V)", x"0")
+ _fn=`basename "$<" .c` ;\
+ eval "_disable_fn_set=\$${DISABLE_CLANG_$$_fn}"; \
+ if test "$$_disable_fn_set" != "y" ; then echo "CLANG $<"; else echo "CLANG $< ... skipped"; fi
+endif
+ _fn=`basename "$<" .c` ;\
+ eval "_disable_fn_set=\$${DISABLE_CLANG_$$_fn}"; \
+ if test "$$_disable_fn_set" != "y" ; then $(CLANG) $(CLANG_FLAGS) -c $< -o $@.clang && rm -f $@.clang; fi
+# end of ifeq (x"$(USE_CLANG)", x"y")
+endif
+
+$(OUT_DIR)/%.o: $(SRC_DIR)/%.s $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+ifeq (x"$(V)", x"0")
+ @echo "AS $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_AS) $(asFLAGS) -o $@ $<
+
+$(OUT_DIR)/%.o: $(SRC_DIR)/%.S $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+ifeq (x"$(V)", x"0")
+ @echo "AS $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_CC) $(ASFLAGS) -o $@ $<
+
+
+$(OUT_DIR)/%.d: $(SRC_DIR)/%.c $(SRC_DIR)/Makefile
+ifneq ("$(BUILD_DEPS_IN_CC)", "y")
+ifeq (x"$(V)", x"0")
+ @echo "DP $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_DEP) -MM -MT $(@:.d=.o) $(DEP_FLAGS) $< > $@ && sed 's,\($*\.o\)[ :]*,\1 $@ : ,g' -i $@
+endif
+
+$(CODEGEN_OUTPUT_DIR)/%.o: $(CODEGEN_OUTPUT_DIR)/%.c $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+ifeq (x"$(V)", x"0")
+ @echo "CC $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_CC) $(CFLAGS) -D__BASENAME__=`basename $<` -c -o $@ $<
+
+$(CODEGEN_OUTPUT_DIR)/%.d: $(CODEGEN_OUTPUT_DIR)/%.c $(SRC_DIR)/Makefile
+ifneq ("$(BUILD_DEPS_IN_CC)", "y")
+ifeq (x"$(V)", x"0")
+ @echo "DP $<"
+endif
+ $(SILENT_BUILD)mkdir -p $(dir $@)
+ $(SILENT_BUILD)$(BLD_DEP) -MM -MT $(@:.d=.o) $(DEP_FLAGS) $< > $@ && sed 's,\($*\.o\)[ :]*,\1 $@ : ,g' -i $@
+endif
+
+ifneq ("$(SKIP_DEPS)", "yes")
+ifneq ("$(MOD_TYPE)", "linux_module")
+ifneq ("$(MOD_TYPE)", "linux_lib")
+-include $(OBJS:.o=.d)
+endif
+endif
+endif
+
+BUILD_UNITEST = $(UNITEST)
+ifeq ("$(OBJS)", "")
+ BUILD_UNITEST = n
+endif
+
+# Only build unitest if library objects are included
+ifeq ("$(BUILD_UNITEST)", "y")
+
+unitest: $(OUT_DIR)/unitest
+
+$(OUT_DIR)/unitest: $(OUT_DIR)/unitest.o $(TARGET_LIB_FNAME) $(MOD_DEPS_FILES)
+ $(SILENT_BUILD)$(BLD_CC) -o $@ $(OUT_DIR)/unitest.o $(LFLAGS) $(EXTRA_LIBS_PATH) $(LIBS_START_MARKER) $(EXTRA_LIBS) $(LIBS_END_MARKER) $(LIBS)
+ $(SILENT_BUILD)touch $(OUT_DIR_BASE)/.$(MOD_NAME)
+ @$(BOLD_PRINT) "done: $@"
+
+# else of ifneq ("$(BUILD_UNITEST)", "y")
+else
+
+unitest: $(TARGET_LIB_FNAME) $(MOD_DEPS_FILES)
+
+# endif of ifneq ("$(BUILD_UNITEST)", "y")
+endif
+
+# Generate sources if necessary
+ifneq ("$(GEN_SRCS)$(GEN_HDRS)$(GEN_OMCI_SRCS)$(GEN_OMCI_HDRS)$(GEN_OMCI_STACK_SRCS)$(GEN_OMCI_STACK_HDRS)", "")
+
+$(GEN_BAL_SRCS) $(GEN_BAL_HDRS): $(OUT_DIR)/.$(MOD_NAME)_generated_bal
+$(GEN_OMCI_SRCS) $(GEN_OMCI_HDRS): $(OUT_DIR)/.$(MOD_NAME)_generated_omci
+$(GEN_OMCI_STACK_SRCS) $(GEN_OMCI_STACK_HDRS): $(OUT_DIR)/.$(MOD_NAME)_generated_omci_stack
+
+$(OUT_DIR)/.$(MOD_NAME)_generated_bal: $(BAL_MODEL_FILE) $(wildcard $(CODEGEN_DIR)/*) $(wildcard $(CODEGEN_INPUT_DIR)/*)
+ $(call gen_cmd,$(GEN_BAL_SRCS),$(GEN_BAL_HDRS),$(BAL_MODEL_FILE),"bcmbal")
+
+$(OUT_DIR)/.$(MOD_NAME)_generated_omci: $(OMCI_MODEL_FILE) $(wildcard $(CODEGEN_DIR)/*) $(wildcard $(CODEGEN_INPUT_DIR)/*)
+ $(call gen_cmd,$(GEN_OMCI_SRCS),$(GEN_OMCI_HDRS),$(OMCI_MODEL_FILE),"bcmomci")
+
+$(OMCI_STACK_CODEGEN_EXE): $(OMCI_STACK_CODEGEN_INPUT_DIR)/omci_me_codegen.c
+ mkdir -p $(OUT_DIR)
+ $(BLD_CC_HOST) $(EXTRA_CFLAGS) -gdwarf-3 -o $@ $< -I$(TOP_DIR)/src/common/os_abstraction -I$(TOP_DIR)/src/common/os_abstraction/posix -I$(TOP_DIR)/src/common/config -I$(TOP_DIR)/src/core/platform -I$(TOP_DIR)/src/common/include
+
+$(OUT_DIR)/.$(MOD_NAME)_generated_omci_stack: $(OMCI_STACK_MODEL_FILE) $(wildcard $(CODEGEN_DIR)/*) $(wildcard $(CODEGEN_INPUT_DIR)/*) $(OMCI_STACK_CODEGEN_EXE)
+ $(call gen_omci_stack_cmd,$(GEN_OMCI_STACK_SRCS),$(GEN_OMCI_STACK_HDRS),$(OMCI_STACK_MODEL_FILE),"bcm_omci")
+
+define gen_cmd
+ mkdir -p $(CODEGEN_OUTPUT_DIR)
+ echo "Generating code from model: $(notdir $1 $2)"
+ $(MONO_PATH) $(CODEGEN_EXE) --genobjmodel -objset="$3" -style=bal -prefix=$4 \
+ -templatedir="$(CODEGEN_INPUT_DIR)" -outdir="$(CODEGEN_OUTPUT_DIR)"
+ touch $@
+ echo "Code generation complete!"
+endef
+
+define gen_omci_stack_cmd
+ echo "Generating code from model: $(notdir $1 $2)"
+ $(OMCI_STACK_CODEGEN_EXE) $4 $(OUT_DIR) $3 $(addprefix $(OMCI_STACK_CODEGEN_INPUT_DIR)/, $(addsuffix .tmpl, $(notdir $1 $2)))
+ for file in $(GEN_OMCI_STACK_HDRS) $(GEN_OMCI_STACK_SRCS); do \
+ $(TOP_DIR)/tools/copyright_tools/insert_copyright.pl -t c -l $(TOP_DIR)/COPYRIGHT $$file > $$file.tmp; \
+ mv $$file.tmp $$file; \
+ done
+ touch $@
+ echo "Code generation complete!"
+endef
+
+# end of ifneq ("$(GEN_SRCS)$(GEN_HDRS)$(GEN_OMCI_SRCS)$(GEN_OMCI_HDRS)$(GEN_OMCI_STACK_SRCS)$(GEN_OMCI_STACK_HDRS)", "")
+endif
+
+#
+# Dependency rules generation: --> Makefile.config.$(MOD_NAME)
+#
+
+MOD_CONFIG_FILE = $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+MOD_CONFIG_DEF = $(MOD_NAME)_DEP_DEFINED
+ifneq ("$(MOD_INC_DIRS)", "")
+ # Make sure that each directory is an absolute path
+ MOD_INCS = $(addprefix -I, $(abspath $(subst -I,,$(subst $(TOP_DIR)/,,$(MOD_INC_DIRS)))))
+else
+ MOD_INCS = -I$(SRC_DIR)
+ ifneq ("$(GEN_HDRS)", "")
+ MOD_INCS += -I$(CODEGEN_OUTPUT_DIR)
+ endif
+endif
+
+#
+# Generate Makefile.config.$(MODULE) capable of re-creating the module
+#
+moddep: $(GEN_SRCS) $(GEN_HDRS)
+ifeq (x"$(V)", x"3")
+ @echo "!!!!! moddep for MOD_NAME=$(MOD_NAME) MOD_TYPE=$(MOD_TYPE) MOD_CUSTOM=$(MOD_CUSTOM)!!!"
+endif
+ $(SILENT_BUILD)mkdir -p $(OUT_DIR_BASE)
+ @rm -fr $(MOD_CONFIG_FILE)
+ @rm -fr $(OBJS:.o=.d)
+
+ @echo "ifeq (x\"$$""(V)\", x\"2\")" >> $(MOD_CONFIG_FILE)
+ @echo " $$""(info !!! MODULE=$$""(MOD_NAME) --> $(MOD_CONFIG_FILE): $(MOD_CONFIG_DEF)=$$""($(MOD_CONFIG_DEF)), DEPS=$(MOD_DEPS))" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+
+ # Prevent double inclusion
+ @echo "ifneq (\"$$""($(MOD_CONFIG_DEF))\", \"y\")" >> $(MOD_CONFIG_FILE)
+ @echo "" >> $(MOD_CONFIG_FILE)
+ @echo "$(MOD_CONFIG_DEF) := y" >> $(MOD_CONFIG_FILE)
+ @echo "export $(MOD_NAME)_DIR := $(SRC_DIR)" >> $(MOD_CONFIG_FILE)
+ @echo "export $(MOD_NAME)_OUT_DIR := $(OUT_DIR)" >> $(MOD_CONFIG_FILE)
+
+ ifeq ("$(MODULE_IS_A_LIBRARY)", "y")
+ @echo "_skip_it := y" >> $(MOD_CONFIG_FILE)
+ else
+ @echo "_skip_it := n" >> $(MOD_CONFIG_FILE)
+ endif
+ @echo "ifneq (\"$$""(SKIP_LIB_MODULES)\", \"y\")" >> $(MOD_CONFIG_FILE)
+ @echo " _skip_it := n" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+
+ @echo "ifneq (\"$$""(_skip_it)\", \"y\")" >> $(MOD_CONFIG_FILE)
+
+ ifeq ("$(MODULE_IS_A_LIBRARY)", "y")
+ ifneq ("$(OBJS)", "")
+ @echo "EXTRA_LIBS += $(LIBS_MARKER)$(TARGET_LIB)" >> $(MOD_CONFIG_FILE)
+ @echo "EXTRA_LIBS_PATH += $(LIBS_PATH_MARKER)$(OUT_DIR)" >> $(MOD_CONFIG_FILE)
+ endif
+ ifneq ("$(MOD_LIBS)", "")
+ @echo "EXTRA_LIBS += $(MOD_LIBS)" >> $(MOD_CONFIG_FILE)
+ endif
+ ifneq ("$(MOD_LIBS_NOREC_BEFORE)", "")
+ @echo "EXTRA_LIBS_NOREC_BEFORE += $(MOD_LIBS_NOREC_BEFORE)" >> $(MOD_CONFIG_FILE)
+ endif
+ ifneq ("$(MOD_LIBS_NOREC_AFTER)", "")
+ @echo "EXTRA_LIBS_NOREC_AFTER += $(MOD_LIBS_NOREC_AFTER)" >> $(MOD_CONFIG_FILE)
+ endif
+ @echo "ifneq (x\"$$""(MOD_NAME)\", x\"$(MOD_NAME)\")" >> $(MOD_CONFIG_FILE)
+ @echo " MOD_DEPS_FILES += $(OUT_DIR_BASE)/.$(MOD_NAME)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+
+ ifeq ("$(MOD_TYPE)", "linux_lib")
+ ifneq ("$(OBJS)", "")
+ @echo "ALL_LIB_OBJS += $(LINUX_LIB_OBJECTS)" >> $(MOD_CONFIG_FILE)
+ endif
+ @echo "ifneq (x\"$$""(MOD_NAME)\", x\"$(MOD_NAME)\")" >> $(MOD_CONFIG_FILE)
+ @echo " MOD_DEPS_FILES += $(OUT_DIR_BASE)/.$(MOD_NAME)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+
+ ifeq ("$(MOD_TYPE)", "linux_module")
+ @echo "ifneq (x\"$$""(MOD_NAME)\", x\"$(MOD_NAME)\")" >> $(MOD_CONFIG_FILE)
+ @echo " KBUILD_EXTRA_SYMBOLS += $(SRC_DIR)/Module.symvers" >> $(MOD_CONFIG_FILE)
+ @echo " MOD_DEPS_FILES += $(OUT_DIR_BASE)/.$(MOD_NAME)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+
+ # Module creation rules
+ @echo "$(MOD_NAME)_$(SUBSYSTEM): $(OUT_DIR_BASE)/.$(MOD_NAME)" >> $(MOD_CONFIG_FILE)
+ @echo "" >> $(MOD_CONFIG_FILE)
+ @echo "$(OUT_DIR_BASE)/.$(MOD_NAME): .FORCE" >> $(MOD_CONFIG_FILE)
+ ifeq ("$(MOD_CUSTOM)", "y")
+ @echo " $$""(MAKE) MOD_DIR=$(MOD_DIR) -f $(MAKE_DIR)/Makefile.template $(MOD_TARGET)" >> $(MOD_CONFIG_FILE)
+ else
+ ifneq ("$(OBJS)", "")
+ @echo " $$""(MAKE) MOD_DIR=$(MOD_DIR) -f $(MAKE_DIR)/Makefile.template $(MOD_TARGET)" >> $(MOD_CONFIG_FILE)
+ endif
+ ifeq ("$(OBJS)", "")
+ @echo " if [ ! -f $(OUT_DIR_BASE)/.$(MOD_NAME) ]; then touch $(OUT_DIR_BASE)/.$(MOD_NAME); fi" >> $(MOD_CONFIG_FILE)
+ endif
+ endif
+ @echo "" >> $(MOD_CONFIG_FILE)
+ @echo ".FORCE:" >> $(MOD_CONFIG_FILE)
+ @echo "" >> $(MOD_CONFIG_FILE)
+
+ ifneq ("$(MOD_DEFS)", "")
+ @echo "EXTRA_CFLAGS += $(MOD_DEFS)" >> $(MOD_CONFIG_FILE)
+ endif
+
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+
+ # If it is a library and this file is included as someone's dependency - extend MOD_DEP_FULL_NAMES
+ # and generate a rule to rebuilt the library
+ ifneq ("$(MOD_DEPS)$(MOD_DEPS_OPT)", "")
+ @echo "ifeq (x\"$$""(V)\", x\"2\")" >> $(MOD_CONFIG_FILE)
+ @echo " $$""(info !!! Now include dependencies $(MOD_DEPS) $(MOD_DEPS_OPT)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ ifneq ("$(MOD_DEPS)", "")
+ @echo "$(MOD_NAME)_MOD_DEPS = $(MOD_DEPS)" >> $(MOD_CONFIG_FILE)
+ @echo "ifneq (x\"$$""(SKIP_DEPS)\", x\"yes\")" >> $(MOD_CONFIG_FILE)
+ @echo "include $$""($(MOD_NAME)_MOD_DEPS:%=$(OUT_DIR_BASE)/Makefile.config.%)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+ ifneq ("$(MOD_DEPS_OPT)", "")
+ @echo "$(MOD_NAME)_MOD_DEPS_OPT = $(MOD_DEPS_OPT)" >> $(MOD_CONFIG_FILE)
+ @echo "ifneq (x\"$$""(SKIP_DEPS)\", x\"yes\")" >> $(MOD_CONFIG_FILE)
+ @echo "-include $$""($(MOD_NAME)_MOD_DEPS_OPT:%=$(OUT_DIR_BASE)/Makefile.config.%)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+ @echo "ifeq (x\"$$""(V)\", x\"2\")" >> $(MOD_CONFIG_FILE)
+ @echo " $$""(info !!! $(MOD_NAME) finished including dependencies)" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+ endif
+
+ @echo "EXTRA_CFLAGS += $(MOD_INCS)" >> $(MOD_CONFIG_FILE)
+ @echo "" >> $(MOD_CONFIG_FILE)
+ @echo "endif" >> $(MOD_CONFIG_FILE)
+#
+# end of moddep: target
+#
+
+clean_module::
+ifeq ("$(MOD_TYPE)", "linux_module")
+ $(SILENT_BUILD)-test -f $(SRC_DIR)/Makefile && $(MAKE) $(KERNEL_MAKEPARMS) clean
+ $(SILENT_BUILD)cd $(SRC_DIR) && rm -fr $($(MOD_NAME)-objs) $($(MOD_NAME)-objs:../%=../.%.cmd)
+ $(SILENT_BUILD)rm -fr $(OUT_DIR_BASE)/linux_modules/$(MOD_NAME).ko
+endif
+ifeq ("$(MOD_TYPE)", "linux_lib")
+ $(SILENT_BUILD)rm -fr $(LINUX_LIB_OBJECTS)
+endif
+ $(SILENT_BUILD)cd $(SRC_DIR) && rm -fr $(patsubst %.c,.%.o.cmd,$(srcs))
+ $(SILENT_BUILD)[ ! -d $(OUT_DIR) ] || find $(OUT_DIR) -name '*.[o,d,a]' -print0 | xargs -0 rm -rf
+ $(SILENT_BUILD)[ ! -d $(OUT_DIR) ] || find $(OUT_DIR) -name '*~' -print0 | xargs -0 rm -rf
+ $(SILENT_BUILD)[ ! -d $(OUT_DIR) ] || find $(OUT_DIR) -name '*.ko' -print0 | xargs -0 rm -rf
+ $(SILENT_BUILD)[ ! -d $(OUT_DIR) ] || find $(OUT_DIR) -name '.*.cmd' -print0 | xargs -0 rm -rf
+ $(SILENT_BUILD)rm -fr $(SRC_DIR)/*.mod.c $(SRC_DIR)/modules.order $(SRC_DIR)/Module.symvers $(SRC_DIR)/.tmp_versions
+ $(SILENT_BUILD)rm -fr $(MOD_TARGET) $(OUT_DIR)/$(TARGET) $(OUT_DIR)/unitest $(TARGET_LIB_FNAME)
+ $(SILENT_BUILD)rm -fr $(ALL_LIB_OBJS)
+ $(SILENT_BUILD)rm -fr $(GEN_SRCS) $(GEN_HDRS) $(OUT_DIR)/.$(MOD_NAME)_generated_*
+ifneq ("$(MOD_NAME)", "")
+ $(SILENT_BUILD)rm -fr $(OUT_DIR_BASE)/.$(MOD_NAME)
+ $(SILENT_BUILD)rm -fr $(SRC_DIR)/.$(MOD_NAME)_in_progress
+endif
+
+clobber: clean_module
+ $(SILENT_BUILD)rm -fr $(OUT_DIR)
+
+# Optional subsystem-specific rules
+-include mk/$(SUBSYSTEM)/Makefile.$(SUBSYSTEM).rules
+
+# Generate board-specific environment if any
+board_env: $(BOARD_ENV_RULE)
+
+module_name:
+ $(info $(MOD_NAME))
diff --git a/bal_release/mk/Makefile.template b/bal_release/mk/Makefile.template
new file mode 100644
index 0000000..633e962
--- /dev/null
+++ b/bal_release/mk/Makefile.template
@@ -0,0 +1,12 @@
+# Central Makefile template
+# Builds specific module
+# Input parameters:
+# MOD_DIR
+# TOP_DIR
+
+ifeq (x"$(V)", x"1")
+ $(info Building module $(MOD_DIR))
+endif
+
+include $(MAKE_DIR)/Makefile.config
+include $(MAKE_DIR)/Makefile.rules
diff --git a/bal_release/mk/agent/modules.agent.bal b/bal_release/mk/agent/modules.agent.bal
new file mode 100644
index 0000000..5dca4f6
--- /dev/null
+++ b/bal_release/mk/agent/modules.agent.bal
@@ -0,0 +1,24 @@
+3rdparty/bcm-sdk
+3rdparty/linenoise
+src/common/bal_app_utils
+src/common/cli
+src/common/dev_log
+src/common/include
+3rdparty/maple
+src/common/os_abstraction
+src/common/os_abstraction/os_cli
+src/common/utils
+src/core/main
+src/core/util/mac
+src/core/util/switch
+src/core/util/switch/dpp
+src/core/util/switch/esw
+src/lib/libbalapi
+src/lib/libbalapicli
+src/lib/libobjmsg
+src/lib/libomcisvc
+src/lib/librscmgr
+src/lib/libtopology
+src/lib/libutils
+src/lib/libcmdline
+
diff --git a/bal_release/mk/bin_release.sh b/bal_release/mk/bin_release.sh
new file mode 100755
index 0000000..8bd0294
--- /dev/null
+++ b/bal_release/mk/bin_release.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+
+# This script is called from the main Makefile.
+# Prerequisites:
+# 1. BAL standalone or ofpal_of_agent binaries are built.
+# 2. Environment variables defined:
+# - BUILD_TARGET : bal_of_agent / bal_core
+# - BIN_RELEASE_FILE_PREFIX : binary release file prefix
+
+if [[ "$BIN_RELEASE_FILE_PREFIX" == "" ]]; then
+ echo BIN_RELEASE_FILE_PREFIX variable must be set
+ exit -1
+fi
+
+TMP_DIR=/tmp/bal_bin_release/`date +%d_%m_%Y_%H_%M_%S`
+BIN_RELEASE_FILE=$BIN_RELEASE_FILE_PREFIX.tar.gz
+BIN_RELEASE_DIR=$TMP_DIR/$BIN_RELEASE_FILE_PREFIX
+
+mkdir -p $BIN_RELEASE_DIR
+
+if [[ "$BUILD_TARGET" == "core" ]]; then
+ echo Generating BAL Release Archive $BIN_RELEASE_FILE
+ cp build/core/src/core/main/bal_core $BIN_RELEASE_DIR/
+elif [[ "$BUILD_TARGET" == "agent" ]]; then
+ echo Generating OF Agent Release Archive $BIN_RELEASE_FILE
+ cp build/agent/3rdparty/indigo/ofpal_of_agent $BIN_RELEASE_DIR/bcm_sdn_agent
+# The following are relevant only when BUILD_NC_AGENT=y, so they might not exist
+ if test -e build/agent/start_sdn_agent.sh; then cp build/agent/start_sdn_agent.sh $BIN_RELEASE_DIR; fi
+ if test -e build/agent/lib; then cp -ar build/agent/lib $BIN_RELEASE_DIR; fi
+ if test -e build/agent/bin; then cp -ar build/agent/bin $BIN_RELEASE_DIR; fi
+ if test -e build/agent/modules; then cp -ar build/agent/modules $BIN_RELEASE_DIR; fi
+ if test -e /usr/lib/libssl.so.10; then cp -ar /usr/lib/libssl.so.10 $BIN_RELEASE_DIR; fi
+ if test -e /usr/lib/libcrypto.so.10; then cp -ar /usr/lib/libcrypto.so.10 $BIN_RELEASE_DIR; fi
+else
+ echo BUILD_TARGET has unexpected value \"$BUILD_TARGET\". Must be \"core\" or \"agent\"
+ exit -1
+fi
+
+cp scripts/bal_autostart.ini $BIN_RELEASE_DIR/
+cp scripts/bal_config.ini $BIN_RELEASE_DIR/
+cp 3rdparty/bcm-sdk/rc/bal/rpc.soc.template $BIN_RELEASE_DIR
+
+cd $TMP_DIR
+tar -czf $BIN_RELEASE_FILE $BIN_RELEASE_FILE_PREFIX
+echo ./$BIN_RELEASE_FILE created
+
diff --git a/bal_release/mk/boards/wrx/board.config b/bal_release/mk/boards/wrx/board.config
new file mode 100644
index 0000000..9ca4ae0
--- /dev/null
+++ b/bal_release/mk/boards/wrx/board.config
@@ -0,0 +1,49 @@
+# WRX board
+#
+
+export CONFIG_MAC_RPC ?= n
+export CONFIG_SWITCH_RPC ?= n
+
+# Kernel tree and toolchain
+BOARD_DIR ?= $(TOP_DIR)/../boards/cur/$(BOARD)
+KERNEL_BRCM_VER = 3.0.2-m1.01
+TOOLCHAIN_PATH ?= /opt/toolchains/maple/toolchains_bin/mipscross/linux/bin
+CROSS_COMPILE = $(TOOLCHAIN_PATH)/mips64-nlm-linux-
+CROSS_LIB_PATH = $(TOOLCHAIN_PATH)/../mips64-nlm-linux/lib64
+CONFIGURE_TARGET = mips64-nlm-linux
+export TOOLCHAIN_PATH
+export CROSS_COMPILE
+export CONFIGURE_TARGET
+
+# In the moment we don't plan to build any kernel modules
+# if/when we do set OD_KERNEL=linux
+export OS_KERNEL= posix
+
+# OS for user space
+OS = posix
+
+# The following group is only needed if we decide that do need linux kernel modules
+# In this case OS_KERNEL above must be set =linux and a few additions are needed in the source tree
+KERNELDIR = $(BOARD_DIR)/linux/$(KERNEL_BRCM_VER)/linux
+KERNEL_OUTDIR ?= $(KERNELDIR)
+export KERNELDIR
+export KERNEL_OUTDIR
+KERNEL_ARCH = mips
+ARCH_FLAGS += -EB -mabi=64
+LD_ARCH_FLAGS += -melf64btsmip
+HOST_BIG_ENDIAN ?= y
+
+export KERNEL_ARCH
+export ARCH_FLAGS
+
+export KERNEL_TAR_NAME = wrx_linux-sdk.tar.bz2
+export LIBS_TAR_NAME = libraries.tar.bz2
+
+
+ifeq ("$(SUBSYSTEM)", "core")
+ # Core-specific stuff
+endif
+
+ifeq ("$(SUBSYSTEM)", "apps")
+ # Apps-specific stuff
+endif
diff --git a/bal_release/mk/clang.opts b/bal_release/mk/clang.opts
new file mode 100644
index 0000000..1b383ef
--- /dev/null
+++ b/bal_release/mk/clang.opts
@@ -0,0 +1,6 @@
+# CLANG options
+
+# CLANG tool
+export CLANG ?= clang
+export CLANG_OPTS = -Wno-unused-function
+export LLVMVER ?= 3.6
diff --git a/bal_release/mk/config.lnt b/bal_release/mk/config.lnt
new file mode 100644
index 0000000..1540792
--- /dev/null
+++ b/bal_release/mk/config.lnt
@@ -0,0 +1,104 @@
+-i/tools/arm/DS-5_5.18.0/Linux-64/include
+-wlib(0) // no complaints for libs
+-b
+-u
+-v
+-A(C99)
+-cgnu
+-d__GNUC__
+-d__FUNCTION__="FUNC"
+-fhs
++dBCMOS_TRUE=((bcmos_bool)1)
++dBCMOS_FALSE=((bcmos_bool)0)
+-strong(AzcXJzc)
+-strong(AXJb,bcmos_bool)
+-strong(, uint64_t)
+-strong(, uint32_t)
+-strong(, uint16_t)
+-strong(, uint8_t)
+-strong(, int64_t)
+-strong(, int32_t)
+-strong(, int16_t)
+-strong(, int8_t)
+-strong(, ULONG)
+-strong(, size_t)
+-sem( bcmos_fastlock_lock, thread_lock )
+-sem( bcmos_fastlock_unlock, thread_unlock )
+-sem( bcmos_sem_wait, thread_lock )
+-sem( bcmos_sem_post, thread_unlock )
+-sem( bcmos_mutex_lock, thread_lock )
+-sem( bcmos_mutex_unlock, thread_unlock )
+-function( free, bcmos_blk_pool_free )
+-function( malloc(0), bcmos_blk_pool_alloc(0) )
+-function( calloc(0), bcmos_blk_pool_calloc(0) )
+-function( malloc(0), bcmos_byte_pool_alloc(0) )
+-function( malloc(1), bcmos_byte_pool_alloc(2) )
+-function( free, bcmos_byte_pool_free )
+-function( malloc(r), bcmos_blk_pool_alloc(r) )
+-function( calloc(r), bcmos_blk_pool_calloc(r) )
+-function( malloc(r), bcmos_byte_pool_alloc(r) )
+-function( malloc, bcmos_alloc )
+-function( calloc, bcmos_calloc )
+-function( free, bcmos_free )
+-function( malloc(0), bcmdb_set_lock_read(0) )
+-function( free(0), bcmdb_set_unlock_read(0) )
+-function( malloc(0), bcmdb_set_lock_modify(0) )
+-function( free(0), bcmdb_set_unlock_modify(0) )
+-function( malloc(0), bcmdb_record_getraw_read(0) )
+-function( free(0), bcmdb_record_unlock_read(0) )
+-function( malloc(0), bcmdb_record_getraw_write(0) )
+-function( free(0), bcmdb_record_unlock_write(0) )
+-e*
++e64
++e408
++e413
++e414
++e415
++e416
++e419
++e420
++e423
++e424
++e428
++e429
++e433
++e438
++e449
++e454
++e455
++e530
++e547
++e549
++e587
++e588
++e589
++e590
++e603
++e604
++e632
++e633
++e634
++e635
++e636
++e637
++e638
++e639
++e640
++e644
++e652
++e674
++e684
++e685
++e727
++e733
++e789
++e810
++e957
+
++doffsetof(__typ,__id)=((size_t)&(((__typ*)0)->__id))
++d__attribute__(...)=
+
+// this is repeated because each invocation doubles the size of macro storage
++macros +macros +macros +macros
++macros +macros +macros +macros
+-passes(2)
diff --git a/bal_release/mk/core/Makefile.core.config b/bal_release/mk/core/Makefile.core.config
new file mode 100644
index 0000000..8ac4117
--- /dev/null
+++ b/bal_release/mk/core/Makefile.core.config
@@ -0,0 +1,19 @@
+# BAL core configuration
+#
+# Set environment, extra flags, etc.
+# In particular, set CROSS_COMPILE
+# For linux environment make sure to set also OS_KERNEL=linux, KERNELDIR, KERNEL_OUTDIR and KERNEL_ARCH
+ifneq ("$(BOARD)", "")
+ include mk/boards/$(BOARD)/board.config
+ -include mk/boards/$(BOARD)/$(TOOLCHAIN).opts
+endif
+
+include mk/$(TOOLCHAIN).opts
+
+export KERNELDIR
+export KERNEL_OUTDIR
+export KERNEL_ARCH
+export OS_KERNEL
+
+BUILD_OF_AGENT := n
+BUILD_NC_AGENT := n
diff --git a/bal_release/mk/core/Makefile.core.rules b/bal_release/mk/core/Makefile.core.rules
new file mode 100644
index 0000000..c00678b
--- /dev/null
+++ b/bal_release/mk/core/Makefile.core.rules
@@ -0,0 +1,7 @@
+# BAL core-specific rules
+#
+# Platform/board-specific rules
+# In particular, set BOARD_ENV_RULE if there is anything board-specific to be done
+ifneq ("$(BOARD)", "")
+ -include mk/boards/$(BOARD)/board.rules
+endif
diff --git a/bal_release/mk/core/modules.core.bal b/bal_release/mk/core/modules.core.bal
new file mode 100644
index 0000000..44b64c3
--- /dev/null
+++ b/bal_release/mk/core/modules.core.bal
@@ -0,0 +1,23 @@
+3rdparty/bcm-sdk
+3rdparty/linenoise
+src/common/bal_app_utils
+src/common/cli
+src/common/dev_log
+src/common/include
+3rdparty/maple
+src/common/os_abstraction
+src/common/os_abstraction/os_cli
+src/common/utils
+src/core/main
+src/core/util/mac
+src/core/util/switch
+src/core/util/switch/dpp
+src/core/util/switch/esw
+src/lib/libbalapi
+src/lib/libbalapicli
+src/lib/libobjmsg
+src/lib/librscmgr
+src/lib/libtopology
+src/lib/libutils
+src/lib/libcmdline
+src/apps/bal_cli
diff --git a/bal_release/mk/create_artifacts.sh b/bal_release/mk/create_artifacts.sh
new file mode 100755
index 0000000..193f1dc
--- /dev/null
+++ b/bal_release/mk/create_artifacts.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+#set -x
+
+# Copy config script. Look in the BAL directory first. If not found, take from the scripts
+function copy_config_script {
+ if test -n "$2"; then
+ template_dir=$2
+ else
+ template_dir=$bal_dir/scripts
+ fi
+ if [ -f $bal_dir/$1 ]; then
+ cp -a $bal_dir/$1 $target_dir/
+ else
+ cp -a $template_dir/$1 $target_dir/
+ fi
+}
+
+bal_dir=`pwd`
+
+# Copy and strip bcm_sdn_agent
+if [ "$BUILD_OF_AGENT" = "y" ]; then
+ target_dir=bcm_sdn_agent_artifacts
+ target_exec=bcm_sdn_agent
+ target_name=bcm_sdn_agent
+ build_dir=build/agent
+else
+ target_dir=bcm_bal_artifacts
+ target_name=bal_cli
+ target_exec=src/apps/bal_cli/bal_cli
+ build_dir=build/core
+fi
+
+cd $build_dir
+echo "Creating $target_name build artifacts in `pwd`/$target_dir"
+rm -fr $target_dir
+mkdir -p $target_dir
+
+echo "Stripping $target_name and extracting debug symbols"
+${CROSS_COMPILE}objcopy --strip-debug --strip-unneeded $target_exec $target_dir/$target_name
+${CROSS_COMPILE}objcopy --only-keep-debug $target_exec $target_name.debug
+${CROSS_COMPILE}objcopy --add-gnu-debuglink=$target_name.debug $target_dir/$target_name
+echo "Stripping complete"
+
+if [ "$JENKINS_BUILD" == "y" ]; then
+ cp $bal_dir/../../../build_info.log build_info.log
+ tar -czf $target_name.debug.tar.gz $target_name.debug build_info.log
+ rm build_info.log
+else
+ tar -czf $target_name.debug.tar.gz $target_name.debug
+fi
+
+# Copy init scripts. Look in the BAL directory first. If not found, take from the scripts
+copy_config_script bal_config.ini
+copy_config_script bal_autostart.ini
+copy_config_script bal_topology.ini
+# Rename the bal_topology.ini file to avoid bringup issues
+mv $target_dir/bal_topology.ini $target_dir/bal_topology.ini.sample
+copy_config_script rpc.soc.template $bal_dir/3rdparty/bcm-sdk/rc/bal
+cp -ar ../../3rdparty/bcm-sdk/rc $target_dir/switch_rc
+rm -fr $target_dir/switch_rc/arad $target_dir/switch_rc/kt2
+
+if [ "$BUILD_NC_AGENT" = "y" ]; then
+ cp -ar lib $target_dir/
+ # for SDN-PAL running on x86, copy the libssl and libcrypto
+ if [ "$BOARD" = "" ]; then
+ echo "Copying libcrypto and libssl for x86 target"
+ cp /usr/lib/libssl.so.10 /usr/lib/libcrypto.so.10 $target_dir/lib/
+ fi
+ cp -ar modules $target_dir/
+ cp -a start_sdn_agent.sh $target_dir/
+ cp -a start_netopeer_cli.sh $target_dir/
+ cp -a bin/netopeer-cli $target_dir/
+fi
+
+if [ "$BOARD" = "wrx" ]; then
+ echo "Copying SVK4 specific scripts and files"
+ copy_config_script bal_setup_svk4.sh
+ echo 'if [ "${PWD}" != "/broadcom" ]; then echo "ERROR: Your archive file must be expanded into /broadcom before running this script"; else if [ -d /etc/rcS.d ]; then echo "Installing bal startup script in /etc/rcS.d" && pushd /etc/rcS.d >/dev/null && rm -f S99balsetup && ln -s /broadcom/bal_setup_svk4.sh S99balsetup && popd >/dev/null && echo "Installing svk4 scripts" && cp -f switch_rc/svk4/* . && touch /etc/svk4 && cat bal_config.ini | sed s/"of_devs=1"/"of_devs=2"/g > bal_config.ini.svk4_devs && cat bal_config.ini.svk4_devs | sed s/"num_nni_ports=1"/"num_nni_ports=6"/g > bal_config.ini.svk4_devs_nni && cat bal_config.ini.svk4_devs_nni | sed s/"maptable=3"/"maptable=4"/g > bal_config.ini && rm -f bal_config.ini.svk4_devs && rm -f bal_config.ini.svk4_devs_nni; fi; fi' > svk4_install.sh
+ chmod 755 svk4_install.sh
+ cp svk4_install.sh $target_dir
+ echo "Please run svk4_install.sh (only on SVK4 hardware!)" > README.svk4
+ cp ../../3rdparty/maple/sdk/build/fs/svk_init_startup.sh $target_dir/
+ if [ "$JENKINS_BUILD" == "y" ]; then
+ cp ../../3rdparty/bcm-sdk/build-wrx/sdk-all-*/build/projects/xPON_OLT/jenkins/jobs/Bal.Synced.bcm-sdk-*.Wrx/workspace/bal/cur/3rdparty/bcm-sdk/linux-*-bde.ko $target_dir/
+ fi
+ cp README.svk4 $target_dir/ && rm README.svk4
+fi
+
+if [ "$JENKINS_BUILD" == "y" ]; then
+ echo "Including build_info.log in the archive"
+ cp $bal_dir/../../../build_info.log $target_dir/
+fi
+
+archive=$target_dir.tar.gz
+echo "Archiving artifacts in `pwd`/$archive"
+tar -czf $archive $target_dir
+echo "Archive contains:"
+tar tzvf $archive
+
+
diff --git a/bal_release/mk/gcc.opts b/bal_release/mk/gcc.opts
new file mode 100644
index 0000000..ccdcf32
--- /dev/null
+++ b/bal_release/mk/gcc.opts
@@ -0,0 +1,56 @@
+EXTRA_CFLAGS += -Wall -Werror
+ARFLAGS = r
+
+BLD_CC_HOST = $(CCACHE) gcc
+BLD_CC = $(CCACHE) $(CROSS_COMPILE)gcc
+BLD_AS = $(CCACHE) $(CROSS_COMPILE)gcc
+BLD_AR = $(CROSS_COMPILE)ar
+BLD_DEP = $(BLD_CC)
+
+# Maple SDK requires C99
+CFLAGS += -std=c99
+ifeq ("$(ENABLE_EXTRA_WARNINGS)", "y")
+ CFLAGS += -Wextra -Wbad-function-cast -Wcast-align -Wcast-qual -Wchar-subscripts
+ CFLAGS += -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wredundant-decls
+ CFLAGS += -Wstrict-prototypes -Wparentheses -Wswitch -Wswitch-default -Wunused -Wuninitialized -Wunused-but-set-variable
+ CFLAGS += -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare
+ CFLAGS += -Wshadow -Wno-inline
+endif
+
+BUILD_DEPS_IN_CC ?= y
+export BUILD_DEPS_IN_CC
+
+ifeq ("$(BUILD_DEPS_IN_CC)", "y")
+ CFLAGS += -MMD -MP
+endif
+
+ifeq ("$(CROSS_COMPILE)", "")
+ ARCH_FLAGS += -m32 -march=i386
+ LD_ARCH_FLAGS += -m elf_i386 --oformat=elf32-i386
+ SIMULATION_BUILD ?= y
+ export SIMULATION_BUILD
+ GCCVER ?= 4.8.1
+ export GCCVER
+ # Temporary, until bad cast in bcm_dev_log_task.c is fixed (SWMAPLE-2123)
+ CFLAGS += -Wno-strict-aliasing
+ CONFIGURE_TARGET ?= i586-linux-gnu
+endif
+
+ifeq ("$(EXPORT_DYNAMIC_SYMBOLS)", "y")
+ ARCH_FLAGS += -Wl,-export-dynamic
+endif
+
+ifneq ("$(SIMULATION_BUILD)", "y")
+ EXTRA_CFLAGS += -Wframe-larger-than=16384
+endif
+
+LIBS_MARKER =-l
+LIBS_PATH_MARKER =-L
+LIBS_START_MARKER = -Wl,--start-group
+LIBS_END_MARKER = -Wl,--end-group
+
+# Debug and release optimization options. Can be overwritten in Makefile.config.$(PLATFORM)
+DEBUG_O_CFLAGS ?= -g -gdwarf-3 -O0
+DEBUG_O_LFLAGS ?= -g
+RELEASE_O_CFLAGS ?= -g -gdwarf-3 -O0
+RELEASE_O_LFLAGS ?= -g
diff --git a/bal_release/mk/lint.sh b/bal_release/mk/lint.sh
new file mode 100755
index 0000000..9b89478
--- /dev/null
+++ b/bal_release/mk/lint.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+LINT=/projects/xpon_co_lint/bin/flint
+if [ -e $LINT ]; then
+if [ -w "${@: -1}" ]; then
+ $LINT $*
+else
+ echo "Skipping non-writable file ${@: -1}"
+fi
+else
+ echo "ERROR: lint executable $LINT doesn't exist"
+fi
diff --git a/bal_release/mk/src_release.sh b/bal_release/mk/src_release.sh
new file mode 100755
index 0000000..0db73d8
--- /dev/null
+++ b/bal_release/mk/src_release.sh
@@ -0,0 +1,296 @@
+#!/bin/bash
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+
+# This script is called from the main Makefile.
+# Prerequisites:
+# 1. BAL standalone or ofpal_of_agent binaries are built.
+# 2. Environment variables defined:
+# - SRC_RELEASE_FILE_PREFIX : source release file prefix (string)
+# - INCLUDE_MAPLE_SDK_RELEASE : include maple SDK release (if set, then Maple SDK release is included, and its zip actually contains BAL's code, without OMCI and SDN-PAL).
+
+if [[ "$SRC_RELEASE_FILE_PREFIX" == "" ]]; then
+ echo SRC_RELEASE_FILE_PREFIX variable must be set
+ exit -1
+fi
+
+TMP_DIR=/tmp/bal_src_release/`date +%d_%m_%Y_%H_%M_%S`
+
+BAL_RELEASE_PREFIX=bal.$SRC_RELEASE_FILE_PREFIX
+SDN_PAL_RELEASE_PREFIX=sdn_pal.$SRC_RELEASE_FILE_PREFIX
+OMCI_RELEASE_PREFIX=omci.$SRC_RELEASE_FILE_PREFIX
+
+BAL_RELEASE_DIR=$TMP_DIR/bal/$SRC_RELEASE_FILE_PREFIX
+SDN_PAL_RELEASE_DIR=$TMP_DIR/sdn_pal/$SRC_RELEASE_FILE_PREFIX
+OMCI_RELEASE_DIR=$TMP_DIR/omci/$SRC_RELEASE_FILE_PREFIX
+
+BAL_SRC_RELEASE_FILE=$BAL_RELEASE_PREFIX.tar.gz
+SDN_PAL_SRC_RELEASE_FILE=$SDN_PAL_RELEASE_PREFIX.tar.gz
+OMCI_SRC_RELEASE_FILE=$OMCI_RELEASE_PREFIX.tar.gz
+
+CP="cp -R --parents"
+
+if [ -d build/core ]; then
+ SUBSYSTEM=core
+elif [ -d build/agent ]; then
+ SUBSYSTEM=agent
+else
+ echo Neither build/core nor build/agent subdirectories exist
+ exit -1
+fi
+
+if [ ! -f build/$SUBSYSTEM/src/common/include/bal_model_ids.h ]; then
+ echo Generated BAL header files are missing. Build BAL first
+ exit -1
+fi
+
+if [ ! -f build/$SUBSYSTEM/src/lib/libomcisvc/omci_model_ids.h ]; then
+ echo Generated OMCI SVC header files are missing. Build OMCI SVC first
+ exit -1
+fi
+
+mkdir -p $BAL_RELEASE_DIR
+mkdir -p $SDN_PAL_RELEASE_DIR
+mkdir -p $OMCI_RELEASE_DIR
+
+# Copy auto-generated files first, as we will need to do "make clean" afterwards (because some 3rdparty libraries have binaries in the source directories and we need to clean those).
+# 1. BAL
+mkdir -p $BAL_RELEASE_DIR/src/common/include
+cp \
+ build/$SUBSYSTEM/src/common/include/bal_model_ids.h \
+ build/$SUBSYSTEM/src/common/include/bal_model_types.h \
+ $BAL_RELEASE_DIR/src/common/include
+
+mkdir -p $BAL_RELEASE_DIR/src/lib/libobjmsg
+cp \
+ build/$SUBSYSTEM/src/lib/libobjmsg/bal_model_funcs.c \
+ build/$SUBSYSTEM/src/lib/libobjmsg/bal_obj_msg_pack_unpack.c \
+ build/$SUBSYSTEM/src/lib/libobjmsg/bal_model_funcs.h \
+ build/$SUBSYSTEM/src/lib/libobjmsg/bal_obj_msg_pack_unpack.h \
+ $BAL_RELEASE_DIR/src/lib/libobjmsg
+
+mkdir -p $BAL_RELEASE_DIR/src/lib/libbalapicli
+cp \
+ build/$SUBSYSTEM/src/lib/libbalapicli/bal_api_cli_helpers.h \
+ build/$SUBSYSTEM/src/lib/libbalapicli/bal_api_cli_helpers.c \
+ build/$SUBSYSTEM/src/lib/libbalapicli/bal_api_cli_handlers.c \
+ $BAL_RELEASE_DIR/src/lib/libbalapicli
+
+# 2. OMCI
+# Copy auto-generated files to the sources directory
+mkdir -p $OMCI_RELEASE_DIR/src/lib/libomcisvc
+cp \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_model_ids.h \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_model_types.h \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_model_funcs.h \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_model_funcs.c \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_cli_handlers.c \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_cli_helpers.h \
+ build/$SUBSYSTEM/src/lib/libomcisvc/omci_cli_helpers.c \
+ $OMCI_RELEASE_DIR/src/lib/libomcisvc
+
+# Clean
+make clean
+make clean BUILD_NC_AGENT=y
+
+# Now recreate the subsystem directory (wiped out by the make clean), because the archive artifacts from the build will go there
+mkdir -p build/$SUBSYSTEM
+
+# Now main copy
+
+# 1. BAL
+
+# Copy only relevant sources.
+for file in `find mk -maxdepth 1 -type f`; do cp -L --parents $file $BAL_RELEASE_DIR; done
+$CP 3rdparty/bcm-sdk/make $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/Makefile $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/Makefile.sdk $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/make_ing_dir.sh $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/rc $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/*.patch $BAL_RELEASE_DIR/
+$CP 3rdparty/bcm-sdk/sh $BAL_RELEASE_DIR/
+$CP 3rdparty/linenoise $BAL_RELEASE_DIR/
+$CP 3rdparty/maple/Makefile $BAL_RELEASE_DIR/
+$CP branch.info $BAL_RELEASE_DIR/
+chmod +w $BAL_RELEASE_DIR/branch.info
+echo PERFORCE_REVISION=$BUILD_PERFORCE_REVISION >> $BAL_RELEASE_DIR/branch.info
+$CP COPYRIGHT $BAL_RELEASE_DIR/
+$CP doxygen $BAL_RELEASE_DIR/
+$CP Makefile $BAL_RELEASE_DIR/
+$CP README* $BAL_RELEASE_DIR/
+$CP mk/boards $BAL_RELEASE_DIR/
+$CP mk/core/Makefile* $BAL_RELEASE_DIR/
+$CP mk/core/modules.core.bal $BAL_RELEASE_DIR/
+$CP mk/agent/modules.agent.bal $BAL_RELEASE_DIR/
+$CP scripts $BAL_RELEASE_DIR/
+$CP src/common $BAL_RELEASE_DIR/
+$CP src/core $BAL_RELEASE_DIR/
+$CP src/apps/bal_cli $BAL_RELEASE_DIR/
+$CP src/datamodel/bal.objset $BAL_RELEASE_DIR/
+$CP src/lib/common $BAL_RELEASE_DIR/
+$CP src/lib/libbalapi $BAL_RELEASE_DIR/
+$CP src/lib/libbalapicli $BAL_RELEASE_DIR/
+$CP src/lib/libobjmsg $BAL_RELEASE_DIR/
+$CP src/lib/librscmgr $BAL_RELEASE_DIR/
+$CP src/lib/libtopology $BAL_RELEASE_DIR/
+$CP src/lib/libutils $BAL_RELEASE_DIR/
+$CP src/lib/libcmdline $BAL_RELEASE_DIR/
+$CP tools $BAL_RELEASE_DIR/
+
+# The following file will indicate a release build
+touch $BAL_RELEASE_DIR/.release_build
+
+# Add write permission to all the copied files
+find $BAL_RELEASE_DIR -type f | xargs -d '\n' chmod +w
+
+# Remove codegen_templates and .ccache
+find $BAL_RELEASE_DIR -name codegen_templates | xargs rm -rf
+find $BAL_RELEASE_DIR -name .ccache | xargs rm -rf
+
+cd $BAL_RELEASE_DIR/..
+tar -czf $BAL_SRC_RELEASE_FILE $SRC_RELEASE_FILE_PREFIX
+cd - > /dev/null
+mv $TMP_DIR/bal/$BAL_SRC_RELEASE_FILE .
+echo ./$BAL_SRC_RELEASE_FILE created
+
+# 2. SDN-PAL
+
+# Copy only relevant sources.
+for file in `find mk -maxdepth 1 -type f`; do cp --parents $file $SDN_PAL_RELEASE_DIR; done
+$CP 3rdparty/loci $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libxml2 $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libxslt $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libgpg-error $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libgcrypt $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libssh $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libcurl $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/libnetconf $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/indigo $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/openyuma $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/yang/BBF $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/yang/IANA $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/yang/IETF $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/pyang $SDN_PAL_RELEASE_DIR/
+$CP 3rdparty/netopeer $SDN_PAL_RELEASE_DIR/
+$CP mk/agent/Makefile* $SDN_PAL_RELEASE_DIR/
+$CP mk/agent/modules.agent.sdn_pal $SDN_PAL_RELEASE_DIR/
+$CP src/agent $SDN_PAL_RELEASE_DIR/
+$CP src/netconf $SDN_PAL_RELEASE_DIR/
+$CP src/ofpal $SDN_PAL_RELEASE_DIR/
+
+# Add write permission to all the copied files
+find $SDN_PAL_RELEASE_DIR -type f | xargs -d '\n' chmod +w
+
+# Remove .ccache
+find $SDN_PAL_RELEASE_DIR -name .ccache | xargs rm -rf
+
+cd $SDN_PAL_RELEASE_DIR/..
+tar -czf $SDN_PAL_SRC_RELEASE_FILE $SRC_RELEASE_FILE_PREFIX
+cd - > /dev/null
+mv $TMP_DIR/sdn_pal/$SDN_PAL_SRC_RELEASE_FILE .
+echo ./$SDN_PAL_SRC_RELEASE_FILE created
+
+# 3. OMCI
+
+# Copy only relevant sources.
+$CP mk/core/modules.core.omci $OMCI_RELEASE_DIR/
+$CP mk/agent/modules.agent.omci $OMCI_RELEASE_DIR/
+$CP src/datamodel/omci* $OMCI_RELEASE_DIR/
+$CP src/lib/libomcistack $OMCI_RELEASE_DIR/
+$CP src/lib/libomcisvc $OMCI_RELEASE_DIR/
+
+# Remove OCS OMCI stack from modules.*.omci
+sed -i '/3rdparty\/ocs_omci/d' $OMCI_RELEASE_DIR/mk/core/modules.core.omci
+sed -i '/3rdparty\/ocs_omci/d' $OMCI_RELEASE_DIR/mk/agent/modules.agent.omci
+
+# Add write permission to all the copied files
+find $OMCI_RELEASE_DIR -type f | xargs -d '\n' chmod +w
+
+# Remove codegen_templates and .ccache
+find $OMCI_RELEASE_DIR -name codegen_templates | xargs rm -rf
+find $OMCI_RELEASE_DIR -name .ccache | xargs rm -rf
+
+# Add a flag to OMCI SVC's Makefile, so that when OMCI package is extracted, builds will include real OMCI SVC, not stubs.
+echo "USE_BCM_OMCI_SVC_IN_RELEASE=y" >> $OMCI_RELEASE_DIR/src/lib/libomcisvc/Makefile.config.omci
+
+cd $OMCI_RELEASE_DIR/..
+tar -czf $OMCI_SRC_RELEASE_FILE $SRC_RELEASE_FILE_PREFIX
+cd - > /dev/null
+mv $TMP_DIR/omci/$OMCI_SRC_RELEASE_FILE .
+echo ./$OMCI_SRC_RELEASE_FILE created
+
+# If INCLUDE_MAPLE_SDK_RELEASE is defined, then we create a maple release that will wrap the BAL release.
+if [[ "$INCLUDE_MAPLE_SDK_RELEASE" != "" ]]; then
+ OLD_DIR=`pwd`
+ BAL_MAPLE_RELEASE_DIR=$TMP_DIR/bal_maple_release
+ ./3rdparty/maple/cur/scripts/rel_delivery.sh $MAPLE_REL_DELIVERY_PREFIX
+ BCM68620_ZIP_FILE=`ls ./3rdparty/maple/cur/SW-BCM68620*.zip`
+ mkdir -p $BAL_MAPLE_RELEASE_DIR/bcm68620_release
+ unzip $BCM68620_ZIP_FILE -d $BAL_MAPLE_RELEASE_DIR/bcm68620_release
+
+ cd $BAL_MAPLE_RELEASE_DIR
+ ln -s bcm68620_release/release/docs docs
+
+ mkdir -p bal_release
+ cd $BAL_RELEASE_DIR
+ $CP . $BAL_MAPLE_RELEASE_DIR/bal_release/
+ cd $BAL_MAPLE_RELEASE_DIR/bal_release/3rdparty/maple
+ ln -s ../../../bcm68620_release cur
+
+ cd $BAL_MAPLE_RELEASE_DIR
+ zip -y -r `basename $BCM68620_ZIP_FILE` ./*
+ cd $OLD_DIR
+ mv $BAL_MAPLE_RELEASE_DIR/`basename $BCM68620_ZIP_FILE` .
+ echo `basename ./$BCM68620_ZIP_FILE` created
+fi
+
+echo Instructions of how to extract and compile source release packages exist in `ls README*` files
+
+rm -rf $TMP_DIR
+
diff --git a/bal_release/scripts/bal_autostart.ini b/bal_release/scripts/bal_autostart.ini
new file mode 100644
index 0000000..129eb49
--- /dev/null
+++ b/bal_release/scripts/bal_autostart.ini
@@ -0,0 +1,117 @@
+# ========================================================================
+#
+# This is a sample bal_autostart.ini file. If used, it must reside in
+# the same directory as the bcm_sdn_agent executable.
+#
+# Examples for EPON ,GPON, XGPON1, and XGSPON systems are given below. You cannot mix
+# EPON / GPON / XGPON1 / XGSPON entries in this file. Systems are assumed to be either
+# EPON or GPON or XGPON1 or XGSPON (as determined by the entry for topology.pon_mode in
+# the bal_config.ini file). NGPON2 systems are not supported by the autostart feature
+# or BAL code at this time.
+#
+# ========================================================================
+# This is a sample autostart script for a MAPLE EPON system,
+# where ONUs are identified by their MAC address
+#
+# NOTE: This script is only useable on an SDN version
+# of BAL, that is, with the bcm_sdn_agent.
+#
+# On startup, the bcm_sdn_agent code reads this autostart file,
+# then:
+# - brings up the access-terminal
+# - brings up each interface specified in the entry list
+# - brings up a subscriber-terminal for each ONU entry
+#
+# ONU IDs can overlap on different PON interfaces
+#
+# Entry format for an EPON system is:
+# onu=ONU ID, int=PON INTERFACE ID, mac=MAC ADDRESS OF THE ONU
+# e.g.
+# onu=3, int=2, mac=00:33:23:33:33:98
+# ========================================================================
+#
+# Uncomment-out entries below and modify them for your EPON system
+#
+#onu=1, int=0, mac=00:10:18:ad:69:d0
+#onu=6, int=0, mac=00:10:18:ad:63:38
+#onu=3, int=2, mac=00:10:18:ad:66:74
+#onu=12, int=0, mac=00:10:18:ad:29:32
+#onu=3, int=1, mac=00:10:18:ad:59:22
+#onu=3, int=0, mac=00:10:18:ad:68:44
+
+
+
+# ========================================================================
+# This is a sample autostart script for a MAPLE GPON system,
+# where ONUs are identified by their password and serial number
+#
+# NOTE: This script is only useable on an SDN version
+# of BAL, that is, with the bcm_sdn_agent
+#
+# On startup, the bcm_sdn_agent code reads this autostart file,
+# then:
+# - brings up the access-terminal
+# - brings up each interface specified in the entry list
+# - brings up a subscriber-terminal for each ONU entry
+#
+# ONU IDs can overlap on different PON interfaces
+#
+# Entry format for an GPON system is:
+# onu=ONU ID, int=PON INTERFACE ID, vend=VENDOR ID, pass=PASSWORD
+# e.g.
+# onu=3, int=2, vend=VENDOR ID FROM ONU LABEL, pass=ONU PASSWORD
+#
+# NOTE: If bcm_sdn_agent is started in autonoumous ONU activation mode (-O or --auto_activate command line option),
+# vend and pass parameters should be set as 0. In this case, the system does not bring the
+# subscriber terminal up. The subscriber terminal will be activated automatically when discovered.
+# Note that ONU entries with with vend & pass equal and not-equal 0 can be mixed. In this case,
+# some subscriber terminals will be pre-configured, before they are discovered
+# ===================================================================
+#
+# Uncomment-out entries below and modify them for your GPON system
+#
+#onu=1, int=0, vend=4252434d01946121, pass=31323334353637383930
+#onu=6, int=0, vend=4252434d01946132, pass=31323334353637383930
+#
+# Uncomment the entry below if bcm_sdn_agent is started in autonomous ONU
+# activation mode (-O or --auto_activate). The entry below will cause PON
+# interface 2 to be enabled. ONUs will be activated automatically when discovered
+#
+#onu=1, int=2, vend=00, pass=00
+
+
+# ========================================================================
+# This is a sample autostart script for a MAPLE XGPON1 or XGSPON system,
+# where ONUs are identified by their password and registration ID
+#
+# NOTE: This script is only useable on an SDN version
+# of BAL, that is, with the bcm_sdn_agent
+#
+# On startup, the bcm_sdn_agent code reads this autostart file,
+# then:
+# - brings up the access-terminal
+# - brings up each interface specified in the entry list
+# - brings up a subscriber-terminal for each ONU entry
+#
+# ONU IDs can overlap on different PON interfaces
+#
+# Entry format for an XGPON1 or XGSPON system is:
+# onu=ONU ID, int=PON INTERFACE ID, vend=VENDOR ID, registration_id=REGISTRATION_ID
+# e.g.
+# onu=3, int=2, vend=VENDOR ID FROM ONU LABEL, registration_id=REGISTRATION_ID
+#
+# As in case with GPON, bcm_sdn_agent controlling XGPON1 or XGSPON system can be started in autonomous
+# ONU activation mode. In this case vend and registration_id should be set 0.
+# The ONU will be activated automatically when discovered
+# ===================================================================
+#
+# Uncomment-out entries below and modify them for your XGPON1 or XGSPON system
+#
+#onu=1, int=0, vend=4252434d01946121, registration_id=202020202020202020202020202020202020202020202020202020202020202020202020
+#onu=6, int=0, vend=4252434d01946132, registration_id=202020202020202020202020202020202020202020202020202020202020202020202020
+#
+# Uncomment the entry below if bcm_sdn_agent is started in autonomous ONU
+# activation mode (-O or --auto_activate). The entry below will cause PON
+# interface 2 to be enabled. ONUs will be activated automatically when discovered
+#
+#onu=1, int=2, vend=00, registration_id=00
diff --git a/bal_release/scripts/bal_config.ini b/bal_release/scripts/bal_config.ini
new file mode 100644
index 0000000..a48ab23
--- /dev/null
+++ b/bal_release/scripts/bal_config.ini
@@ -0,0 +1,24 @@
+iwf_mode=direct
+# Mapping table between Qumran and Maple: 3-separate QaX/Maple SVKs, 4-SVK4
+intf_maptable=3
+num_nni_ports=1
+# UDP port where bcm.user listens for pkt_send messages from core (needed for remote bcm.user only!)
+pkt_send_svr_listen_port=50002
+# UDP port where the core listens for pkt_rcv message from bcm.user (needed for remote bcm.user only!)
+trap_udp_port=50001
+
+# The following topology configuration (currently commented out) is an alternative for bal_topology.ini.
+# In case both exist, bal_topology.ini takes precedence over this configuration.
+topology.num_of_devs=1
+topology.num_of_pons_per_dev=2
+# Allowed pon modes are: gpon|xgpon|xgs|ngpon2|epon_tdma|epon_1g|epon_10g
+topology.pon_mode=xgs
+
+#enable (y) or disable (n) loopback mode in MAC (does not need access to Maple HW if enabled)
+#mac_loopback=y
+
+# Enable NNI auto-negotiation on NNI port <n>.
+# It is known to work on NNI0 with some 1G transceivers, however
+# this mode wasn't tested on NNI interfaces other than 0 and/or with different transceivers.
+# Use at your own risk
+# autoneg_nni<n>=y
diff --git a/bal_release/scripts/bal_setup_svk4.sh b/bal_release/scripts/bal_setup_svk4.sh
new file mode 100755
index 0000000..ceb1cc2
--- /dev/null
+++ b/bal_release/scripts/bal_setup_svk4.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Start bal devices
+#
+
+case "$1" in
+ start)
+ echo -n "Starting bal devices: "
+ /broadcom/mk_bcm_node.sh
+ /broadcom/svk_init_startup.sh
+ echo "OK"
+ ;;
+ stop)
+ echo "OK"
+ ;;
+ restart|reload)
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart}"
+ exit 1
+esac
+
+exit $?
diff --git a/bal_release/scripts/bal_topology.ini b/bal_release/scripts/bal_topology.ini
new file mode 100644
index 0000000..4cf96ec
--- /dev/null
+++ b/bal_release/scripts/bal_topology.ini
@@ -0,0 +1,18 @@
+# Logical PON ID, PON Mode (gpon|xgpon|epon_10g|xgs|ngpon2), Physical Device ID, Physical PON ID
+# Comments below contain gpon configuration example
+#0, gpon, 0, 0
+#1, gpon, 0, 1
+#2, gpon, 0, 2
+#3, gpon, 0, 3
+#4, gpon, 0, 4
+#5, gpon, 0, 5
+#6, gpon, 0, 6
+#7, gpon, 0, 7
+#8, gpon, 0, 8
+#9, gpon, 0, 9
+#10, gpon, 0, 10
+#11, gpon, 0, 11
+#12, gpon, 0, 12
+#13, gpon, 0, 13
+#14, gpon, 0, 14
+#15, gpon, 0, 15
diff --git a/bal_release/scripts/bcm_user_start_stop b/bal_release/scripts/bcm_user_start_stop
new file mode 100755
index 0000000..0e3985c
--- /dev/null
+++ b/bal_release/scripts/bcm_user_start_stop
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+# Start/Stop BCM.USER
+#
+
+#
+# Set the directory path to bcm.user, or
+# allow the user to specify the path to bcm.user as the second argument when calling this script
+# (the first argument must be one of: [ start, stop ]
+#
+if [ -z $2 ]; then
+
+# Look for bcm.user, set the starting directory appropriately, or
+# simple exit if not found
+#
+if [ -f /mnt/bcm.user ]; then
+BCM_USER_BIN_DIR=/mnt/
+elif [ -f /broadcom/bcm.user ]; then
+BCM_USER_BIN_DIR=/broadcom
+elif [ -f /opt/bcm56450/bcm.user ]; then
+BCM_USER_BIN_DIR=/opt/bcm56450
+elif [ -f ./bcm.user ]; then
+BCM_USER_BIN_DIR=.
+else
+echo "cannot find bcm.user, exiting"
+exit 1
+fi
+
+else # the user may choose the starting directory directly using the second argment
+BCM_USER_BIN_DIR=$2
+fi
+
+case "$1" in
+ start)
+ echo -n "Starting bcm.user: "
+ cd ${BCM_USER_BIN_DIR}
+ lsmod | grep -q linux_user_bde > /dev/null
+ if [ "$?" == "0" ]; then
+ rmmod linux_user_bde
+ echo -n "(-user)"
+ fi
+
+ lsmod | grep -q linux_kernel_bde > /dev/null
+ if [ "$?" == "0" ]; then
+ rmmod linux_kernel_bde
+ echo -n "(-kernel)"
+ fi
+
+#
+# The linux_kernel_bde and linux_user_bde modules are loaded by the bcm.user executable
+#
+
+# Create the linux device file, if it does not already exist
+ if [ ! -c /dev/linux-user-bde ]; then
+ mknod /dev/linux-user-bde c 126 0
+ fi
+ ./bcm.user
+ echo "OK"
+ ;;
+ stop)
+ echo -n "Stopping bcm.user: "
+ pkill -f bcm.user
+ echo "OK"
+ ;;
+ restart|reload)
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart}"
+ exit 1
+esac
+
+exit $?
diff --git a/bal_release/scripts/maple_start_stop b/bal_release/scripts/maple_start_stop
new file mode 100755
index 0000000..bd81d75
--- /dev/null
+++ b/bal_release/scripts/maple_start_stop
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Start/Stop Maple
+#
+case "$1" in
+ start)
+ echo -e "Checking if svk_init.sh calls trx_init.sh\n"
+ cd /opt/bcm68620
+ if [ ! -e trx_init.sh ]; then
+ echo "trx_init.sh not present" && cd - && exit 1
+ fi
+ if [ -z "`grep "./bcm_user_appl < trx_init.sh" svk_init.sh`" ]; then
+ echo "svk_init.sh does not call trx_init.sh" && cd - && exit 1
+ elif [[ ! -z "`grep "./bcm_user_appl < trx_init.sh" svk_init.sh | grep "^\s*#\s*"`" ]]; then
+ echo "call to trx_init.sh is commented out in svk_init.sh" && cd - && exit 1
+ fi
+
+ echo -n "Starting MAPLE: "
+ cd /opt/bcm68620 && ./svk_init.sh --proxy 40000
+ ;;
+ stop)
+ echo -n "Stopping Maple: "
+ pkill -f bcm_user_appl
+ if [ ! -z "`lsmod | grep -m 1 coop_dba_linux`" ]; then
+ rmmod coop_dba_linux
+ fi
+ if [ ! -z "`lsmod | grep -m 1 bcm_dev_ctrl_linux`" ]; then
+ rmmod bcm_dev_ctrl_linux
+ fi
+ if [ ! -z "`lsmod | grep -m 1 i2c_devs`" ]; then
+ rmmod i2c_devs.ko
+ fi
+ if [ ! -z "`lsmod | grep -m 1 os_linux`" ]; then
+ rmmod os_linux.ko
+ fi
+ if [ ! -z "`lsmod | grep -m 1 ll_pcie`" ]; then
+ rmmod ll_pcie.ko
+ fi
+ if [ -e /dev/maple_dev_ctrl ]; then
+ rm /dev/maple_dev_ctrl
+ fi
+ LOCK_DIR_INIT=/tmp/bcm68620_svk_init
+ LOCK_DIR_KERNEL_LOG_OWNED=/tmp/bcm68620_kernel_log_owned
+ rm -fr $LOCK_DIR_INIT
+ rm -fr $LOCK_DIR_KERNEL_LOG_OWNED
+ echo "OK"
+ ;;
+ restart|reload)
+ "$0" stop
+ "$0" start
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart}"
+ exit 1
+esac
+
+exit $?
diff --git a/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all.py b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all.py
new file mode 100644
index 0000000..16e3b1f
--- /dev/null
+++ b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all.py
@@ -0,0 +1,112 @@
+# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+import logging
+
+from ryu.base import app_manager
+from time import sleep
+from ryu.controller import ofp_event
+from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
+from ryu.controller.handler import set_ev_cls
+from ryu.ofproto import ofproto_v1_3
+from ryu.lib.packet import packet
+from ryu.lib.packet import ethernet
+from ryu.lib import addrconv
+
+LOG = logging.getLogger('ryu.app.pon_topology')
+
+class PonTopology13(app_manager.RyuApp):
+ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+
+ def __init__(self, *args, **kwargs):
+ super(PonTopology13, self).__init__(*args, **kwargs)
+ self.mac_to_port = {}
+
+ @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
+ def switch_features_handler(self, ev):
+ datapath = ev.msg.datapath
+
+ # This does nothing if flows have not been previously configured in the OF agent
+ self.del_all_flows(datapath)
+
+ # Configure the flows (VID 100)
+ #
+ # Ports 1-128 are implicitly mapped to UNI-0 on ONU 1->128
+ # Ports 129 and above are implicitly mapped to OLT NNI-0 and above
+ self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
+ self.add_vid_flow(datapath,10001, 129, 1, 100, 0)
+
+ sleep(1)
+ self.send_barrier(datapath)
+
+ sleep(5)
+
+ self.del_all_flows(datapath)
+
+ @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
+ def port_status_handler(self, ev):
+ LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)
+
+ def add_meter(self, datapath, meter_id, rate):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
+ mod = parser.OFPMeterMod(datapath=datapath,command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=meter_id, bands=[band])
+ LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
+ datapath.send_msg(mod)
+
+ def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ actions = [parser.OFPActionOutput(dst_port)]
+ if meter_id != 0:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions), parser.OFPInstructionMeter(meter_id)]
+ else:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
+
+ # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD)
+ # message match field.
+ match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
+ mod = parser.OFPFlowMod(datapath=datapath,
+ cookie=cookie,
+ cookie_mask=32767,
+ priority=0,
+ match=match,
+ instructions=inst)
+ LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d",
+ src_port, dst_port, vid, meter_id, cookie)
+ datapath.send_msg(mod)
+
+ def del_flow(self, datapath, cookie):
+ LOG.info("del_flow: cookie=%d", cookie)
+ self._del_flow(datapath, cookie, 32767)
+
+ def del_all_flows(self, datapath):
+ LOG.info("del_all_flows")
+ # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
+ self._del_flow(datapath, 0, 0)
+
+ def _del_flow(self, datapath, cookie, mask):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(
+ datapath=datapath, match=None, cookie=cookie, cookie_mask=mask,
+ command=ofproto.OFPFC_DELETE)
+ datapath.send_msg(mod)
+
+ def send_barrier(self, datapath):
+ LOG.info("send_barrier")
+ datapath.send_barrier()
+
diff --git a/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all_loop.py b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all_loop.py
new file mode 100644
index 0000000..ad87847
--- /dev/null
+++ b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_all_loop.py
@@ -0,0 +1,120 @@
+# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+import logging
+
+from ryu.base import app_manager
+from time import sleep
+from ryu.controller import ofp_event
+from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
+from ryu.controller.handler import set_ev_cls
+from ryu.ofproto import ofproto_v1_3
+from ryu.lib.packet import packet
+from ryu.lib.packet import ethernet
+from ryu.lib import addrconv
+
+LOG = logging.getLogger('ryu.app.pon_topology')
+
+class PonTopology13(app_manager.RyuApp):
+ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+
+ def __init__(self, *args, **kwargs):
+ super(PonTopology13, self).__init__(*args, **kwargs)
+ self.mac_to_port = {}
+
+ @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
+ def switch_features_handler(self, ev):
+ datapath = ev.msg.datapath
+
+ # Add/Del upstream/downstream flows (VID 100) in a loop to test for leaks in the OF agent
+ #
+ # (NOTE: The first del_all_flows does nothing if flows have not been previously
+ # configured in the OF agent)
+ while 1:
+ self.del_all_flows(datapath)
+
+ self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
+ self.add_vid_flow(datapath,10001, 129, 1, 100, 0)
+
+ sleep(1)
+ self.send_barrier(datapath)
+
+ sleep(5)
+
+
+ @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
+ def port_status_handler(self, ev):
+ LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)
+
+ def add_meter(self, datapath, meter_id, rate):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
+ mod = parser.OFPMeterMod(datapath=datapath,
+ command=ofproto.OFPMC_ADD,
+ flags=ofproto.OFPMF_KBPS,
+ meter_id=meter_id,
+ bands=[band])
+ LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
+ datapath.send_msg(mod)
+
+ def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ actions = [parser.OFPActionOutput(dst_port)]
+ if meter_id != 0:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions),
+ parser.OFPInstructionMeter(meter_id)]
+ else:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
+
+ # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD)
+ # message match field.
+ match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
+ mod = parser.OFPFlowMod(datapath=datapath,
+ cookie=cookie,
+ cookie_mask=32767,
+ priority=0,
+ match=match,
+ instructions=inst)
+ LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d",
+ src_port, dst_port, vid, meter_id, cookie)
+ datapath.send_msg(mod)
+
+ def del_flow(self, datapath, cookie):
+ LOG.info("del_flow: cookie=%d", cookie)
+ self._del_flow(datapath, cookie, 32767)
+
+ def del_all_flows(self, datapath):
+ LOG.info("del_all_flows")
+ # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
+ self._del_flow(datapath, 0, 0)
+
+ def _del_flow(self, datapath, cookie, mask):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(
+ datapath=datapath, match=None, cookie=cookie, cookie_mask=mask,
+ command=ofproto.OFPFC_DELETE)
+ datapath.send_msg(mod)
+
+ def send_barrier(self, datapath):
+ LOG.info("send_barrier")
+ datapath.send_barrier()
+
+
+
+
+
diff --git a/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_ds_then_us.py b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_ds_then_us.py
new file mode 100644
index 0000000..377903f
--- /dev/null
+++ b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_ds_then_us.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+import logging
+
+from ryu.base import app_manager
+from time import sleep
+from ryu.controller import ofp_event
+from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
+from ryu.controller.handler import set_ev_cls
+from ryu.ofproto import ofproto_v1_3
+from ryu.lib.packet import packet
+from ryu.lib.packet import ethernet
+from ryu.lib import addrconv
+
+LOG = logging.getLogger('ryu.app.pon_topology')
+
+class PonTopology13(app_manager.RyuApp):
+ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+
+ def __init__(self, *args, **kwargs):
+ super(PonTopology13, self).__init__(*args, **kwargs)
+ self.mac_to_port = {}
+
+ @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
+ def switch_features_handler(self, ev):
+ datapath = ev.msg.datapath
+
+ # This does nothing if flows have not been previously configured in the OF agent
+ self.del_all_flows(datapath)
+
+ # Configure the flows (VID 100)
+ #
+ # Ports 1-128 are implicitly mapped to UNI-0 on ONU 1-12
+ # Ports 129 and above are implicitly mapped to OLT NNI-0 and above
+ self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
+ self.add_vid_flow(datapath,10001, 129, 1, 100, 0)
+
+ sleep(1)
+ self.send_barrier(datapath)
+
+ sleep(5)
+
+ # Delete the downstream flow
+ self.del_flow(datapath, 10001)
+ # Then delete the upstream flow
+ self.del_flow(datapath, 10000)
+
+ @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
+ def port_status_handler(self, ev):
+ LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)
+
+ def add_meter(self, datapath, meter_id, rate):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
+ mod = parser.OFPMeterMod(datapath=datapath,
+ command=ofproto.OFPMC_ADD,
+ flags=ofproto.OFPMF_KBPS,
+ meter_id=meter_id,
+ bands=[band])
+ LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
+ datapath.send_msg(mod)
+
+ def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ actions = [parser.OFPActionOutput(dst_port)]
+ if meter_id != 0:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions),
+ parser.OFPInstructionMeter(meter_id)]
+ else:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
+
+ # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD)
+ # message match field.
+ match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
+ mod = parser.OFPFlowMod(datapath=datapath,
+ cookie=cookie,
+ cookie_mask=32767,
+ priority=0,
+ match=match,
+ instructions=inst)
+ LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d",
+ src_port, dst_port, vid, meter_id, cookie)
+ datapath.send_msg(mod)
+
+ def del_flow(self, datapath, cookie):
+ LOG.info("del_flow: cookie=%d", cookie)
+ self._del_flow(datapath, cookie, 32767)
+
+ def del_all_flows(self, datapath):
+ LOG.info("del_all_flows")
+
+ # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
+ self._del_flow(datapath, 0, 0)
+
+ def _del_flow(self, datapath, cookie, mask):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(datapath=datapath,
+ match=None,
+ cookie=cookie,
+ cookie_mask=mask,
+ command=ofproto.OFPFC_DELETE)
+ datapath.send_msg(mod)
+
+ def send_barrier(self, datapath):
+ LOG.info("send_barrier")
+ datapath.send_barrier()
+
diff --git a/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_us_then_ds.py b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_us_then_ds.py
new file mode 100644
index 0000000..188208f
--- /dev/null
+++ b/bal_release/scripts/ryu/PON_topology_100_flow_add_then_delete_us_then_ds.py
@@ -0,0 +1,119 @@
+# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+import logging
+
+from ryu.base import app_manager
+from time import sleep
+from ryu.controller import ofp_event
+from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
+from ryu.controller.handler import set_ev_cls
+from ryu.ofproto import ofproto_v1_3
+from ryu.lib.packet import packet
+from ryu.lib.packet import ethernet
+from ryu.lib import addrconv
+
+LOG = logging.getLogger('ryu.app.pon_topology')
+
+class PonTopology13(app_manager.RyuApp):
+ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+
+ def __init__(self, *args, **kwargs):
+ super(PonTopology13, self).__init__(*args, **kwargs)
+ self.mac_to_port = {}
+
+ @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
+ def switch_features_handler(self, ev):
+ datapath = ev.msg.datapath
+
+ # This does nothing if flows have not been previously configured in the OF agent
+ self.del_all_flows(datapath)
+
+ # Configure the flows (VID 100)
+ #
+ # Ports 1-128 are implicitly mapped to UNI-0 on ONU 1->128
+ # Ports 129 and above are implicitly mapped to OLT NNI-0 and above
+ self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
+ self.add_vid_flow(datapath,10001, 129, 1, 100, 0)
+
+ sleep(1)
+ self.send_barrier(datapath)
+
+ sleep(5)
+
+ # Delete the upstream flow
+ self.del_flow(datapath, 10000)
+ # Then delete the downstream flow
+ self.del_flow(datapath, 10001)
+
+ @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
+ def port_status_handler(self, ev):
+ LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)
+
+ def add_meter(self, datapath, meter_id, rate):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
+ mod = parser.OFPMeterMod(datapath=datapath,
+ command=ofproto.OFPMC_ADD,
+ flags=ofproto.OFPMF_KBPS,
+ meter_id=meter_id,
+ bands=[band])
+ LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
+ datapath.send_msg(mod)
+
+ def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ actions = [parser.OFPActionOutput(dst_port)]
+ if meter_id != 0:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions), parser.OFPInstructionMeter(meter_id)]
+ else:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
+
+ # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD)
+ # message match field.
+ match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
+ mod = parser.OFPFlowMod(datapath=datapath,
+ cookie=cookie,
+ cookie_mask=32767,
+ priority=0,
+ match=match,
+ instructions=inst)
+ LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d",
+ src_port, dst_port, vid, meter_id, cookie)
+ datapath.send_msg(mod)
+
+ def del_flow(self, datapath, cookie):
+ LOG.info("del_flow: cookie=%d", cookie)
+ self._del_flow(datapath, cookie, 32767)
+
+ def del_all_flows(self, datapath):
+ LOG.info("del_all_flows")
+ # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
+ self._del_flow(datapath, 0, 0)
+
+ def _del_flow(self, datapath, cookie, mask):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(
+ datapath=datapath, match=None, cookie=cookie, cookie_mask=mask,
+ command=ofproto.OFPFC_DELETE)
+ datapath.send_msg(mod)
+
+ def send_barrier(self, datapath):
+ LOG.info("send_barrier")
+ datapath.send_barrier()
+
diff --git a/bal_release/scripts/ryu/PON_topology_100_flow_add_with_ds_meter.py b/bal_release/scripts/ryu/PON_topology_100_flow_add_with_ds_meter.py
new file mode 100644
index 0000000..6b73d17
--- /dev/null
+++ b/bal_release/scripts/ryu/PON_topology_100_flow_add_with_ds_meter.py
@@ -0,0 +1,125 @@
+# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+import logging
+
+from ryu.base import app_manager
+from time import sleep
+from ryu.controller import ofp_event
+from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
+from ryu.controller.handler import set_ev_cls
+from ryu.ofproto import ofproto_v1_3
+from ryu.lib.packet import packet
+from ryu.lib.packet import ethernet
+from ryu.lib import addrconv
+
+LOG = logging.getLogger('ryu.app.pon_topology')
+
+class PonTopology13(app_manager.RyuApp):
+ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+
+ def __init__(self, *args, **kwargs):
+ super(PonTopology13, self).__init__(*args, **kwargs)
+ self.mac_to_port = {}
+
+ @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
+ def switch_features_handler(self, ev):
+ datapath = ev.msg.datapath
+
+ # This does nothing if flows have not been previously configured in the OF agent
+ self.del_all_flows(datapath)
+
+ # Add a meter (500 Kbps rate limit) with an ID of 11
+ self.add_meter(datapath, 11, 500)
+
+ # Configure the flows (VID 100)
+ # Note: the downstream flow has a meter ID reference
+ #
+ # Ports 1-128 are implicitly mapped to UNI-0 on ONUs 1->128
+ # Ports 129 and above are implicitly mapped to OLT NNI-0 and above
+ self.add_vid_flow(datapath,10000, 1, 129, 100, 0)
+ self.add_vid_flow(datapath,10001, 129, 1, 100, 11)
+
+ sleep(1)
+ self.send_barrier(datapath)
+
+
+ @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
+ def port_status_handler(self, ev):
+ LOG.debug('port_status_handler port id: %d', ev.msg.desc.port_no)
+
+ def add_meter(self, datapath, meter_id, rate):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ band = parser.OFPMeterBandDrop(burst_size=0, rate=rate)
+ mod = parser.OFPMeterMod(datapath=datapath,command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=meter_id, bands=[band])
+ LOG.info("add_meter: meter_id=%d, rate=%d KBPS")
+ datapath.send_msg(mod)
+
+ def add_vid_flow(self, datapath, cookie, src_port, dst_port, vid, meter_id):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+ actions = [parser.OFPActionOutput(dst_port)]
+ if meter_id != 0:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions), parser.OFPInstructionMeter(meter_id)]
+ else:
+ inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
+
+ # NOTE: 0x1000 is OR'd into the vid to set the OFPVID_PRESENT flag in the OpenFlow FLOW_MOD (OFPFC_ADD)
+ # message match field.
+ match = parser.OFPMatch(in_port=src_port, vlan_vid=(vid | 0x1000))
+ mod = parser.OFPFlowMod(datapath=datapath,
+ cookie=cookie,
+ cookie_mask=32767,
+ priority=0,
+ match=match,
+ instructions=inst)
+ LOG.info("add_vid_flow: src_port=%d dst_port=%d vid=%d meter=%d cookie=%d",
+ src_port, dst_port, vid, meter_id, cookie)
+ datapath.send_msg(mod)
+
+ def del_flow(self, datapath, cookie):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(
+ datapath=datapath, match=None, cookie=cookie, cookie_mask=32767,
+ command=ofproto.OFPFC_DELETE)
+ LOG.info("del_flow: cookie=%d", cookie)
+ datapath.send_msg(mod)
+
+ def del_all_flows(self, datapath):
+ LOG.info("del_all_flows")
+ # Cookie 0 (argument 2) tells the OF agent to delete all configured flows
+ self._del_flow(datapath, 0, 0)
+
+ def _del_flow(self, datapath, cookie, mask):
+ ofproto = datapath.ofproto
+ parser = datapath.ofproto_parser
+
+ mod = parser.OFPFlowMod(datapath=datapath,
+ match=None,
+ cookie=cookie,
+ cookie_mask=mask,
+ command=ofproto.OFPFC_DELETE)
+ datapath.send_msg(mod)
+
+ def send_barrier(self, datapath):
+ LOG.info("send_barrier")
+ datapath.send_barrier()
+
+
+
+
+
diff --git a/bal_release/scripts/trx_init.sh b/bal_release/scripts/trx_init.sh
new file mode 100644
index 0000000..880bff6
--- /dev/null
+++ b/bal_release/scripts/trx_init.sh
@@ -0,0 +1,67 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+
+# Commands required to enable all 16 PON ports on the MAPLE device
+
+/board/trx_enable pon_id=0
+/board/trx_enable pon_id=1
+/board/trx_enable pon_id=2
+/board/trx_enable pon_id=3
+/board/trx_enable pon_id=4
+/board/trx_enable pon_id=5
+/board/trx_enable pon_id=6
+/board/trx_enable pon_id=7
+/board/trx_enable pon_id=8
+/board/trx_enable pon_id=9
+/board/trx_enable pon_id=10
+/board/trx_enable pon_id=11
+/board/trx_enable pon_id=12
+/board/trx_enable pon_id=13
+/board/trx_enable pon_id=14
+/board/trx_enable pon_id=15
diff --git a/bal_release/scripts/upgrade_bal_qumran.sh b/bal_release/scripts/upgrade_bal_qumran.sh
new file mode 100755
index 0000000..8b8b61d
--- /dev/null
+++ b/bal_release/scripts/upgrade_bal_qumran.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+# Define all BAL apps to be upgraded here
+FILELIST=('bcm.user' 'linux-kernel-bde.ko' 'linux-user-bde.ko' 'bcm88470_board.soc' 'combo28_dram.soc' 'config.bcm' 'init.sh' 'qax.soc' 'rc.soc')
+#JENKINSSERVER='jenkins-tlva-06.il.broadcom.com'
+JENKINSSERVER='10.187.130.172'
+ING_SDK_VER='6.5.6'
+
+mkdir -p old
+
+JENKINSPATH1="http://${JENKINSSERVER}/job/Bal.Synced.bcm-sdk-${ING_SDK_VER}/lastSuccessfulBuild/artifact/bal/cur/"
+JENKINSFILE1=(
+ '3rdparty/bcm-sdk/build/sdk-all-'${ING_SDK_VER}'/build/linux/user/wrx-3_7/bcm.user'
+ '3rdparty/bcm-sdk/build/sdk-all-'${ING_SDK_VER}'/build/linux/user/wrx-3_7/linux-kernel-bde.ko'
+ '3rdparty/bcm-sdk/build/sdk-all-'${ING_SDK_VER}'/build/linux/user/wrx-3_7/linux-user-bde.ko'
+ '3rdparty/bcm-sdk/rc/qax/bcm88470_board.soc'
+ '3rdparty/bcm-sdk/rc/qax/combo28_dram.soc'
+ '3rdparty/bcm-sdk/rc/qax/config.bcm'
+ '3rdparty/bcm-sdk/rc/qax/init.sh'
+ '3rdparty/bcm-sdk/rc/qax/qax.soc'
+ '3rdparty/bcm-sdk/rc/qax/rc.soc'
+)
+
+
+function coloredEcho(){
+ local exp=$1;
+ local color=$2;
+ if ! [[ $color =~ '^[0-9]$' ]] ; then
+ case $(echo $color | tr '[:upper:]' '[:lower:]') in
+ black) color=0 ;;
+ red) color=1 ;;
+ green) color=2 ;;
+ yellow) color=3 ;;
+ blue) color=4 ;;
+ magenta) color=5 ;;
+ cyan) color=6 ;;
+ white|*) color=7 ;; # white or invalid color
+ esac
+ fi
+ tput setaf $color;
+ echo $exp;
+ tput sgr0;
+}
+
+function check_return(){
+ echo -n "$1... "
+ $($2)
+ if [ $? -eq 0 ]; then
+ coloredEcho '[ OK ]' green
+ else
+ coloredEcho '[ ERROR ]' red
+ fi
+}
+
+# Checking connectivity to Jenkins Server
+echo -n "Verifing Connectivity to Jenkins... "
+ping -c 1 ${JENKINSSERVER} &> /dev/null
+if [ $? -eq 0 ]; then
+ coloredEcho '[ OK ]' green
+ else
+ coloredEcho '[ ERROR ]' red
+ echo 'Aborting Upgrade!'
+ exit 0
+ fi
+
+# delete any old versions
+echo 'Deleting older versions...'
+for FILE in ${FILELIST[@]}
+ do
+ check_return "Deleting ${FILE}.old" "rm -f old/${FILE}.old"
+ done
+
+# rename the existing versions
+echo 'Renaming last version x.old ...'
+for FILE in ${FILELIST[@]}
+ do
+ check_return "Moving ${FILE} to ${FILE}.old" "mv ${FILE} old/${FILE}.old"
+ done
+
+# Get the new versions
+echo 'Downloading ING version '${ING_SDK_VER}'...'
+for FILE in ${JENKINSFILE1[@]}
+ do
+ COMMAND="wget -q ${JENKINSPATH1}${FILE}"
+ SHORTFILE=$(echo ${FILE} | sed 's:.*/::')
+ check_return "Getting Latest ${SHORTFILE}" "${COMMAND}"
+ done
+
+# Changing permissions to executable
+echo 'Changing permissions to executable...'
+for FILE in ${FILELIST[@]}
+ do
+ check_return "Makiing ${FILE} executable" "chmod 755 ${FILE}"
+ done
+
+echo 'Upgrade Complete'
diff --git a/bal_release/src/apps/bal_cli/Makefile b/bal_release/src/apps/bal_cli/Makefile
new file mode 100644
index 0000000..52c885f
--- /dev/null
+++ b/bal_release/src/apps/bal_cli/Makefile
@@ -0,0 +1,39 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+#
+# BAL core CLI application
+#
+MOD_NAME = bal_cli
+MOD_DEPS = bal_core dev_log cli os_cli bal_api_cli topology cmdline
+MOD_DEPS_OPT = omcisvc
+MOD_TYPE = app
+
+srcs = bal_cli_app.c
diff --git a/bal_release/src/apps/bal_cli/bal_cli_app.c b/bal_release/src/apps/bal_cli/bal_cli_app.c
new file mode 100644
index 0000000..40a6229
--- /dev/null
+++ b/bal_release/src/apps/bal_cli/bal_cli_app.c
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_cli_app.c
+ * @brief BAL CLI application
+ * @addtogroup ctrlr
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_core.h>
+#include <bal_cli.h>
+
+#ifdef OMCI_SVC
+#include <omci_svc.h>
+#include <omci_svc_cli.h>
+#endif
+
+
+/*****************************************************************************/
+/**
+ * @brief The main entry point for the Bal Core
+ *
+ * A function to initialize and start the Bal Core. The user
+ * supplied command line arguments are processed, the internal CLI is
+ * initialized, as are all of the components in the Core. User input to
+ * the CLI is then processed. This function does not return until the
+ * user quits the CLI, at which time the BAL core terminates operation.
+ *
+ * Errors encountered during the execution of this function are considered
+ * to be fatal.
+ *
+ * @param argc command line argument count
+ *
+ * @param argv pointer to command line argument list
+ *
+ * @returns 0 on success, or -EINVAL when an error is encountered
+ *
+ *****************************************************************************/
+int main(int argc, char *argv[])
+{
+ bcmos_errno ret;
+
+ do
+ {
+ /* Init BAL components */
+ ret = bcmbal_init_all(argc, argv, NULL);
+ if (BCM_ERR_OK != ret)
+ break;
+
+ /* Execute init script if any */
+ ret = bcmbal_cli_exec_init_script();
+ if (BCM_ERR_OK != ret)
+ break;
+
+ /* Let everything run until CLI terminates */
+ while (!bcmbal_cli_is_terminated())
+ bcmos_usleep(1000000);
+ }
+ while (0);
+
+ /* Cleanup */
+ bcmbal_cli_finish();
+ bcmbal_finish();
+ bcmos_exit();
+
+ return (BCM_ERR_OK == ret) ? 0 : -1;
+}
+
+
+/*@}*/
diff --git a/bal_release/src/common/bal_app_utils/Makefile b/bal_release/src/common/bal_app_utils/Makefile
new file mode 100644
index 0000000..2551bf6
--- /dev/null
+++ b/bal_release/src/common/bal_app_utils/Makefile
@@ -0,0 +1,36 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# Common utilities
+#
+MOD_NAME = bal_app_utils
+MOD_TYPE = lib
+MOD_DEPS = dev_log maple_sdk
+srcs = bal_app_common_utils.c
diff --git a/bal_release/src/common/bal_app_utils/bal_app_common_utils.c b/bal_release/src/common/bal_app_utils/bal_app_common_utils.c
new file mode 100755
index 0000000..83894d6
--- /dev/null
+++ b/bal_release/src/common/bal_app_utils/bal_app_common_utils.c
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_app_common_utils.c
+ * @brief BAL app common Utilities functionality
+ *
+ * @addtogroup util
+ */
+
+/*@{*/
+
+#include "bal_app_common_utils.h"
+
+/*****************************************************************************/
+/**
+* @brief app_util_parse_ip_port
+*
+* This routine is used to parse the user supplied IP address and port of the
+* remote MAC device.
+*
+* @param ip_port A string containing the IP:port to parse
+*
+* @param ip The IP address that results from the parsing function
+*
+* @param port The port that results from the parsing function
+*
+* @return bcmos_errno
+*/
+/*****************************************************************************/
+bcmos_errno app_util_parse_ip_port(const char *ip_port, uint32_t *ip, uint16_t *port)
+{
+ int n;
+ uint32_t ip1, ip2, ip3, ip4, pp;
+
+ if (!ip_port)
+ {
+ bcmos_printf("ERR: ip_port is not set\n");
+ return BCM_ERR_PARM;
+ }
+ n = sscanf(ip_port, "%u.%u.%u.%u:%u", &ip1, &ip2, &ip3, &ip4, &pp);
+ if (n != 5 || ip1 > 0xff || ip2 > 0xff || ip3 > 0xff || ip4 > 0xff || pp > 0xffff)
+ {
+ bcmos_printf("ERR: Can't parse %s. Must be ip_address:port\n", ip_port);
+ return BCM_ERR_PARM;
+ }
+ *ip = (ip1 << 24) | (ip2 << 16) | (ip3 << 8) | ip4;
+ *port = pp;
+ return BCM_ERR_OK;
+}
+
+/*@}*/
+
diff --git a/bal_release/src/common/bal_app_utils/bal_app_common_utils.h b/bal_release/src/common/bal_app_utils/bal_app_common_utils.h
new file mode 100755
index 0000000..1db1b9f
--- /dev/null
+++ b/bal_release/src/common/bal_app_utils/bal_app_common_utils.h
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_app_common_utils.h
+ * @brief BAL Utilities include file
+ *
+ * @defgroup util Bal App Util Routines
+ * @ingroup lib
+ */
+
+#ifndef _BAL_COMMON_UTILS_H
+#define _BAL_COMMON_UTILS_H
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include <bal_utils_msg.h>
+#include <bal_msg_type.h>
+#include <bal_objs.h>
+
+bcmos_errno app_util_parse_ip_port(const char *ip_port, uint32_t *ip, uint16_t *port);
+
+/*@}*/
+
+#endif /* _BAL_COMMON_UTILS_H*/
diff --git a/bal_release/src/common/cli b/bal_release/src/common/cli
new file mode 120000
index 0000000..8573c77
--- /dev/null
+++ b/bal_release/src/common/cli
@@ -0,0 +1 @@
+../../3rdparty/maple/sdk/host_reference/cli
\ No newline at end of file
diff --git a/bal_release/src/common/config/bcm_config.h b/bal_release/src/common/config/bcm_config.h
new file mode 100644
index 0000000..9221c1a
--- /dev/null
+++ b/bal_release/src/common/config/bcm_config.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef BCMOLT_CONFIG_H_
+#define BCMOLT_CONFIG_H_
+
+/** \defgroup config Configuration Constants
+ * Configuration constants that must be revised by customer
+ * @{
+ */
+
+#define BCMTR_MAX_OLTS 1 /**< Max number of OLTs */
+
+/** @} */
+
+
+#endif /* BCMOLT_CONFIG_H_ */
diff --git a/bal_release/src/common/db_engine/Makefile b/bal_release/src/common/db_engine/Makefile
new file mode 100644
index 0000000..23b64f6
--- /dev/null
+++ b/bal_release/src/common/db_engine/Makefile
@@ -0,0 +1,36 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# Data Base engine
+#
+MOD_NAME = db
+MOD_TYPE = lib
+
+srcs = bcm_db_engine.c
diff --git a/bal_release/src/common/db_engine/bcm_db_engine.c b/bal_release/src/common/db_engine/bcm_db_engine.c
new file mode 100644
index 0000000..dc4f19a
--- /dev/null
+++ b/bal_release/src/common/db_engine/bcm_db_engine.c
@@ -0,0 +1,1606 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/*
+ * Data Base Engine
+ *
+ * Proprietary and confidential.
+ */
+#include <bcmos_system.h>
+#include <bcm_db_engine.h>
+
+/* DB trace level */
+bcmos_trace_level bcmdb_trace_level = BCMOS_TRACE_LEVEL_ERROR;
+
+#define BCMDB_TRACE(level, fmt, args...) \
+ do { \
+ if (level <= bcmdb_trace_level) \
+ bcmos_trace(level, "%s#%d> " fmt, __FUNCTION__, __LINE__, ## args); \
+ } while (0)
+
+/* Print error trace conditionally, depending on the current trace level */
+#define BCMDB_TRACE_ERROR(fmt, args...) \
+ BCMDB_TRACE(BCMOS_TRACE_LEVEL_ERROR, "DB ERR: %s#%d> " fmt, __FUNCTION__, __LINE__, ## args)
+
+/* Print warning trace conditionally, depending on the current trace level */
+#define BCMDB_TRACE_WARNING(fmt, args...) \
+ BCMDB_TRACE(BCMOS_TRACE_LEVEL_WARNING, "DB WARN: %s#%d> " fmt, __FUNCTION__, __LINE__, ## args)
+
+/* Print info trace conditionally, depending on the current trace level */
+#define BCMDB_TRACE_INFO(fmt, args...) \
+ BCMDB_TRACE(BCMOS_TRACE_LEVEL_INFO, "DB INFO: %s#%d> " fmt, __FUNCTION__, __LINE__, ## args)
+
+/* Enable debug prints */
+#define BCMDB_DEBUG
+
+#ifdef BCMDB_DEBUG
+
+/* Print debug trace conditionally, depending on the current trace level */
+#define BCMDB_TRACE_DEBUG(fmt, args...) \
+ BCMDB_TRACE(BCMOS_TRACE_LEVEL_DEBUG, "DB DBG: %s#%d> " fmt, __FUNCTION__, __LINE__, ## args)
+
+#else
+
+#define BCMDB_TRACE_DEBUG(fmt, args...)
+
+#endif
+
+
+
+/** Data base entry
+ * \ingroup bcmdb
+ */
+struct bcmdb_entry
+{
+ void *data; /* Set or record */
+ uint8_t flags;
+#define BCMDB_FLAG_VALID 0x01 /**< Entry is valid */
+#define BCMDB_FLAG_RECORD 0x02 /**< Record */
+#define BCMDB_FLAG_SOS 0x10 /**< Set of sets */
+ uint8_t read_count;
+ uint8_t write_pending;
+ uint8_t ffu;
+};
+
+/** Set/Record change notification
+ * \ingroup bcmdb
+ */
+typedef struct bcmdb_notify
+{
+ struct bcmdb_notify *next;
+ bcmdb_notify_cb cb;
+ long cb_priv;
+} bcmdb_notify;
+
+/** Data Base Set control block
+ * \ingroup bcmdb
+ */
+struct bcmdb_set
+{
+ bcmdb_entry entry; /**< Common fields for set and record */
+ char *name; /**< Set name */
+ bcmdb_set *parent; /**< Set parent */
+ bcmdb_key my_key; /**< Key in the parent set */
+ int max_entries; /**< Max number of elements in the set. -1=inlimited */
+ int num_entries; /**< Current number of elements in the set */
+ int entry_size; /**< Set entry size. */
+ int magic; /**< Magic number */
+#define BCMDB_MAGIC_ACTIVE_SET (('a'<<24) | ('s'<<16) | ('e'<<8) | 't')
+#define BCMDB_MAGIC_FREE_SET (('f'<<24) | ('s'<<16) | ('e'<<8) | 't')
+
+ /** Get next element */
+ bcmdb_key (*entry_get_next)(const bcmdb_set *this, bcmdb_key cur);
+
+ /** Add new entry. returns 0 if ok */
+ int (*entry_new)(bcmdb_set *this, bcmdb_key key, const void *data);
+
+ /** Delete entry */
+ int (*entry_delete)(bcmdb_set *this, bcmdb_entry *entry);
+
+ /*
+ * Handle – key mapping
+ */
+
+ /** Convert entry handle to entry key */
+ bcmdb_key (*handle_to_key)(const bcmdb_set *this, const bcmdb_entry *entry);
+
+ /** Convert entry key to entry handle */
+ bcmdb_entry *(*key_to_handle)(const bcmdb_set *this, bcmdb_key key);
+
+ /*
+ * Set/Record locking
+ * entry is handle of the set or record to be locked/unlocked
+ */
+
+ /** Lock the whole set for reading */
+ void (*lock_set_read)(bcmdb_set *set);
+
+ /** Unlock set locked for reading */
+ void (*unlock_set_read)(bcmdb_set *set);
+
+ /** Lock the whole set for update */
+ long (*lock_set_modify)(bcmdb_set *set);
+
+ /** Unlock set locked for update */
+ void (*unlock_set_modify)(bcmdb_set *set, long fastlock_flags);
+
+ /** Lock the set recursively for update (SoS only) */
+ void (*lock_set_recursively_modify)(bcmdb_set *set);
+
+ /** Unlock recursively set locked for update (SoS only) */
+ void (*unlock_set_recursively_modify)(bcmdb_set *set);
+
+ /** Lock record for reading */
+ void *(*lock_record_read)(bcmdb_set *set, bcmdb_key key);
+
+ /** Release read lock */
+ void (*unlock_record_read)(bcmdb_set *set, bcmdb_key key);
+
+ /** Lock record for modification. */
+ void *(*lock_record_write)(bcmdb_set *set, bcmdb_key key, int is_deletion);
+
+ /** Release modify lock */
+ void (*unlock_record_write)(bcmdb_set *set, int is_deletion, int is_cancellation);
+
+ /** Format function that converts record data to human-readable form */
+ bcmdb_format_cb format;
+
+ /** Update notification mechanism.\n
+ * Note that notification functions are called before the actual update of the data base, so that
+ * there is an option to abort the update if needed.
+ */
+ bcmdb_notify *notify_list_head;
+
+ /** Shadow data record */
+ void *shadow_data;
+
+ /** holds the pointer to a write-locked entry */
+ bcmdb_entry *write_locked_entry ;
+
+ /** mutex that prevents multiple simultaneous updates */
+ bcmos_mutex mutex_update;
+
+ /** semaphore that holds update while there are unfinished reads */
+ bcmos_sem sem_wait_read_to_finish;
+
+ /** fastlock */
+ bcmos_fastlock fastlock;
+};
+
+
+/**< Data base record
+ * \ingroup bcmdb
+ */
+struct bcmdb_record
+{
+ struct bcmdb_entry e; /**< Entry - common part for set and record */
+};
+
+/*
+ * DB backend callbacks
+ */
+
+/*
+ * Array-based backend
+ */
+
+/** Get next element */
+static bcmdb_key _bcmdb_array_entry_get_next(const bcmdb_set *this, bcmdb_key key)
+{
+ BUG_ON(!this->entry.data);
+
+ if (key < 0)
+ key = 0;
+ else
+ ++key;
+
+ while((unsigned)key<this->max_entries)
+ {
+ bcmdb_entry *entry = (bcmdb_entry *)this->entry.data + key;
+ if ((entry->flags & BCMDB_FLAG_VALID))
+ break;
+ ++key;
+ }
+
+ if ((unsigned)key >= this->max_entries)
+ return BCMDB_KEY_NO_MORE; /* no more */
+
+ return key;
+}
+
+/*
+ * Handle – key mapping
+ */
+
+/** Convert entry handle to entry key */
+static inline bcmdb_key _bcmdb_array_handle_to_key(const bcmdb_set *this, const bcmdb_entry *entry)
+{
+ bcmdb_key key;
+
+ BUG_ON(!this);
+ BUG_ON(!entry);
+ BUG_ON(!this->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!this->entry.data);
+
+ key = entry - (bcmdb_entry *)this->entry.data;
+ if ((unsigned)key >= this->max_entries)
+ return BCMDB_KEY_INVAL;
+
+ return key;
+}
+
+
+/** Convert entry key to entry handle */
+static inline bcmdb_entry *_bcmdb_array_key_to_handle(const bcmdb_set *this, bcmdb_key key)
+{
+ BUG_ON(!this);
+ BUG_ON(!this->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!this->entry.data);
+
+ if ((unsigned long)key >= this->max_entries)
+ return NULL;
+
+ return (bcmdb_entry *)this->entry.data + key;
+}
+
+
+/** sem-based set read-lock */
+static void bcmdb_set_lock_read_sem(bcmdb_set *set)
+{
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+}
+
+
+/** sem-based set read-unlock */
+static void bcmdb_set_unlock_read_sem(bcmdb_set *set)
+{
+ bcmos_mutex_unlock(&set->mutex_update);
+}
+
+
+/** sem-based set modify-lock */
+static long bcmdb_set_lock_modify_sem(bcmdb_set *set)
+{
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+ return 0;
+}
+
+
+/** sem-based set modify-unlock */
+static void bcmdb_set_unlock_modify_sem(bcmdb_set *set, long fastlock_flags)
+{
+ bcmos_mutex_unlock(&set->mutex_update);
+}
+
+
+/** helper function which recursively locks all subsets of SoS
+ * for modify */
+static void bcmdb_recursive_subsets_lock_modify(bcmdb_set *sos)
+{
+ int key;
+ int left_entries = sos->num_entries;
+ bcmdb_entry *entry;
+ bcmdb_set *subset;
+
+ BUG_ON(!(sos->entry.flags & BCMDB_FLAG_SOS));
+
+ for (key = 0; key < sos->max_entries; ++key)
+ {
+ entry = sos->key_to_handle(sos, key);
+
+ if ((entry->flags & BCMDB_FLAG_VALID))
+ {
+ subset = (bcmdb_set *)entry->data;
+ subset->lock_set_recursively_modify(subset);
+
+ --left_entries;
+ /* if we handled all subsets we can break the "for" */
+ if (left_entries==0)
+ {
+ break;
+ }
+ }
+ }
+}
+
+
+/** helper function which recursively unlocks all subsets of SoS
+ * for modify */
+static void bcmdb_recursive_subsets_unlock_modify(bcmdb_set *sos)
+{
+ int key;
+ int left_entries = sos->num_entries;
+ bcmdb_entry *entry;
+ bcmdb_set *subset;
+
+ BUG_ON(!(sos->entry.flags & BCMDB_FLAG_SOS));
+
+ for (key = 0; key < sos->max_entries; ++key)
+ {
+ entry = sos->key_to_handle(sos, key);
+
+ if ((entry->flags & BCMDB_FLAG_VALID))
+ {
+ subset = (bcmdb_set *)entry->data;
+ subset->unlock_set_recursively_modify(subset);
+
+ --left_entries;
+ /* if we handled all subsets we can break the "for" */
+ if (left_entries==0)
+ {
+ break;
+ }
+ }
+ }
+}
+
+
+/** sem-based set modify-lock recursively */
+static void bcmdb_set_lock_recursively_modify_sem(bcmdb_set *set)
+{
+ BCMDB_TRACE_DEBUG("lock set modify recursively: %s\n", set->name);
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+ BCMDB_TRACE_DEBUG("mutex was locked\n");
+
+ if ((set->entry.flags & BCMDB_FLAG_SOS))
+ {
+ BCMDB_TRACE_DEBUG("going to lock the subsets\n");
+ bcmdb_recursive_subsets_lock_modify(set);
+ }
+}
+
+
+/** sem-based set modify-unlock recursively */
+static void bcmdb_set_unlock_recursively_modify_sem(bcmdb_set *set)
+{
+ BCMDB_TRACE_DEBUG("unlock set modify recursively: %s\n", set->name);
+
+ if ((set->entry.flags & BCMDB_FLAG_SOS))
+ {
+ BCMDB_TRACE_DEBUG("going to unlock the subsets\n");
+ bcmdb_recursive_subsets_unlock_modify(set);
+ }
+
+ bcmos_mutex_unlock(&set->mutex_update);
+ BCMDB_TRACE_DEBUG("mutex was unlocked\n");
+}
+
+
+/** NB-read-sem-write policy: set read lock */
+static void bcmdb_set_lock_read__nb_read_sem_write(bcmdb_set *set)
+{
+ long flags;
+
+ BCMDB_TRACE_DEBUG("lock set read: %s\n", set->name);
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ ++set->entry.read_count;
+ BCMDB_TRACE_DEBUG("read_count is now: %u\n", set->entry.read_count);
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+}
+
+
+/** NB-read-sem-write policy: set read unlock */
+static void bcmdb_set_unlock_read__nb_read_sem_write(bcmdb_set *set)
+{
+ long flags;
+
+ BCMDB_TRACE_DEBUG("unlock set read: %s\n", set->name);
+
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ BUG_ON(!set->entry.read_count);
+ if (!(--set->entry.read_count) &&
+ set->entry.write_pending)
+ {
+ BCMDB_TRACE_DEBUG("going to wake pending writer\n");
+
+ set->entry.write_pending = 0;
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ bcmos_sem_post(&set->sem_wait_read_to_finish);
+ }
+ else
+ {
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ }
+}
+
+
+/** NB-read-sem-write policy: set modify lock */
+static long bcmdb_set_lock_modify__nb_read_sem_write(bcmdb_set *set)
+{
+ long flags;
+
+ BCMDB_TRACE_DEBUG("lock set modify: %s\n", set->name);
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+ BCMDB_TRACE_DEBUG("mutex was locked\n");
+
+ while(1)
+ {
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ if (!set->entry.read_count)
+ break;
+ /* Wait until read is completed */
+ set->entry.write_pending = 1;
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ bcmos_sem_wait(&set->sem_wait_read_to_finish, BCMOS_WAIT_FOREVER);
+ }
+ /* At this point fastlock is taken and there are no pending reads */
+
+ BCMDB_TRACE_DEBUG("fastlock is taken, no active reads\n");
+
+ return flags;
+}
+
+
+/** NB-read-sem-write policy: set modify unlock */
+static void bcmdb_set_unlock_modify__nb_read_sem_write(bcmdb_set *set, long fastlock_flags)
+{
+ BCMDB_TRACE_DEBUG("unlock set modify: %s\n", set->name);
+ bcmos_fastlock_unlock(&set->fastlock, fastlock_flags);
+ bcmos_mutex_unlock(&set->mutex_update);
+ BCMDB_TRACE_DEBUG("mutex was unlocked\n");
+}
+
+
+/** sem-read/sem-write policy: lock entry */
+static void *bcmdb_sem_read_sem_write_lock(bcmdb_set *set, bcmdb_key key, int is_deletion)
+{
+ bcmdb_entry *entry;
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+
+ if (is_deletion)
+ {
+ /* there is nothing to return in deletion case */
+ return NULL;
+ }
+
+ entry = set->key_to_handle(set, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ {
+ bcmos_mutex_unlock(&set->mutex_update);
+ return NULL;
+ }
+ return entry->data;
+}
+
+/** sem-read/sem-write policy: unlock entry */
+static void bcmdb_sem_read_sem_write_unlock(bcmdb_set *set)
+{
+ bcmos_mutex_unlock(&set->mutex_update);
+}
+
+/** sem-read/sem-write policy: lock entry for reading */
+static void *bcmdb_sem_read_sem_write_lock_read(bcmdb_set *set, bcmdb_key key)
+{
+ return bcmdb_sem_read_sem_write_lock(set, key, 0) ;
+}
+
+/** sem-read/sem-write policy: unlock entry for reading */
+static void bcmdb_sem_read_sem_write_unlock_read(bcmdb_set *set, bcmdb_key key)
+{
+ bcmdb_sem_read_sem_write_unlock(set);
+}
+
+/** sem-read/sem-write policy: lock entry for writing */
+static void *bcmdb_sem_read_sem_write_lock_write(bcmdb_set *set, bcmdb_key key, int is_deletion)
+{
+ return bcmdb_sem_read_sem_write_lock(set, key, is_deletion) ;
+}
+
+/** sem-read/sem-write policy: unlock entry for writing */
+static void bcmdb_sem_read_sem_write_unlock_write(bcmdb_set *set, int is_deletion, int is_cancellation)
+{
+ bcmdb_sem_read_sem_write_unlock(set);
+}
+
+/** non-blocking-read/shadow write policy: Lock entry for reading */
+static void *bcmdb_nb_read_shadow_write_lock_read(bcmdb_set *set, bcmdb_key key)
+{
+ bcmdb_entry *entry;
+ long flags;
+
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ entry = set->key_to_handle(set, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ {
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ return NULL;
+ }
+ ++entry->read_count;
+
+ BCMDB_TRACE_DEBUG("lock record read: %s, key=%d new_read_count=%d\n", set->name, key, entry->read_count);
+
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ return entry->data;
+}
+
+
+/** non-blocking-read/shadow write policy: Unlock entry for reading */
+static void bcmdb_nb_read_shadow_write_unlock_read(bcmdb_set *set, bcmdb_key key)
+{
+ bcmdb_entry *entry=set->key_to_handle(set, key);
+ long flags;
+ BUG_ON(!entry);
+
+ BCMDB_TRACE_DEBUG("unlock record read: %s, key=%d\n", set->name, key);
+
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ /* If write is pending - finish it and release write lock */
+ BUG_ON(!entry->read_count);
+ if (!(--entry->read_count) && set->entry.write_pending)
+ {
+ BCMDB_TRACE_DEBUG("going to wake pending writer\n");
+
+ /* Write was pending. Release write task */
+ set->entry.write_pending = 0;
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ bcmos_sem_post(&set->sem_wait_read_to_finish);
+ }
+ else
+ {
+ BCMDB_TRACE_DEBUG("read_count is now: %u\n", entry->read_count);
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ }
+}
+
+/** non-blocking-read/shadow write policy: Lock entry for
+ * writing/deletion.
+ * returned value of NULL means error only in case that
+ * is_deletion is 0 */
+static void *bcmdb_nb_read_shadow_write_lock_write(bcmdb_set *set, bcmdb_key key, int is_deletion)
+{
+ bcmdb_entry *entry;
+
+ BCMDB_TRACE_DEBUG("lock record write: %s, key=%d\n", set->name, key);
+
+ bcmos_mutex_lock(&set->mutex_update, BCMOS_WAIT_FOREVER);
+ BCMDB_TRACE_DEBUG("mutex was locked\n");
+
+ if (is_deletion)
+ {
+ /* there is nothing to return in deletion case */
+ return NULL;
+ }
+
+ /* this check is needed since mutex_update is task-aware.
+ it is not allowed for a task to lock for writing a 2nd record before unlocking the first one. */
+ if (set->write_locked_entry)
+ {
+ BCMDB_TRACE_ERROR("there is already an entry locked for writing\n");
+ bcmos_mutex_unlock(&set->mutex_update);
+ return NULL;
+ }
+
+ entry = set->key_to_handle(set, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ {
+ bcmos_mutex_unlock(&set->mutex_update);
+ return NULL;
+ }
+ /* Copy data to shadow entry */
+ memcpy(set->shadow_data, entry->data, set->entry_size);
+ set->write_locked_entry = entry;
+ return set->shadow_data;
+}
+
+/** non-blocking-read/shadow write policy: Unlock entry for
+ * writing/deletion */
+static void bcmdb_nb_read_shadow_write_unlock_write(bcmdb_set *set, int is_deletion, int is_cancellation)
+{
+ bcmdb_entry *entry = set->write_locked_entry;
+ long flags;
+ void *old_data;
+
+ /* no entry is locked */
+ BUG_ON(!entry);
+
+ BCMDB_TRACE_DEBUG("unlock record write: %s\n", set->name);
+
+ /* cancellation: no need to update the entry from the shadow (or to delete the entry in case of deletion). */
+ if (is_cancellation)
+ {
+ set->write_locked_entry = NULL;
+ bcmos_mutex_unlock(&set->mutex_update);
+ return;
+ }
+
+ while(1)
+ {
+ flags = bcmos_fastlock_lock(&set->fastlock);
+ /* Wait until neither record nor set are locked for reading */
+ if (!entry->read_count && !set->entry.read_count)
+ break;
+
+ /* Read lock is active. wait */
+
+ BCMDB_TRACE_DEBUG("read lock is active. going to sleep.\n");
+
+ set->entry.write_pending = 1;
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ bcmos_sem_wait(&set->sem_wait_read_to_finish, BCMOS_WAIT_FOREVER);
+ }
+
+ /* At this point there is no read lock and fastlock is taken. */
+
+ BCMDB_TRACE_DEBUG("fastlock is taken, no active reads\n");
+
+ if (is_deletion)
+ {
+ /* delete the entry */
+ set->entry_delete(set, entry);
+ }
+ else
+ {
+ /* Exchange record data with shadow and release all locks. */
+ old_data = entry->data;
+ entry->data = set->shadow_data;
+ set->shadow_data = old_data;
+ set->write_locked_entry = NULL;
+ }
+
+ bcmos_fastlock_unlock(&set->fastlock, flags);
+ bcmos_mutex_unlock(&set->mutex_update);
+ BCMDB_TRACE_DEBUG("mutex was unlocked\n");
+}
+
+/** none policy: set read-lock */
+static inline void bcmdb_set_lock_read_dummy(bcmdb_set *set)
+{
+}
+
+/** none policy: set read-unlock */
+static inline void bcmdb_set_unlock_read_dummy(bcmdb_set *set)
+{
+}
+
+/** none policy: set modify-lock */
+static inline long bcmdb_set_lock_modify_dummy(bcmdb_set *set)
+{
+ return 0;
+}
+
+/** none policy: set modify-unlock */
+static inline void bcmdb_set_unlock_modify_dummy(bcmdb_set *set, long fastlock_flags)
+{
+}
+
+/** none policy: set modify-lock recursively */
+static void bcmdb_set_lock_recursively_modify_dummy(bcmdb_set *set)
+{
+}
+
+/** none policy: set modify-unlock recursively */
+static void bcmdb_set_unlock_recursively_modify_dummy(bcmdb_set *set)
+{
+}
+
+/** none policy: record lock */
+static inline void *bcmdb_dummy_lock(bcmdb_set *set, bcmdb_key key, int is_deletion)
+{
+ bcmdb_entry *entry;
+
+ /* there is nothing to return in deletion case */
+ if (is_deletion)
+ return NULL;
+
+ entry = set->key_to_handle(set, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ return NULL;
+ return entry->data;
+}
+
+/** none policy: record unlock */
+static inline void bcmdb_dummy_unlock(bcmdb_set *set)
+{
+}
+
+/** none policy: record lock for reading */
+static inline void *bcmdb_dummy_lock_read(bcmdb_set *set, bcmdb_key key)
+{
+ return bcmdb_dummy_lock(set, key, 0);
+}
+
+/** none policy: record unlock for reading */
+static inline void bcmdb_dummy_unlock_read(bcmdb_set *set, bcmdb_key key)
+{
+ bcmdb_dummy_unlock(set);
+}
+
+/** none policy: record lock for writing */
+static inline void *bcmdb_dummy_lock_write(bcmdb_set *set, bcmdb_key key, int is_deletion)
+{
+ return bcmdb_dummy_lock(set, key, is_deletion);
+}
+
+/** none policy: record unlock for writing */
+static inline void bcmdb_dummy_unlock_write(bcmdb_set *set, int is_deletion, int is_cancellation)
+{
+ bcmdb_dummy_unlock(set);
+}
+
+
+
+/** Add new sub-set. returns 0 if ok
+ * data contains new set handle
+ */
+static int bcmdb_set_new(bcmdb_set *this, bcmdb_key key, const void *data)
+{
+ /* Although this callback takes "const void *" parameter,
+ * it is just for compatibility fith SoR->new_entry interface.
+ * For SoS this parameter is not constant on application level
+ * (see bcmdb_set_add())
+ */
+ bcmdb_entry *entry = this->key_to_handle(this, key);
+ bcmdb_set *new_set = (bcmdb_set *)(long)data;
+
+ if (!entry)
+ return BCM_ERR_PARM;
+ if ((entry->flags & BCMDB_FLAG_VALID))
+ return BCM_ERR_ALREADY;
+ ++this->num_entries;
+ entry->data = (void *)(long)data;
+ entry->flags |= BCMDB_FLAG_VALID;
+ new_set->my_key = key;
+ new_set->parent = this;
+ return 0;
+}
+
+/** Add new record. returns 0 if ok
+ * data contains record data pointer
+ */
+static int bcmdb_record_new(bcmdb_set *this, bcmdb_key key, const void *data)
+{
+ bcmdb_record *record = (bcmdb_record *)this->key_to_handle(this, key);
+ if (!record || !record->e.data)
+ return BCM_ERR_PARM;
+ if ((record->e.flags & BCMDB_FLAG_VALID))
+ return BCM_ERR_ALREADY;
+ ++this->num_entries;
+ memcpy(record->e.data, data, this->entry_size);
+ record->e.flags |= BCMDB_FLAG_VALID;
+ return 0;
+}
+
+/** Delete entry */
+static int bcmdb_entry_delete(bcmdb_set *this, bcmdb_entry *entry)
+{
+ if (!entry)
+ return BCM_ERR_PARM;
+ if (!(entry->flags & BCMDB_FLAG_VALID))
+ return BCM_ERR_ALREADY;
+ entry->flags &= ~BCMDB_FLAG_VALID;
+ --this->num_entries;
+ return 0;
+}
+
+
+/*
+ * External APIs
+ */
+
+
+/** Initialize data base engine
+ *
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ * \ingroup bcmdb
+ */
+int bcmdb_module_init(void)
+{
+ return 0;
+}
+
+
+/** Make set-of-sets control block.
+ *
+ * Helper function that creates a set of sets with reasonable defaults for all callbacks and fields.
+ * Once created, the set control block can be tuned before adding the new set to its parent set.
+ * \param[in] init set parameters
+ * \param[out] new_set set control block
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_make_set_of_sets(const bcmdb_sos_init *init, bcmdb_set **new_set)
+{
+ bcmdb_set *sos;
+ bcmdb_entry *entries;
+ int rc;
+
+ /* Parameter check */
+ if (!init || !init->name || !new_set)
+ return BCM_ERR_PARM;
+ if ((init->backend_type == BCMDB_BACKEND_ARRAY) && !init->max_entries)
+ return BCM_ERR_PARM;
+
+ /* Allocate set control block and set records */
+ sos = bcmos_calloc(sizeof(bcmdb_set) + strlen(init->name) + 1);
+ if (!sos)
+ return BCM_ERR_NOMEM;
+ sos->name = (char *)(sos + 1);
+ strcpy(sos->name, init->name);
+ sos->entry_size = sizeof(bcmdb_set);
+ sos->max_entries = init->max_entries;
+ sos->my_key = BCMDB_KEY_INVAL;
+ sos->entry.flags = BCMDB_FLAG_SOS;
+ sos->magic = BCMDB_MAGIC_ACTIVE_SET;
+
+ /* Set backend callbacks */
+ switch(init->backend_type)
+ {
+ case BCMDB_BACKEND_ARRAY:
+ entries = bcmos_calloc(sizeof(bcmdb_set)*init->max_entries);
+ if (!entries)
+ {
+ bcmos_free(sos);
+ return BCM_ERR_NOMEM;
+ }
+ sos->entry.data = entries;
+ sos->entry_get_next = _bcmdb_array_entry_get_next;
+ sos->handle_to_key = _bcmdb_array_handle_to_key;
+ sos->key_to_handle = _bcmdb_array_key_to_handle;
+ sos->entry_new = bcmdb_set_new;
+ sos->entry_delete = bcmdb_entry_delete;
+ break;
+
+ default:
+ printf("Only array-based DB backend is supported\n");
+ bcmos_free(sos);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ /* Set locking callbacks. SoS locking policy is always SEMAPHORE */
+
+ /* in SoS, locking for read is same as for write (and is done recursively). */
+ sos->lock_set_read = bcmdb_set_lock_recursively_modify_sem;
+ sos->unlock_set_read = bcmdb_set_unlock_recursively_modify_sem;
+ sos->lock_set_modify = bcmdb_set_lock_modify_sem;
+ sos->unlock_set_modify = bcmdb_set_unlock_modify_sem;
+ sos->lock_set_recursively_modify = bcmdb_set_lock_recursively_modify_sem ;
+ sos->unlock_set_recursively_modify = bcmdb_set_unlock_recursively_modify_sem ;
+
+ /* create mutex_update */
+ rc = bcmos_mutex_create(&sos->mutex_update, init->os_flags);
+ if (rc)
+ {
+ bcmos_free(entries);
+ bcmos_free(sos);
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmos_fastlock_init(&sos->fastlock, init->os_flags);
+
+ *new_set = sos;
+
+ return 0;
+}
+
+
+
+
+/** Make set-of-records control block.
+ *
+ * Helper function that creates a set of records with reasonable defaults for all callbacks and fields.
+ * Once created, the set control block can be tuned before adding the new set to its parent set.
+ * \param[in] init set parameters
+ * \param[in] alloc_records true (1) - allocate memory for all records.
+ * \param[out] new_set set control block
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_make_set_of_records(const bcmdb_sor_init *init, int alloc_records, bcmdb_set **new_set)
+{
+ bcmdb_set *sor;
+ bcmdb_entry *entries = NULL;
+ void *data = NULL;
+ int i;
+ int rc ;
+
+ /* Parameter check */
+ if (!init || !init->name)
+ return BCM_ERR_PARM;
+ if ((init->backend_type == BCMDB_BACKEND_ARRAY) && !init->max_entries)
+ return BCM_ERR_PARM;
+ if (!init->record_size)
+ return BCM_ERR_PARM;
+
+ /* Allocate set control block and set records */
+ sor = bcmos_calloc(sizeof(bcmdb_set) + strlen(init->name) + 1);
+ if (!sor)
+ return BCM_ERR_NOMEM;
+ sor->name = (char *)(sor + 1);
+ strcpy(sor->name, init->name);
+ sor->entry_size = init->record_size;
+ sor->max_entries = init->max_entries;
+ sor->my_key = BCMDB_KEY_INVAL;
+ sor->magic = BCMDB_MAGIC_ACTIVE_SET;
+ sor->format = init->format;
+
+ /* Set backend callbacks */
+ switch(init->backend_type)
+ {
+ case BCMDB_BACKEND_ARRAY:
+ entries = bcmos_calloc(sizeof(bcmdb_entry)*init->max_entries);
+ if (!entries)
+ {
+ bcmos_free(sor);
+ return BCM_ERR_NOMEM;
+ }
+ sor->entry.data = entries;
+ sor->entry_get_next = _bcmdb_array_entry_get_next;
+ sor->handle_to_key = _bcmdb_array_handle_to_key;
+ sor->key_to_handle = _bcmdb_array_key_to_handle;
+ sor->entry_new = bcmdb_record_new;
+ sor->entry_delete = bcmdb_entry_delete;
+
+ /* Preallocate data */
+ if (alloc_records)
+ {
+ int size = init->max_entries * init->record_size;
+ if (init->lock_policy == BCMDB_LOCK_NB_READ_SHADOW_WRITE)
+ size += init->record_size; /* room for shadow entry */
+ /* Allocate data + 1 extra for shadow area */
+ data = bcmos_calloc(size);
+ if (!data)
+ {
+ bcmos_free(entries);
+ bcmos_free(sor);
+ return BCM_ERR_NOMEM;
+ }
+ for(i=0; i<init->max_entries; i++)
+ {
+ bcmdb_entry *entry = (bcmdb_entry *)sor->entry.data + i;
+ entry->data = (void *)((long)data + i * init->record_size);
+ }
+ if (init->lock_policy == BCMDB_LOCK_NB_READ_SHADOW_WRITE)
+ {
+ sor->shadow_data = (void *)((long)data + i * init->record_size);
+ }
+ }
+
+ /* Initialize records */
+ for(i=0; i<init->max_entries; i++)
+ {
+ bcmdb_entry *entry = (bcmdb_entry *)sor->entry.data + i;
+ entry->flags = BCMDB_FLAG_RECORD;
+ }
+ break;
+
+ default:
+ printf("Only array-based DB backend is supported\n");
+ bcmos_free(sor);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ /* Set locking callbacks based on locking policy */
+ switch(init->lock_policy)
+ {
+ case BCMDB_LOCK_SEM_READ_SEM_WRITE:
+ sor->lock_record_write = bcmdb_sem_read_sem_write_lock_write;
+ sor->lock_record_read = bcmdb_sem_read_sem_write_lock_read;
+ sor->unlock_record_write = bcmdb_sem_read_sem_write_unlock_write;
+ sor->unlock_record_read = bcmdb_sem_read_sem_write_unlock_read;
+ sor->lock_set_read = bcmdb_set_lock_read_sem;
+ sor->unlock_set_read = bcmdb_set_unlock_read_sem;
+ sor->lock_set_modify = bcmdb_set_lock_modify_sem;
+ sor->unlock_set_modify = bcmdb_set_unlock_modify_sem;
+ sor->lock_set_recursively_modify = bcmdb_set_lock_recursively_modify_sem ;
+ sor->unlock_set_recursively_modify = bcmdb_set_unlock_recursively_modify_sem ;
+ break;
+
+ case BCMDB_LOCK_NONE:
+ case BCMDB_LOCK_OTHER:
+ sor->lock_record_write = bcmdb_dummy_lock_write;
+ sor->lock_record_read = bcmdb_dummy_lock_read;
+ sor->unlock_record_write = bcmdb_dummy_unlock_write;
+ sor->unlock_record_read = bcmdb_dummy_unlock_read;
+ sor->lock_set_read = bcmdb_set_lock_read_dummy;
+ sor->unlock_set_read = bcmdb_set_unlock_read_dummy;
+ sor->lock_set_modify = bcmdb_set_lock_modify_dummy;
+ sor->unlock_set_modify = bcmdb_set_unlock_modify_dummy;
+ sor->lock_set_recursively_modify = bcmdb_set_lock_recursively_modify_dummy ;
+ sor->unlock_set_recursively_modify = bcmdb_set_unlock_recursively_modify_dummy ;
+ break;
+
+ case BCMDB_LOCK_NB_READ_SHADOW_WRITE:
+ sor->lock_record_write = bcmdb_nb_read_shadow_write_lock_write;
+ sor->lock_record_read = bcmdb_nb_read_shadow_write_lock_read;
+ sor->unlock_record_write = bcmdb_nb_read_shadow_write_unlock_write;
+ sor->unlock_record_read = bcmdb_nb_read_shadow_write_unlock_read;
+ sor->lock_set_read = bcmdb_set_lock_read__nb_read_sem_write;
+ sor->unlock_set_read = bcmdb_set_unlock_read__nb_read_sem_write;
+ sor->lock_set_modify = bcmdb_set_lock_modify__nb_read_sem_write;
+ sor->unlock_set_modify = bcmdb_set_unlock_modify__nb_read_sem_write;
+ sor->lock_set_recursively_modify = bcmdb_set_lock_recursively_modify_sem ;
+ sor->unlock_set_recursively_modify = bcmdb_set_unlock_recursively_modify_sem ;
+ break;
+
+ default:
+ printf("Lock policy %d is not supported\n", init->lock_policy);
+ if (data)
+ bcmos_free(data);
+ if (entries)
+ bcmos_free(entries);
+ bcmos_free(sor);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ /* create mutex_update */
+ rc = bcmos_mutex_create(&sor->mutex_update, init->os_flags);
+ if (rc)
+ {
+ if (data)
+ bcmos_free(data);
+ if (entries)
+ bcmos_free(entries);
+ bcmos_free(sor);
+ return BCM_ERR_NOMEM;
+ }
+
+ /* create sem_wait_read_to_finish. it is initialized to be taken */
+ rc = bcmos_sem_create(&sor->sem_wait_read_to_finish, 0, init->os_flags);
+ if (rc)
+ {
+ /* no point to check here the error code of bcmos_mutex_destroy */
+ bcmos_mutex_destroy(&sor->mutex_update);
+ if (data)
+ bcmos_free(data);
+ if (entries)
+ bcmos_free(entries);
+ bcmos_free(sor);
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmos_fastlock_init(&sor->fastlock, init->os_flags);
+
+ *new_set = sor;
+
+ return 0;
+}
+
+
+/** Lock data set for reading. When set is locked - it can't be
+ * modified.
+ *
+ * \param[in] set data base set to be locked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_lock_read(bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!set->lock_set_read);
+ set->lock_set_read(set);
+}
+
+
+/** Release data set lock
+ *
+ * Unlock set locked by \ref bcmdb_set_lock_read
+ *
+ * \param[in] set data base set to be unlocked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_unlock_read(bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!set->unlock_set_read);
+ set->unlock_set_read(set);
+}
+
+
+/** Lock data set for modify. If the set is SoS, the locking
+ * will be recursive.
+ *
+ * \param[in] set data base set to be locked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_lock_modify(bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!set->lock_set_recursively_modify);
+ set->lock_set_recursively_modify(set);
+}
+
+
+/** Release data set lock
+ *
+ * Unlock set locked by \ref bcmdb_set_lock_modify
+ *
+ * \param[in] set data base set to be unlocked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_unlock_modify(bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!set->unlock_set_recursively_modify);
+ set->unlock_set_recursively_modify(set);
+}
+
+
+/** Add set to the parent set with specific key.
+ *
+ * The function adds set to the parent set creating data base hierarchy.
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ * \param[in] sos parent set of sets
+ * \param[in] key key to add new set at
+ * \param[in] new_set set control block
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ * \ingroup bcmdb
+ */
+int bcmdb_set_add(bcmdb_set *sos, bcmdb_key key, bcmdb_set *new_set)
+{
+ int rc;
+ long fastlock_flags;
+ BUG_ON(!sos);
+ BUG_ON(!sos->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sos->entry.flags & BCMDB_FLAG_SOS));
+ BUG_ON(!new_set);
+ BUG_ON(!new_set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!new_set->my_key == BCMDB_KEY_INVAL);
+ fastlock_flags = sos->lock_set_modify(sos);
+ rc = sos->entry_new(sos, key, new_set);
+ sos->unlock_set_modify(sos, fastlock_flags);
+ return rc;
+}
+
+
+/** Get set handle given its key.
+ *
+ * \param[in] sos parent set of sets
+ * \param[in] key set key.
+ * \return
+ * !=0 - set handle
+ * NULL- doesn't exist
+ * \ingroup bcmdb
+ */
+bcmdb_set *bcmdb_set_handle(const bcmdb_set *sos, bcmdb_key key)
+{
+ bcmdb_entry *entry;
+ BUG_ON(!sos);
+ BUG_ON(!sos->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sos->entry.flags & BCMDB_FLAG_SOS));
+ entry = sos->key_to_handle(sos, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ return NULL;
+ return (bcmdb_set *)entry->data;
+}
+
+
+/** Get set key given its handle.
+ *
+ * \param[in] set set handle
+ * \param[in] key set key.
+ * \return
+ * !=BCMDB_KEY_INVAL - set key
+ * BCMDB_KEY_INVAL - error
+ * \ingroup bcmdb
+ */
+bcmdb_key bcmdb_set_key(const bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ return set->my_key;
+}
+
+
+/** Get set name
+ *
+ * \param[in] set set handle
+ * \return set name
+ * \ingroup bcmdb
+ */
+const char *bcmdb_set_name(const bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ return set->name;
+}
+
+
+/** Get number of records in the set.
+ *
+ * \param[in] set set handle
+ * \return number of active records in the set
+ * \ingroup bcmdb
+ */
+int bcmdb_set_num_records(const bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ return set->num_entries;
+}
+
+
+/** Get entry size
+ *
+ * \param[in] set set handle
+ * \return set entry size
+ * \ingroup bcmdb
+ */
+int bcmdb_set_entry_size(const bcmdb_set *set)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ return set->entry_size;
+}
+
+
+/** Add record to the parent set with specific key.
+ *
+ * The function creates a new record and adds it to the parent set with specific key.
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ * \param[in] sor parent set of records
+ * \param[in] key key to add new set at
+ * \param[in] data record data. Data size is defined at parent SOR registration time.
+ * \param[out] p_record new record handle
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ * \ingroup bcmdb
+ */
+int bcmdb_record_add(bcmdb_set *sor, bcmdb_key key, const void *data)
+{
+ int rc;
+ long fastlock_flags;
+
+ BUG_ON(!sor);
+ BUG_ON(!data);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+
+ fastlock_flags = sor->lock_set_modify(sor);
+ rc=sor->entry_new(sor, key, data);
+ sor->unlock_set_modify(sor, fastlock_flags);
+ return rc;
+}
+
+
+/** Delete record from the parent SoR given the record key.
+ *
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key.
+ */
+void bcmdb_record_delete(bcmdb_set *sor, bcmdb_key key)
+{
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+
+ sor->lock_record_write(sor, key, 1);
+ sor->unlock_record_write(sor, 1, 0);
+}
+
+
+/** Get record data pointer without locking.
+ *
+ * The function returns pointer to data structure stored in data base record.\n
+ * Attention! The caller is required to aquire read or write lock - as appropriate
+ * before calling this function and release the lock when processing is finished.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ * \ingroup bcmdb
+ */
+void *bcmdb_record_getraw_nolock(bcmdb_set *sor, bcmdb_key key)
+{
+ bcmdb_entry *entry;
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+ entry = sor->key_to_handle(sor, key);
+ if (!entry || !(entry->flags & BCMDB_FLAG_VALID))
+ return NULL;
+ return entry->data;
+}
+
+
+/** Lock record for reading and return record data pointer.
+ *
+ * The function aquires read-lock and returns pointer to data structure stored in data base record.\n
+ * read-lock must be released separately when the pointer is no longer in use.
+ * Note that the default record-read lock is non-blocking and counting.
+ * That means that multiple processes cam read-lock the same record without blocking.
+ * The function is low-level. It is recommended to use macro \ref bcmdb_record_get_read instead.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ * \ingroup bcmdb
+ */
+const void *bcmdb_record_getraw_read(bcmdb_set *sor, bcmdb_key key)
+{
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+ return sor->lock_record_read(sor, key);
+}
+
+
+/** Unlock record locked for reading.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_record_unlock_read(bcmdb_set *sor, bcmdb_key key)
+{
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+ sor->unlock_record_read(sor, key);
+}
+
+
+/** Read record data into user area.
+ *
+ * The function aquires read-lock, reads data into user area and releases read-lock.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[in] offset offset in data record
+ * \param[in] size data size. Note that offset+size must be <= record_size
+ * \param[in] data data pointer.
+ * \return
+ * =0-OK\n
+ * <0-error code
+ * \ingroup bcmdb
+ */
+int bcmdb_record_read(bcmdb_set *sor, bcmdb_key key, int offset, int size, void *data)
+{
+ const void *d = bcmdb_record_getraw_read(sor, key);
+ if (!d)
+ return BCM_ERR_PARM;
+ if ((unsigned)offset + (unsigned)size > sor->entry_size)
+ {
+ bcmdb_record_unlock_read(sor, key);
+ return BCM_ERR_PARM;
+ }
+ memcpy(data, (const char *)d+(unsigned)offset, (unsigned)size);
+ bcmdb_record_unlock_read(sor, key);
+ return 0;
+}
+
+
+/** Lock record for writing and return record data pointer.
+ *
+ * The function aquires write-lock and returns pointer to data structure stored in data base record.\n
+ * write-lock must be released separately when the pointer is no longer in use.
+ * The function is low-level. It is recommended to use macro \ref bcmdb_record_get_write instead.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ * \ingroup bcmdb
+ */
+void *bcmdb_record_getraw_write(bcmdb_set *sor, bcmdb_key key)
+{
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+ return sor->lock_record_write(sor, key, 0);
+}
+
+
+/** Unlock record locked for writing.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] is_cancellation TRUE=cancel transaction
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_record_unlock_write(bcmdb_set *sor, int is_cancellation)
+{
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!(sor->entry.flags & BCMDB_FLAG_SOS)==0);
+ sor->unlock_record_write(sor, 0, is_cancellation);
+}
+
+
+/** Write record data.
+ *
+ * The function aquires modify-lock, replaces data stored in data base record
+ * and releses the lock.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[in] offset offset in data record
+ * \param[in] size data size. Note that offset+size must be <= record_size
+ * \param[in] data data pointer.
+ * \return
+ * =0-OK\n
+ * <0-error code
+ * \ingroup bcmdb
+ */
+int bcmdb_record_write(bcmdb_set *sor, bcmdb_key key, int offset, int size, const void *data)
+{
+ void *d=bcmdb_record_getraw_write(sor, key);
+ if (!d)
+ return BCM_ERR_PARM;
+ if ((unsigned)offset + (unsigned)size > sor->entry_size)
+ {
+ bcmdb_record_unlock_write(sor, 0);
+ return BCM_ERR_PARM;
+ }
+ memcpy((char *)d+(unsigned)offset, data, (unsigned)size);
+ bcmdb_record_unlock_write(sor, 0);
+ return 0;
+}
+
+
+/** Register notification function to get informed
+ * when data base set is modified.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] cb callback function pointer
+ * \param[in] cb_priv private data that should be passed to the callback
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ * \ingroup bcmdb
+ */
+int bcmdb_set_notify_register(bcmdb_set *sor, bcmdb_notify_cb cb, long cb_priv)
+{
+ bcmdb_notify *nf_new, *nf, *nf_prev = NULL;
+
+ BUG_ON(!sor);
+ BUG_ON(!sor->magic == BCMDB_MAGIC_ACTIVE_SET);
+ BUG_ON(!cb);
+
+ nf_new = bcmos_calloc(sizeof(bcmdb_notify));
+ if (!nf_new)
+ return BCM_ERR_NOMEM;
+ nf_new->cb = cb;
+ nf_new->cb_priv = cb_priv;
+
+ /* Add to set's notification list */
+ nf = sor->notify_list_head;
+ while(nf)
+ {
+ nf_prev = nf;
+ nf = nf->next;
+ }
+ if (nf_prev)
+ nf_prev->next = nf_new;
+ else
+ sor->notify_list_head = nf_new;
+
+ return 0;
+}
+
+
+/** Data base iterator
+ *
+ * \param[in] set data base set
+ * \param[in] prev last entry. BCMDB_KEY_ANY=start from the beginning
+ * \return data base entry key following prev or BCMDB_KEY_NO_MORE if end is reached.\n
+ * BCMDB_KEY_INVAL is reqturned if prev key is invalid
+ * \ingroup bcmdb
+ */
+bcmdb_key bcmdb_set_iterate(const bcmdb_set *set, bcmdb_key prev)
+{
+ BUG_ON(!set);
+ BUG_ON(!set->magic == BCMDB_MAGIC_ACTIVE_SET);
+ return set->entry_get_next(set, prev);
+}
+
+
+/* Print database structure */
+static void _bcmdb_print_structure(const bcmdb_set *set, int level)
+{
+ int i;
+
+ if (!set)
+ return;
+
+ /* Indentation */
+ for(i=0; i<level; i++)
+ printf("\t");
+
+ if ((set->entry.flags & BCMDB_FLAG_SOS))
+ {
+ bcmdb_key key = bcmdb_set_iterate(set, BCMDB_KEY_ANY);
+ printf("%-16s SoS max_entries=%d entries=%d\n", set->name, set->max_entries, set->num_entries);
+ while(key >= 0)
+ {
+ _bcmdb_print_structure(bcmdb_set_handle(set, key), level+1);
+ key = bcmdb_set_iterate(set, key);
+ }
+ }
+ else
+ {
+ printf("%-16s SoR max_entries=%d entries=%d record_size=%d total_size=%d\n",
+ set->name, set->max_entries, set->num_entries, set->entry_size,
+ set->entry_size*set->max_entries);
+ }
+}
+
+
+/** Print database structure.
+ *
+ * \param[in] set root set
+ * \ingroup bcmdb
+ */
+void bcmdb_set_print_structure(const bcmdb_set *set)
+{
+ _bcmdb_print_structure(set, 0);
+}
+
+
+/** Format record for printing.
+ *
+ * The function converts record data to human-readible format.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[out] buffer output buffer
+ * \param[in] size buffer size
+ * \return
+ * >=0-amount of data placed in the buffer\n
+ * <0-error code
+ */
+int bcmdb_record_read_formatted(bcmdb_set *sor, bcmdb_key key, char *buffer, int size)
+{
+ const void *data;
+ int len;
+ if (!buffer || !size)
+ return BCM_ERR_PARM;
+ if (!sor->format)
+ return BCM_ERR_NOT_SUPPORTED;
+ *buffer=0;
+ data = bcmdb_record_getraw_read(sor, key);
+ if (!data)
+ return 0;
+ len = sor->format(data, buffer, size);
+ bcmdb_record_unlock_read(sor, key);
+ return len;
+}
diff --git a/bal_release/src/common/db_engine/bcm_db_engine.h b/bal_release/src/common/db_engine/bcm_db_engine.h
new file mode 100644
index 0000000..8d77022
--- /dev/null
+++ b/bal_release/src/common/db_engine/bcm_db_engine.h
@@ -0,0 +1,622 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/*
+ * bcm_db_engine.c
+ *
+ * Data base engine
+ */
+#ifndef BCMDB_ENGINE_H
+
+#define BCMDB_ENGINE_H
+
+/** \defgroup bcmdb_e Data Base Engine Module
+Hierarchical data base is built from 3 types of objects:
+- set: consists of control info and dynamic array of other sets OR of records of the same kind.
+ - Mixing subsets and records in the same set is not supported.
+ - Sets are objects that perform operations like access, locking, adding or removing elements,
+ etc., via methods that can differ for every set.
+ - Set elements are addressed using a single key.
+ - Most sets are internally organized as arrays. However, other organizations (e.g., lists, hash tables)
+ are also possible because each set can have different set of methods for element access.
+- record: is a container for storing information.
+ - Record consists of control info and a structure containing fields.
+ - Record is the smallest DB element that has a handle and can be individually locked.
+ - Record size is fixed at time when the set containing records is created.
+- field: is a convenience element.
+ - DB API includes field access macros for convenience and traceability.
+ Apart from that, record layout is transparent to the DB engine.
+ - DB user has an option of accessing record fields directly (as C structure fields), without using DB API
+ @{
+*/
+
+#define bcmdb_error_print(rc,format,args...) BCMOS_TRACE_ERR("status:%s :" format, bcmos_strerror(rc), ##args)
+
+/** Data base backend type
+ */
+typedef enum
+{
+ BCMDB_BACKEND_ARRAY, /**< Array-based backend */
+ BCMDB_BACKEND_HASH, /**< Hash-based backend */
+ BCMDB_BACKEND_OTHER /**< User-defined backend */
+} bcmdb_backend_type;
+
+
+/** Data locking policy
+ */
+typedef enum
+{
+ BCMDB_LOCK_NONE, /**< No record-level locking. Can be used for records containing independent fields */
+ BCMDB_LOCK_NB_READ_SHADOW_WRITE,/**< Non-blocking read, write using shadow area (default) */
+ BCMDB_LOCK_SEM_READ_SEM_WRITE, /**< Strong locking. Both read and write locks use semaphores */
+ BCMDB_LOCK_OTHER /**< User-defined locking policy */
+} bcmdb_lock_policy;
+
+
+/** Data base key
+ * Valid values >= 0
+ */
+typedef int bcmdb_key;
+
+
+/** Any key
+ */
+#define BCMDB_KEY_ANY (-1)
+
+/** Invalid key
+ */
+#define BCMDB_KEY_INVAL (-2)
+
+/** No more records
+ */
+#define BCMDB_KEY_NO_MORE (-3)
+
+
+ /** Data Base Set control block */
+typedef struct bcmdb_set bcmdb_set;
+
+/** Data Base Record control block */
+typedef struct bcmdb_record bcmdb_record;
+
+/** Data Base Set or Record */
+typedef struct bcmdb_entry bcmdb_entry;
+
+
+/** Data base operations for notifications.
+ */
+typedef enum
+{
+ BCMDB_OPER_ADD, /**< Entry has been added */
+ BCMDB_OPER_DELETE, /**< Entry has been deleted */
+ BCMDB_OPER_UPDATE /**< Entry has been modified */
+} bcmdb_oper_t;
+
+
+/** Data base update notification callback.
+ */
+typedef void (*bcmdb_notify_cb)(bcmdb_set *set, bcmdb_key key, bcmdb_oper_t oper, void *new_data);
+
+
+/** Format callback. Used by bcmdb_record_read_formatted to convert record data to human-readible format */
+typedef int (*bcmdb_format_cb)(const void *data, char *buffer, int buffer_size);
+
+
+/** Set-of-Sets init structure.
+ */
+typedef struct bcmdb_sos_init
+{
+ const char *name; /**< Set name */
+ bcmdb_backend_type backend_type; /**< Backend type */
+ uint32_t max_entries; /**< Max number of entries. 0=unlimited (not supported for array backend) */
+ uint32_t os_flags; /**< OS flags. Control whether set can be accessed by multiple cores. See bcmos_mutex_create() */
+} bcmdb_sos_init;
+
+
+/** Set-of-Records init structure.
+ */
+typedef struct bcmdb_sor_init
+{
+ const char *name; /**< Set name */
+ bcmdb_backend_type backend_type; /**< Backend type */
+ bcmdb_lock_policy lock_policy; /**< Set locking policy */
+ uint32_t max_entries; /**< Max number of entries. 0=unlimited (not supported for array backend) */
+ uint32_t record_size; /**< Record size > 0 */
+ bcmdb_format_cb format; /**< callback that converts record data to human-readable form */
+ uint32_t os_flags; /**< OS flags. Control whether set can be accessed by multiple cores. See bcmos_mutex_create() */
+} bcmdb_sor_init;
+
+
+/** Initialize data base engine
+ *
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_module_init(void);
+
+
+/** Make set-of-sets control block.
+ *
+ * Helper function that creates a set of sets with reasonable defaults for all callbacks and fields.
+ * Once created, the set control block can be tuned before adding the new set to its parent set.
+ * \param[in] init set parameters
+ * \param[out] new_set set control block
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_make_set_of_sets(const bcmdb_sos_init *init, bcmdb_set **new_set);
+
+
+/** Make set-of-sets control block macro.
+ *
+ * Calls \ref bcmdb_make_set_of_sets.
+ * Prints error message and jumps to error_label in case of failure.
+ * For parameter description see \ref bcmdb_make_set_of_sets
+ */
+#define BCMDB_MAKE_SOS(_name,_backend,_max_entries,_p_handle,_rc,_error_label) \
+({\
+ bcmdb_sos_init _init = { .name=_name, .max_entries=_max_entries, .backend_type=_backend};\
+ _rc = bcmdb_make_set_of_sets(&_init, _p_handle);\
+ if (_rc)\
+ {\
+ bcmdb_error_print(_rc, "failed to create set %s.\n", _name);\
+ goto _error_label;\
+ }\
+})
+
+
+/** Make set-of-records control block.
+ *
+ * Helper function that creates a set of records with reasonable defaults for all callbacks and fields.
+ * Once created, the set control block can be tuned before adding the new set to its parent set.
+ * \param[in] init set parameters
+ * \param[in] alloc_records true (1) - allocate memory for all records.
+ * \param[out] new_set set control block
+ * \return
+ * 0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_make_set_of_records(const bcmdb_sor_init *init, int alloc_records, bcmdb_set **new_set);
+
+
+/** Make set-of-records control block macro.
+ *
+ * Calls \ref bcmdb_make_set_of_records.
+ * Prints error message and jumps to error_label in case of failure.
+ * For parameter description see \ref bcmdb_make_set_of_records
+ */
+#define BCMDB_MAKE_SOR(_name,_backend,_lock,_max_entries,_rec_size,_is_alloc,_format,_p_handle,_rc,_error_label) \
+({\
+ bcmdb_sor_init _init = { .name=_name, .max_entries=_max_entries, .backend_type=_backend,\
+ .lock_policy=_lock, .record_size=_rec_size,.format=_format};\
+ _rc = bcmdb_make_set_of_records(&_init,_is_alloc,_p_handle);\
+ if (_rc)\
+ {\
+ bcmdb_error_print(_rc, "failed to create record set %s.\n", _name);\
+ goto _error_label;\
+ }\
+})
+
+
+/** Lock data set. When set is locked - it can't be modified.
+ *
+ * \param[in] set data base set to be locked
+ *
+ */
+void bcmdb_set_lock_read(bcmdb_set *set);
+
+
+/** Release data set lock
+ *
+ * Unlock set locked by \ref bcmdb_set_lock_read
+ *
+ * \param[in] set data base set to be unlocked
+ */
+void bcmdb_set_unlock_read(bcmdb_set *set);
+
+
+/** Lock data set for modify. If the set is SoS, the locking
+ * will be recursive.
+ *
+ * \param[in] set data base set to be locked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_lock_modify(bcmdb_set *set);
+
+
+/** Release data set lock
+ *
+ * Unlock set locked by \ref bcmdb_set_lock_modify
+ *
+ * \param[in] set data base set to be unlocked
+ *
+ * \ingroup bcmdb
+ */
+void bcmdb_set_unlock_modify(bcmdb_set *set);
+
+
+/** Add set to the parent set.
+ *
+ * The function adds set to the parent set creating data base hierarchy.
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ * \param[in] sos parent set of sets
+ * \param[in] key key to add new set at
+ * \param[in] new_set set control block
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_set_add(bcmdb_set *sos, bcmdb_key key, bcmdb_set *new_set);
+
+
+/** Add set to the parent set with specific key macro.
+ *
+ * Calls \ref bcmdb_set_add.
+ * Prints error message and jumps to error_label in case of failure.
+ * For parameter description see \ref bcmdb_set_add
+ */
+#define BCMDB_SET_ADD(_parent,_key,_set,_rc,_error_label) \
+({\
+ _rc = bcmdb_set_add(_parent,_key,_set);\
+ if (_rc)\
+ {\
+ bcmdb_error_print(_rc, "failed to add set %s to %s.\n", bcmdb_set_name(_set), bcmdb_set_name(_parent));\
+ goto _error_label;\
+ }\
+})
+
+
+/** Get set handle given its key.
+ *
+ * \param[in] sos parent set of sets
+ * \param[in] key set key.
+ * \return
+ * !=0 - set handle
+ * NULL- doesn't exist
+ */
+bcmdb_set *bcmdb_set_handle(const bcmdb_set *sos, bcmdb_key key);
+
+
+/** Get set key given its handle.
+ *
+ * \param[in] set set handle
+ * \return
+ * !=BCMDB_KEY_INVAL - set key\n
+ * BCMDB_KEY_INVAL - error
+ */
+bcmdb_key bcmdb_set_key(const bcmdb_set *set);
+
+
+/** Get set name
+ *
+ * \param[in] set set handle
+ * \return set name
+ */
+const char *bcmdb_set_name(const bcmdb_set *set);
+
+
+/** Get number of records in the set.
+ *
+ * \param[in] set set handle
+ * \return number of active records in the set
+ */
+int bcmdb_set_num_records(const bcmdb_set *set);
+
+
+/** Get entry size
+ *
+ * \param[in] set set handle
+ * \return set entry size
+ */
+int bcmdb_set_entry_size(const bcmdb_set *set);
+
+
+/** Add record to the parent set.
+ *
+ * The function creates a new record and adds it to the parent set with specific key.
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[in] data record data. Data size is defined at parent SOR registration time.
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_record_add(bcmdb_set *sor, bcmdb_key key, const void *data);
+
+
+/** Delete record from the parent SoR given the record key.
+ *
+ * The function automatically acquires modify lock and releases it
+ * in the end of operation.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key.
+ */
+void bcmdb_record_delete(bcmdb_set *sor, bcmdb_key key);
+
+
+/** Get record data pointer without locking.
+ *
+ * The function returns pointer to data structure stored in data base record.\n
+ * Attention! The caller is required to aquire read or write lock - as appropriate
+ * before calling this function and release the lock when processing is finished.
+ * The function is low-level. It is recommended to use \ref bcmdb_record_get_nolock instead.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ */
+void *bcmdb_record_getraw_nolock(bcmdb_set *sor, bcmdb_key key);
+
+
+/** Get record data pointer without locking.
+ *
+ * The function returns pointer to data structure stored in data base record.\n
+ * Attention! The caller is required to aquire read or write lock - as appropriate
+ * before calling this function and release the lock when processing is finished.
+ *
+ * \param[in] _sor parent set of records
+ * \param[in] _key record key
+ * \param[in] _record_type underlying data type.
+ * \return
+ * data pointer casted to the underlying data type\n
+ * NULL if there is no record matching the key.
+ */
+#define bcmdb_record_get_nolock(_sor, _key, _record_type) \
+ ({ \
+ assert(sizeof(_record_type)==bcmdb_set_entry_size(_sor)); \
+ (_record_type *)bcmdb_record_getraw_nolock(_sor, _key); \
+ })
+
+
+/** Lock record for reading and return record data pointer.
+ *
+ * The function aquires read-lock and returns pointer to data structure stored in data base record.\n
+ * read-lock must be released separately when the pointer is no longer in use.
+ * Note that the default record-read lock is non-blocking and counting.
+ * That means that multiple processes can read-lock the same record without blocking.
+ * The function is low-level. It is recommended to use macro \ref bcmdb_record_get_read instead.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ */
+const void *bcmdb_record_getraw_read(bcmdb_set *sor, bcmdb_key key);
+
+
+/** Lock record for reading and return record data pointer.
+ *
+ * The macro returns pointer to data structure stored in data base record.\n
+ * The read-lock must be released separately when the pointer is no longer in use.
+ * Note that the default record-read lock is non-blocking and counting.
+ * That means that multiple processes can read-lock the same record without blocking.
+ *
+ * \param[in] _sor parent set of records
+ * \param[in] _key record key
+ * \param[in] _record_type underlying data type.
+ * \return
+ * data pointer casted to the underlying data type
+ */
+#define bcmdb_record_get_read(_sor, _key, _record_type) \
+ ({ \
+ assert(sizeof(_record_type)==bcmdb_set_entry_size(_sor)); \
+ (const _record_type *)bcmdb_record_getraw_read(_sor, _key);\
+ })
+
+
+/** Unlock record locked for reading.
+ *
+ * This function must be called after \ref bcmdb_record_get_read or
+ * \ref bcmdb_record_getraw_read. Following bcmdb_record_read_unlock
+ * call pointer returned by \ref bcmdb_record_get_read becomes invalid.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ *
+ */
+void bcmdb_record_unlock_read(bcmdb_set *sor, bcmdb_key key);
+
+
+/** Read record data into user area.
+ *
+ * The function aquires read-lock, reads data into user area and releases read-lock.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[in] offset offset in data record
+ * \param[in] size data size. Note that offset+size must be <= record_size
+ * \param[in] data data pointer.
+ * \return
+ * =0-OK\n
+ * <0-error code
+ */
+int bcmdb_record_read(bcmdb_set *sor, bcmdb_key key, int offset, int size, void *data);
+
+
+/** Get record field.
+ *
+ * The macro returns record field value.
+ *
+ * \param[in] _sor parent set of records
+ * \param[in] _key record key
+ * \param[in] _record_type type of the underlying data structure.
+ * \param[in] _field_name data structure field name
+ * \param[out] _p_field_value pointer of variable where data structure field value should be returned
+ * \return
+ * =0-OK\n
+ * <0-error code
+ */
+#define bcmdb_record_read_field(_sor, _key, _record_type, _field_name, _p_field_value) \
+ bcmdb_record_read(_sor, _key, offsetof(_record_type, _field_name), \
+ sizeof(*(_p_field_value)), _p_field_value);
+
+
+/** Lock record for writing and return record data pointer.
+ *
+ * The function aquires write-lock and returns pointer to data structure stored in data base record.\n
+ * write-lock must be released separately when the pointer is no longer in use.
+ * The function is low-level. It is recommended to use macro \ref bcmdb_record_get_write instead.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \return
+ * data pointer. NULL if there is no record matching the key.
+ */
+void *bcmdb_record_getraw_write(bcmdb_set *sor, bcmdb_key key);
+
+
+/** Lock record for writing and return record data pointer.
+ *
+ * The function aquires write-lock and returns pointer to data structure stored in data base record.\n
+ * write-lock must be released separately when the pointer is no longer in use.
+ *
+ * \param[in] _sor parent set of records
+ * \param[in] _key record key
+ * \param[in] _record_type underlying data type.
+ * \return
+ * data pointer casted to the underlying data type
+ */
+#define bcmdb_record_get_write(_sor, _key, _record_type) \
+ ({ \
+ assert(sizeof(_record_type)==bcmdb_set_entry_size(_sor)); \
+ (_record_type *)bcmdb_record_getraw_write(_sor, _key);\
+ })
+
+
+/** Unlock record locked for writing.
+ *
+ * This function must be called after \ref bcmdb_record_get_write or
+ * \ref bcmdb_record_getraw_write. Following bcmdb_record_unlock_write
+ * call pointer returned by \ref bcmdb_record_get_write becomes invalid.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] is_cancellation TRUE=cancel transaction
+ *
+ */
+void bcmdb_record_unlock_write(bcmdb_set *sor, int is_cancellation);
+
+
+
+/** Write record data.
+ *
+ * The function aquires modify-lock, replaces data stored in data base record
+ * and releses the lock.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[in] offset offset in data record
+ * \param[in] size data size. Note that offset+size must be <= record_size
+ * \param[in] data data pointer.
+ * \return
+ * =0-OK\n
+ * <0-error code
+ */
+int bcmdb_record_write(bcmdb_set *sor, bcmdb_key key, int offset, int size, const void *data);
+
+
+/** Write record field.
+ *
+ * The macro updates record field value.\n
+ * The macro aquires and releases record-modify lock.
+ *
+ * \param[in] _sor parent set of records
+ * \param[in] _key record key
+ * \param[in] _record_type type of the underlying data structure.
+ * \param[in] _field_name data structure field name
+ * \param[in] _field_value field value
+ * \return
+ * =0-OK\n
+ * <0-error code
+ */
+#define bcmdb_record_write_field(_sor, _key, _record_type, _field_name, _field_value) \
+ ({ \
+ typeof(((_record_type *)0)->_field_name) _f = _field_value;\
+ bcmdb_record_write(_sor, _key, offsetof(_record_type, _field_name), sizeof(_f), &_f);\
+ });
+
+
+/** Register notification function to get informed
+ * when data base set is modified.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] cb callback function pointer
+ * \param[in] cb_priv private data that should be passed to the callback
+ * \return
+ * =0 - OK\n
+ * <0 - error code
+ */
+int bcmdb_set_notify_register(bcmdb_set *sor, bcmdb_notify_cb cb, long cb_priv);
+
+
+/** Data base iterator
+ *
+ * \param[in] set data base set
+ * \param[in] prev last entry. BCMDB_KEY_ANY=start from the beginning
+ * \return data base entry key following prev or BCMDB_KEY_NO_MORE if end is reached.\n
+ * BCMDB_KEY_INVAL is reqturned if prev key is invalid
+ */
+bcmdb_key bcmdb_set_iterate(const bcmdb_set *set, bcmdb_key prev);
+
+
+/** Print database structure.
+ *
+ * \param[in] set root set
+ */
+void bcmdb_set_print_structure(const bcmdb_set *set);
+
+
+/** Format record for printing.
+ *
+ * The function converts record data to human-readable format.
+ *
+ * \param[in] sor parent set of records
+ * \param[in] key record key
+ * \param[out] buffer output buffer
+ * \param[in] size buffer size
+ * \return
+ * >=0-amount of data placed in the buffer\n
+ * <0-error code
+ */
+int bcmdb_record_read_formatted(bcmdb_set *sor, bcmdb_key key, char *buffer, int size);
+
+
+/** @} end of bcmdb_e group */
+
+
+#endif /* #ifndef BCMDB_ENGINE_H */
+
diff --git a/bal_release/src/common/db_engine/unitest.c b/bal_release/src/common/db_engine/unitest.c
new file mode 100644
index 0000000..ca638ce
--- /dev/null
+++ b/bal_release/src/common/db_engine/unitest.c
@@ -0,0 +1,490 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/*
+ * unitest.c
+ *
+ * Created on: 2013-12-10
+ * Author: swallace
+ */
+
+#include "bcmos_system.h"
+#include "bcm_db_engine.h"
+
+/* EPON LLID data structure subset */
+typedef enum
+ {
+ /* Free entry in the LLID management table, available for assignment on an
+ MPCP register request. */
+ unassigned_llid,
+ /* Locked out waiting on a timer to release the LLID */
+ not_registered_llid,
+ /* Waiting for permission to register from host */
+ ignored_llid,
+ /* LLID has been assigned to an ONU MAC but not registered. Intermediate
+ state before the ONU returns a registration ack. */
+ wait_reg_ack_llid,
+ /* OLT link is in-service; user traffic is allowed */
+ inservice_llid,
+ wait_no_reports_llid,
+ /* The following state only applies to multicast/flood links */
+ in_service_mcast_llid,
+ /* We want a "Reserved" state for things like Optical monitoring */
+ reserved_llid,
+ /* We have detected a rogue ONU on this LLID - don't use it! */
+ quarantined_llid,
+ llid_state_count,
+ } epon_olt_llid_state;
+
+static char *get_llid_state_string(epon_olt_llid_state llid_state)
+{
+ static char *llid_state_strings[]= {
+ "unassigned",
+ "not_registered",
+ "ignored",
+ "wait_reg_ack",
+ "inservice",
+ "wait_no_reports",
+ "in_service_mcast",
+ "reserved",
+ "quarantined"
+ };
+
+ return llid_state_strings[(uint16_t)(llid_state)];
+}
+
+#define MAX_LINKS_PER_PORT 512
+#define MAX_PORTS_PER_HALF_CHIP 8
+#define MAX_LINKS_PER_HALF_CHIP ((MAX_LINKS_PER_PORT)*(MAX_PORTS_PER_HALF_CHIP))
+
+typedef uint8_t core_epon;
+typedef uint16_t hw_link_index;
+
+typedef struct epon_db_olt_llid_rec
+ {
+ epon_olt_llid_state state;
+ core_epon epon;
+ hw_link_index index;
+ } epon_db_olt_llid_rec;
+
+
+typedef struct epon_msg_olt_llid_rec
+{
+ uint16_t index;
+ epon_db_olt_llid_rec llid_rec;
+} epon_msg_olt_llid_rec;
+
+typedef enum
+ {
+ enabled,
+ disabled,
+ } epon_olt_port_state;
+
+static char *get_port_state_string(epon_olt_port_state port_state)
+{
+ static char *port_state_strings[]= {
+ "enabled",
+ "disabled",
+ };
+
+ return port_state_strings[(uint16_t)(port_state)];
+}
+
+
+typedef struct epon_db_olt_port_rec
+ {
+ epon_olt_port_state state;
+ } epon_db_olt_port_rec;
+
+typedef struct epon_msg_olt_port_rec
+{
+ uint16_t index;
+ epon_db_olt_port_rec port_rec;
+} epon_msg_olt_port_rec;
+
+typedef enum
+{
+ epon_olt_link_record,
+ epon_olt_port_record,
+ num_db_tables,
+} db_tables;
+
+
+/* Master database handle */
+static bcmdb_set *db_sos_set;
+
+static bcmdb_set* epon_get_db_handle(void)
+{
+ return db_sos_set;
+}
+
+#define LINK_REC_DB() bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record)
+
+#define PORT_REC_DB bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record)
+
+/* Database test messages - */
+typedef enum
+ {
+ update_link_db = 20,
+ update_port_db = 21,
+ dump_db = 30,
+ } dbtest_msgid;
+
+static inline const epon_db_olt_llid_rec *epon_olt_get_llid_rec_read(uint16_t index)
+ {
+ LINK_REC_DB();
+ return bcmdb_record_get_read(db_set, index, epon_db_olt_llid_rec);
+ };
+
+static inline void epon_db_olt_unlock_llid_rec(uint16_t index)
+ {
+ LINK_REC_DB();
+ bcmdb_record_unlock_read(db_set, index);
+ }
+
+
+#define OltGetLlidRecWrite(index) \
+ ({ \
+ LINK_REC_DB(); \
+ bcmdb_record_get_write(db_set, index, epon_db_olt_llid_rec);\
+ })
+
+#define OltCommitLlidRec(index) \
+ ({ \
+ LINK_REC_DB(); \
+ bcmdb_record_unlock_write(db_set, BCMOS_FALSE);\
+ })
+
+
+static void ut_dump_db(void)
+{
+ uint16_t index;
+ bcmdb_set *db_set;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ for (index = 0; index < MAX_PORTS_PER_HALF_CHIP; index++)
+ {
+ const epon_db_olt_port_rec *port_rec;
+ port_rec = bcmdb_record_get_read(db_set, index, epon_db_olt_port_rec);
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Record %d, state %s\n", index,
+ get_port_state_string(port_rec->state));
+ bcmdb_record_unlock_read(db_set, index);
+ }
+
+ for (index = 0; index < MAX_LINKS_PER_HALF_CHIP; index++)
+ {
+ const epon_db_olt_llid_rec *llid_rec;
+ llid_rec = epon_olt_get_llid_rec_read(index);
+ if (llid_rec->state != unassigned_llid)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Record %d, port %d, state %s\n", llid_rec->index,
+ llid_rec->epon, get_llid_state_string(llid_rec->state));
+ }
+ epon_db_olt_unlock_llid_rec(index);
+ }
+
+
+}
+
+static void ut_update_link_db(epon_msg_olt_llid_rec *rec)
+{
+ epon_db_olt_llid_rec *llid_rec;
+ llid_rec=OltGetLlidRecWrite(rec->index);
+ llid_rec->state=rec->llid_rec.state;
+
+ OltCommitLlidRec(index);
+}
+
+static void ut_update_port_db(epon_msg_olt_port_rec *rec)
+{
+ bcmdb_set *db_set;
+ epon_db_olt_port_rec *port_rec;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ port_rec = bcmdb_record_get_write(db_set, rec->index, epon_db_olt_port_rec);
+
+ port_rec->state=rec->port_rec.state;
+
+ bcmdb_record_unlock_write(db_set, BCMOS_FALSE);
+}
+
+
+static void ut_msg_handler(dbtest_msgid id, void *data)
+ {
+ switch (id)
+ {
+ case update_link_db:
+ ut_update_link_db((epon_msg_olt_llid_rec*)data);
+ break;
+
+ case update_port_db:
+ ut_update_port_db((epon_msg_olt_port_rec*)data);
+ break;
+
+ case dump_db:
+ ut_dump_db();
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+/* Database engine unit test functions */
+static uint16_t epon_db_data_init(void)
+ {
+ uint16_t index;
+ bcmdb_set *db_set;
+ int rc = 0;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record);
+ for ( index = 0;
+ (index < MAX_LINKS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
+ index++)
+ {
+ epon_db_olt_llid_rec llid_rec;
+
+ llid_rec.state = unassigned_llid;
+ llid_rec.epon = index/MAX_LINKS_PER_PORT;
+ llid_rec.index = index;
+ rc = bcmdb_record_add(db_set, index, (void *)&llid_rec);
+ }
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ for ( index = 0;
+ (index < MAX_PORTS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
+ index++)
+ {
+ epon_db_olt_port_rec port_rec;
+ port_rec.state = disabled;
+ rc = bcmdb_record_add(db_set, index, (void *)&port_rec);
+ }
+ return rc;
+ }
+
+static int epon_db_instance_init(void)
+ {
+ bcmdb_sos_init db_sos_inst;
+ bcmdb_sor_init db_sor_inst;
+ const char* db_name = "EPON STACK";
+ const char* db_llid_name = "EPON LINK REC";
+ const char* db_eport_name = "EPON PORT REC";
+ bcmdb_set *db_sor_set;
+ int rc;
+
+ db_sos_inst.name = db_name;
+ db_sos_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sos_inst.max_entries = num_db_tables;
+ rc = bcmdb_make_set_of_sets(&db_sos_inst, &db_sos_set);
+
+ if (rc >= 0)
+ {
+ db_sor_inst.name = db_llid_name;
+ db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
+ db_sor_inst.max_entries = MAX_LINKS_PER_HALF_CHIP;
+ db_sor_inst.record_size = sizeof(epon_db_olt_llid_rec);
+ db_sor_inst.format = NULL;
+ bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
+
+ rc = bcmdb_set_add(epon_get_db_handle(),
+ epon_olt_link_record, db_sor_set);
+ }
+ if (rc >= 0)
+ {
+ db_sor_inst.name = db_eport_name;
+ db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
+ db_sor_inst.max_entries = MAX_PORTS_PER_HALF_CHIP;
+ db_sor_inst.record_size = sizeof(epon_db_olt_port_rec);
+ db_sor_inst.format = NULL;
+ rc = bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
+ }
+
+ rc = bcmdb_set_add(epon_get_db_handle(), epon_olt_port_record, db_sor_set);
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "database creation returnd %d\n", rc);
+
+ if (rc >= 0)
+ {
+ rc = epon_db_data_init();
+ }
+ return rc;
+ }
+
+/* Thread handlers - so that the DB accesses can be tested across multiple
+ threads. */
+static int task1_handler(long data)
+{
+ bcmos_msg_queue *q = (bcmos_msg_queue *)data;
+ bcmos_msg *msg;
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "traditional task handler\n");
+
+ while (1)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Waiting for message\n");
+
+ bcmos_msg_recv(q, BCMOS_WAIT_FOREVER, &msg);
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Received message ID %d, data %p\n",
+ msg->type, msg->data);
+
+ ut_msg_handler(msg->type, msg->data);
+ bcmos_usleep(100000);
+ }
+
+ return 0;
+}
+
+
+static bcmos_errno mod1_init(long data)
+{
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "%ld\n", data);
+ return BCM_ERR_OK;
+}
+
+static void mod_msg_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "module %d msg %d data %p\n",
+ module_id, msg->type, msg->data);
+
+ ut_msg_handler(msg->type, msg->data);
+}
+
+
+
+/* Unit test function - */
+int main(int argc, char *argv[])
+{
+ bcmos_task_parm tp = {};
+ bcmos_msg_queue_parm qp = {};
+ bcmos_module_parm mp = {};
+ bcmos_msg msg1 = {};
+ bcmos_msg msg2 = {};
+
+ bcmos_task t1;
+ bcmos_task t2;
+ bcmos_msg_queue q1;
+ bcmos_errno rc;
+ epon_msg_olt_llid_rec link_rec1, link_rec2;
+ epon_msg_olt_port_rec port_msg1, port_msg2;
+
+ bcmos_init();
+ bcmos_trace_level_set(BCMOS_TRACE_LEVEL_DEBUG);
+
+ if (epon_db_instance_init() < 0)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_ERROR,
+ "Could not instantiate a Database\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Database set %p\n",
+ bcmdb_set_handle(db_sos_set, epon_olt_link_record));
+
+ /* Create message queue */
+ qp.name = "msg queue1";
+ qp.size = 16;
+ qp.high_wm = 14;
+ qp.low_wm = 12;
+ rc = bcmos_msg_queue_create(&q1, &qp);
+
+ /* Create a couple of threads */
+ tp.name = "task1";
+ tp.handler = task1_handler;
+ tp.data = (long)&q1;
+ rc = bcmos_task_create(&t1, &tp);
+
+ tp.name = "task2";
+ tp.handler = NULL;
+ tp.data = 0;
+ rc = bcmos_task_create(&t2, &tp);
+
+ /* Register a module */
+ mp.qparm.name = "module1";
+ mp.qparm.size = 16;
+ mp.init = mod1_init;
+ bcmos_module_create(BCMOS_MODULE_ID_TEST1, &t2, &mp);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to update the DB - enable a port*/
+ port_msg1.index=5;
+ port_msg1.port_rec.state=enabled;
+ msg1.type = update_port_db;
+ msg1.data = &port_msg1;
+ bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Send a message to update the DB - enable a port*/
+ port_msg2.index=3;
+ port_msg2.port_rec.state=enabled;
+ msg2.type = update_port_db;
+ msg2.data = &port_msg2;
+ bcmos_msg_send(&q1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to update the DB - put a link In Service*/
+ link_rec1.index=14;
+ link_rec1.llid_rec.state=inservice_llid;
+ msg1.type = update_link_db;
+ msg1.data = &link_rec1;
+ bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Send a message to update the DB - quarantine a link */
+ link_rec2.index=22;
+ link_rec2.llid_rec.state=quarantined_llid;
+ msg2.type = update_link_db;
+ msg2.data = &link_rec2;
+ msg2.handler = mod_msg_handler;
+ bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to dump the DB */
+ msg1.type = dump_db;
+ msg1.handler = mod_msg_handler;
+ msg1.data = NULL;
+ bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ return rc;
+}
diff --git a/bal_release/src/common/debug/ipc_ping/Makefile b/bal_release/src/common/debug/ipc_ping/Makefile
new file mode 100644
index 0000000..07c2b85
--- /dev/null
+++ b/bal_release/src/common/debug/ipc_ping/Makefile
@@ -0,0 +1,36 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# IPC ping debug utility
+#
+MOD_NAME = ipc_ping
+MOD_TYPE = lib
+MOD_DEPS = cli
+srcs = bal_ipc_ping.c
diff --git a/bal_release/src/common/dev_log b/bal_release/src/common/dev_log
new file mode 120000
index 0000000..0c2e71e
--- /dev/null
+++ b/bal_release/src/common/dev_log
@@ -0,0 +1 @@
+../../3rdparty/maple/sdk/host_reference/dev_log
\ No newline at end of file
diff --git a/bal_release/src/common/include/Makefile b/bal_release/src/common/include/Makefile
new file mode 100644
index 0000000..46650aa
--- /dev/null
+++ b/bal_release/src/common/include/Makefile
@@ -0,0 +1,38 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+###############################################################################
+# Common headers
+#
+MOD_NAME = common_include
+MOD_TYPE = lib
+MOD_DEPS =
+gen_bal_hdrs = bal_model_ids.h bal_model_types.h
+
diff --git a/bal_release/src/common/include/bal_buf.h b/bal_release/src/common/include/bal_buf.h
new file mode 100644
index 0000000..c5e06f7
--- /dev/null
+++ b/bal_release/src/common/include/bal_buf.h
@@ -0,0 +1,43 @@
+#ifndef BAL_BUF
+#define BAL_BUF
+
+#include "bcmolt_buf.h"
+
+typedef bcmolt_buf bcmbal_buf;
+
+#define bcmbal_buf_init(buf, size, start) bcmolt_buf_init(buf, size, start, BCMOLT_BUF_ENDIAN_FIXED)
+#define bcmbal_buf_alloc(buf, size) bcmolt_buf_alloc(buf, size, BCMOLT_BUF_ENDIAN_FIXED)
+#define bcmbal_buf_free bcmolt_buf_free
+#define bcmbal_buf_skip bcmolt_buf_skip
+#define bcmbal_buf_set_pos bcmolt_buf_set_pos
+#define bcmbal_buf_get_used bcmolt_buf_get_used
+#define bcmbal_buf_get_remaining_size bcmolt_buf_get_remaining_size
+#define bcmbal_buf_write bcmolt_buf_write
+#define bcmbal_buf_read bcmolt_buf_read
+#define bcmbal_buf_rewind bcmolt_buf_rewind
+#define bcmbal_buf_write_u8 bcmolt_buf_write_u8
+#define bcmbal_buf_read_u8 bcmolt_buf_read_u8
+#define bcmbal_buf_write_u16 bcmolt_buf_write_u16
+#define bcmbal_buf_read_u16 bcmolt_buf_read_u16
+#define bcmbal_buf_write_s16 bcmolt_buf_write_s16
+#define bcmbal_buf_read_s16 bcmolt_buf_read_s16
+#define bcmbal_buf_write_u24 bcmolt_buf_write_u24
+#define bcmbal_buf_read_u24 bcmolt_buf_read_u24
+#define bcmbal_buf_write_u32 bcmolt_buf_write_u32
+#define bcmbal_buf_read_u32 bcmolt_buf_read_u32
+#define bcmbal_buf_write_s32 bcmolt_buf_write_s32
+#define bcmbal_buf_read_s32 bcmolt_buf_read_s32
+#define bcmbal_buf_write_u64 bcmolt_buf_write_u64
+#define bcmbal_buf_read_u64 bcmolt_buf_read_u64
+#define bcmbal_buf_write_bool bcmolt_buf_write_bool
+#define bcmbal_buf_read_bool bcmolt_buf_read_bool
+#define bcmbal_buf_write_mac_address bcmolt_buf_write_mac_address
+#define bcmbal_buf_read_mac_address bcmolt_buf_read_mac_address
+#define bcmbal_buf_write_ipv4_address bcmolt_buf_write_ipv4_address
+#define bcmbal_buf_read_ipv4_address bcmolt_buf_read_ipv4_address
+#define bcmbal_buf_write_ipv6_address bcmolt_buf_write_ipv6_address
+#define bcmbal_buf_read_ipv6_address bcmolt_buf_read_ipv6_address
+#define bcmbal_buf_write_vlan_tag bcmolt_buf_write_vlan_tag
+#define bcmbal_buf_read_vlan_tag bcmolt_buf_read_vlan_tag
+
+#endif /* BAL_BUF */
diff --git a/bal_release/src/common/include/bal_common.h b/bal_release/src/common/include/bal_common.h
new file mode 100644
index 0000000..c5a2558
--- /dev/null
+++ b/bal_release/src/common/include/bal_common.h
@@ -0,0 +1,317 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_common.h
+ *
+ * @brief Common include files and miscellaneous macros for the BAL source code.
+ *
+ */
+
+#ifndef BALCOMMON_H
+#define BALCOMMON_H
+
+/*@{*/
+
+/* --- system includes ---*/
+#include <bcmos_system.h>
+
+/* --- project includes ---*/
+
+/**
+ * @brief OUI Identifier
+ *
+ */
+typedef uint8_t oui_val_t[3];
+
+/*
+ * A max/min function
+ */
+#define max(a,b) ((a > b) ? a : b)
+#define min(a,b) ((a > b) ? b : a)
+
+/**
+ * @brief Maximum value for a VLAN ID
+ */
+#define MAX_VLAN_ID 4094
+
+/**
+ * @brief Minimum value for an 802.1ah I-SID
+ *
+ * Notes from IEEE:
+ * 0 - Reserved for use by future amendments to the standard.
+ * 1 - Default value, unassigned ISID.
+ * 2..FF - Reserved for use by future amendments to the standard.
+ */
+#define MIN_8021AH_ISID 0x00000100
+
+/**
+ * @brief Maximum value for an 802.1ah I-SID
+ *
+ * Notes from IEEE:
+ * FFFFFF is reserved by IEEE
+ */
+#define MAX_8021AH_ISID 0x00FFFFFE
+
+/**
+ * @brief VLAN TPID definitions
+ */
+typedef enum vlan_tpid_type
+{
+ VLAN_TPID_TYPE_DEFAULT = 0x0000, /**< Simple Bridge - i.e. VID 0, no tagging */
+ VLAN_TPID_TYPE_8021Q = 0x8100, /**< C-VLAN */
+ VLAN_TPID_TYPE_8021AD = 0x88A8, /**< S-VLAN */
+ VLAN_TPID_TYPE_9100 = 0x9100, /**< Legacy TPID */
+ VLAN_TPID_TYPE_9200 = 0x9200, /**< Legacy TPID */
+ VLAN_TPID_TYPE_9300 = 0x9300, /**< Legacy TPID */
+ VLAN_TPID_TYPE_8021AH_ITAG = 0x88E7 /**< 802.1ah I-Tag TPID */
+} vlan_tpid_type;
+
+/**
+ * @brief VLAN type definitions
+ */
+typedef enum vlan_mode_type
+{
+ VLAN_MODE_NONE, /**< Neither Shared or L2VPN */
+ VLAN_MODE_SHARED, /**< IP-based shared vlan */
+ VLAN_MODE_8021AD_EN, /**< DPoE 802.1ad (or .1q) encapsulation mode */
+ VLAN_MODE_8021AD_TP, /**< DPoE 802.1ad (or .1q) transport mode */
+ VLAN_MODE_8021AH_EN, /**< DPoE 802.1ah encapsulation mode */
+ VLAN_MODE_8021AH_TP, /**< DPoE 802.1ah transport mode */
+ VLAN_MODE_DAC /**< DPoE DEMARC Auto Configuration */
+} vlan_mode;
+
+/**
+ * @brief Macro to test if a VLAN is 802.1ad
+ */
+#define VLAN_IS_8021AD(_vlan_) (((_vlan_)->type == VLAN_MODE_8021AD_EN) || ((_vlan_)->type == VLAN_MODE_8021AD_TP))
+
+/**
+ * @brief Macro to test if a VLAN is 802.1ah
+ */
+#define VLAN_IS_8021AH(_vlan_) (((_vlan_)->type == VLAN_MODE_8021AH_EN) || ((_vlan_)->type == VLAN_MODE_8021AH_TP))
+
+/**
+ * @brief Macro to test if a VLAN is L2VPN (as opposed to 'None' or "Shared')
+ */
+#define VLAN_IS_L2VPN(_vlan_) (VLAN_IS_8021AD(_vlan_) || VLAN_IS_8021AH(_vlan_))
+
+/**
+ * @brief Macro to test if a VLAN is DPoE IP-HSD
+ */
+#define VLAN_IS_DPOE_IPHSD(_vlan_) (((_vlan_)->type == VlanType_None) && ((_vlan_)->dpoeIp.svid != 0) && ((_vlan_)->dpoeIp.cvid != 0))
+
+/**
+ * @brief Macro to test if a VLAN is Legacy IP-HSD
+ */
+#define VLAN_IS_LEGACY_IPHSD(_vlan_) (((_vlan_)->type == VlanType_None) && ((_vlan_)->dpoeIp.svid == 0))
+
+/**
+ * @brief Macro to test if a VLAN is DPoE IP-HSD with PON-NNI style tagging
+ */
+#define VLAN_IS_DPOE_IPHSD_PON_NNI(_vlan_) (VLAN_IS_DPOE_IPHSD(_vlan_) && ((_vlan_)->dot1ad[VLAN_TAG_OUTER].nniTpid != 0))
+
+/**
+ * @brief Macro to test if a VLAN is Shared
+ */
+#define VLAN_IS_SHARED(_vlan_) ((_vlan_)->type == VLAN_MODE_SHARED)
+
+/**
+ * @brief 802.1ad VLAN Tag index
+ *
+ * This enum is used in the VlanT structure to address the outer vs. the inner
+ * 802.1ad tag.
+ */
+typedef enum vlan_tag_index
+{
+ VLAN_TAG_INDEX_OUTER = 0, /**< Outer tag, typically the S-VLAN tag */
+ VLAN_TAG_INDEX_INNER = 1, /**< Inner tag, typically the C-VLAN tag */
+ VLAN_TAG_INDEX_MAX = 2
+} vlan_tag_index;
+
+/**
+ * @brief VlanT structure
+ */
+typedef struct bcmbal_vlan
+{
+ vlan_mode type; /**< Type of VLAN */
+
+ /** Intra-Chassis Tagging */
+ struct
+ {
+ uint16_t tpid; /**< ICT TPID */
+ uint16_t vid; /**< ICT VLAN ID */
+ } ict;
+
+ /** DPoE IP HSD Tagging */
+ struct
+ {
+ uint16_t svid; /**< S-TAG VID */
+ uint16_t cvid; /**< C-TAG VID */
+ } dpoe_ip;
+
+ /** 802.1ad (and 802.1q) tagging */
+ struct
+ {
+ uint16_t nni_tpid; /**< VLAN Tag TPID used on the NNI */
+ uint16_t uni_tpid; /**< VLAN Tag TPID used on the UNI */
+ uint8_t cos; /**< CoS bits used in this VLAN Tag */
+ uint16_t vid; /**< VLAN ID */
+ } dot_1ad[VLAN_TAG_INDEX_MAX];
+
+ /** 802.1ah encapsulation info */
+ struct
+ {
+ /** 802.1ah B-MACs */
+ bcmos_mac_address bda; /**< 802.1ah Destination B-MAC */
+ bcmos_mac_address bsa; /**< 802.1ah Source B-MAC */
+
+ /** 802.1ah B-Tag */
+ struct
+ {
+ uint16_t nni_tpid; /**< B-Tag TPID used on the NNI */
+ uint16_t uni_tpid; /**< B-Tag TPID used on the UNI */
+ uint16_t vid; /**< B-Tag VLAN ID */
+ } btag;
+
+ /** 802.1ah I-Tag */
+ struct
+ {
+ uint16_t nni_tpid; /**< I-Tag TPID used on the NNI */
+ uint16_t uni_tpid; /**< I-Tag TPID used on the UNI */
+ uint32_t isid; /**< I-Tag Service ID */
+ } itag;
+ } dot_1ah;
+
+ /** L2VPN specific VLAN configuration */
+ uint32_t vpn_idx; /**< Index of L2VPN that link is associated with. */
+} bcmbal_vlan;
+
+/**
+ * @brief MAC Address key structure.
+ *
+ * This structure effectively adds a length field to the MacAddressT structure
+ * which helps when handling GetNext requests that don't contain a full MAC
+ * Address.
+ */
+typedef struct mac_address_key
+{
+ bcmos_mac_address mac_addr; /**< The MAC address */
+ uint16_t len; /**< The length of the MAC address in the field above */
+} mac_address_key;
+
+/**
+ * @brief MAC Address length
+ */
+#define MAC_ADDRESS_LEN 6
+
+/**
+ * @brief Converts a MacAddressT structure into a MacAddressKeyT structure.
+ */
+#define MAC_ADDR_TO_KEY(A, K, L) { \
+ (K)->mac_addr = *(A); \
+ (K)->len = (L); \
+ }
+
+/**
+ * @brief Compares the 802.1ad (or q) fields of two VlanT objects
+ *
+ * This macro returns '1' if all fields match, and '0' otherwise.
+ *
+ * Note, this macro looks at the nniTpid only. This macro is used to determine
+ * whether or not an OLT Domain already exists for a given VLAN (which prevents
+ * configuring duplicate/overlapping OLT domain selectors).
+ *
+ */
+#define VLANS_MATCH_AD(_vlan1_, _vlan2_) (((_vlan1_)->dot1ad[VLAN_TAG_OUTER].vid == (_vlan2_)->dot1ad[VLAN_TAG_OUTER].vid) && \
+ ((_vlan1_)->dot1ad[VLAN_TAG_OUTER].nniTpid == (_vlan2_)->dot1ad[VLAN_TAG_OUTER].nniTpid) && \
+ ((_vlan1_)->dot1ad[VLAN_TAG_INNER].vid == (_vlan2_)->dot1ad[VLAN_TAG_INNER].vid) && \
+ ((_vlan1_)->dot1ad[VLAN_TAG_INNER].nniTpid == (_vlan2_)->dot1ad[VLAN_TAG_INNER].nniTpid))
+
+/**
+ * @brief Compares the 802.1ah (mac-in-mac) fields of two VlanT objects
+ *
+ * This macro returns '1' if all fields match, and '0' otherwise.
+ *
+ * Note, this macro looks at the nniTpid's only. This macro is used to
+ * determine whether or not an OLT Domain already exists for a given VLAN
+ * (which prevents configuring duplicate/overlapping OLT domain selectors).
+ *
+ */
+#define VLANS_MATCH_AH(_vlan1_, _vlan2_) (((_vlan1_)->dot1ah.btag.nniTpid == (_vlan2_)->dot1ah.btag.nniTpid) && \
+ ((_vlan1_)->dot1ah.btag.vid == (_vlan2_)->dot1ah.btag.vid) && \
+ ((_vlan1_)->dot1ah.itag.nniTpid == (_vlan2_)->dot1ah.itag.nniTpid) && \
+ ((_vlan1_)->dot1ah.itag.isid == (_vlan2_)->dot1ah.itag.isid))
+
+/**
+ * @brief Compares the ICT fields of two VlanT objects
+ *
+ * This macro returns '1' if all fields match, and '0' otherwise.
+ *
+ * Note, this macro looks at the ICT fields only. This macro is
+ * used to determine whether or not an OLT Domain already
+ * exists for a given VLAN (which prevents configuring
+ * duplicate/overlapping OLT domain selectors).
+ *
+ */
+#define VLANS_MATCH_ICT(_vlan1_, _vlan2_) (((_vlan1_)->ict.tpid == (_vlan2_)->ict.tpid) && \
+ ((_vlan1_)->ict.vid == (_vlan2_)->ict.vid))
+/**
+ * @brief Compares the 802.1ad (or q) and 802.1ah (mac-in-mac)
+ * fields of two VlanT objects
+ *
+ * This macro returns '1' if all fields match, and '0' otherwise.
+ *
+ */
+#define VLANS_MATCH(_vlan1_, _vlan2_) (VLANS_MATCH_AD(_vlan1_, _vlan2_) && VLANS_MATCH_AH(_vlan1_, _vlan2_))
+
+/**
+ * @brief Macros for setting/clearing bits inside of an integer
+ */
+#define SET_BIT(x,n) ((x) |= (1L << (n)))
+#define CLR_BIT(x,n) ((x) &= (~(1L << (n))))
+#define BIT_IS_SET(x,n) (((x) >> (n)) & 1)
+
+
+
+/**
+ * Static compile time assert used to ensure that enums and associated
+ * character arrays are equal.
+ *
+ * Use the BAL_STATIC_ASSERT function in your code to check array sizes
+ */
+#define _BAL_STATIC_ASSERT_HELPER(expr, msg) (sizeof (struct {unsigned int STATIC_ASSERT__##msg: (expr) ? 1 : -1;} ))
+
+#define BAL_STATIC_ASSERT(expr, msg) extern int (*assert_function__##msg(void)) [_BAL_STATIC_ASSERT_HELPER(expr, msg) ]
+
+/*@}*/
+
+#endif /* #ifndef BALCOMMON_H */
diff --git a/bal_release/src/common/include/bal_ids.h b/bal_release/src/common/include/bal_ids.h
new file mode 100644
index 0000000..e4239e6
--- /dev/null
+++ b/bal_release/src/common/include/bal_ids.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_ids.h
+ * @brief BAL IDs used in the system
+ *
+ * This file contains all of the BAL IDs used in the system
+ *
+ */
+#ifndef BALIDS_H
+#define BALIDS_H
+
+/*@{*/
+
+/*@}*/
+
+#endif /* #ifndef BALIDS_H */
diff --git a/bal_release/src/common/include/bal_model_ids.h b/bal_release/src/common/include/bal_model_ids.h
new file mode 100644
index 0000000..218b74e
--- /dev/null
+++ b/bal_release/src/common/include/bal_model_ids.h
@@ -0,0 +1,714 @@
+#ifndef BAL_MODEL_IDS_H_
+#define BAL_MODEL_IDS_H_
+
+/** \ingroup object_model_data_types
+ * \defgroup object_model_enums BAL Object Model Enumerations
+ */
+
+/** \addtogroup object_model_enums
+ * @{
+ */
+#include <bcmos_system.h>
+
+/** Identifiers for all properties contained in the access_terminal_cfg group.
+ */
+typedef enum bcmbal_access_terminal_cfg_id
+{
+ BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE = 2, /**< Interworking function mode. */
+ BCMBAL_ACCESS_TERMINAL_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_access_terminal_cfg_id;
+
+/** Identifiers for all properties contained in the access_terminal_ind group.
+ */
+typedef enum bcmbal_access_terminal_ind_id
+{
+ BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE = 2, /**< Interworking function mode. */
+ BCMBAL_ACCESS_TERMINAL_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_access_terminal_ind_id;
+
+/** Identifiers for all properties contained in the access_terminal_key group.
+ */
+typedef enum bcmbal_access_terminal_key_id
+{
+ BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID= 0, /**< access_term_id. */
+ BCMBAL_ACCESS_TERMINAL_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_access_terminal_key_id;
+
+/** Identifiers for all properties contained in the flow_cfg group.
+ */
+typedef enum bcmbal_flow_cfg_id
+{
+ BCMBAL_FLOW_CFG_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_FLOW_CFG_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID = 2, /**< Access Interface ID. */
+ BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID = 3, /**< Network Interface ID. */
+ BCMBAL_FLOW_CFG_ID_SUB_TERM_ID = 4, /**< Subscriber Terminal ID. */
+ BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX = 5, /**< Subscriber Terminal uni port index. */
+ BCMBAL_FLOW_CFG_ID_SVC_PORT_ID = 6, /**< Service Port ID. */
+ BCMBAL_FLOW_CFG_ID_AGG_PORT_ID = 7, /**< Aggregate port ID. */
+ BCMBAL_FLOW_CFG_ID_RESOLVE_MAC = 8, /**< Resolve mac. */
+ BCMBAL_FLOW_CFG_ID_CLASSIFIER = 9, /**< Classifier. */
+ BCMBAL_FLOW_CFG_ID_ACTION = 10, /**< Action. */
+ BCMBAL_FLOW_CFG_ID_SLA = 11, /**< SLA. */
+ BCMBAL_FLOW_CFG_ID_COOKIE = 12, /**< Cookie. */
+ BCMBAL_FLOW_CFG_ID_PRIORITY = 13, /**< Priority. */
+ BCMBAL_FLOW_CFG_ID_GROUP_ID = 14, /**< Group ID. */
+ BCMBAL_FLOW_CFG_ID_QUEUE = 15, /**< Egress queue. */
+ BCMBAL_FLOW_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_flow_cfg_id;
+
+/** Identifiers for all properties contained in the flow_ind group.
+ */
+typedef enum bcmbal_flow_ind_id
+{
+ BCMBAL_FLOW_IND_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_FLOW_IND_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_FLOW_IND_ID_ACCESS_INT_ID = 2, /**< Access interface ID. */
+ BCMBAL_FLOW_IND_ID_NETWORK_INT_ID = 3, /**< Network Interface ID. */
+ BCMBAL_FLOW_IND_ID_SUB_TERM_ID = 4, /**< Subscriber terminal ID. */
+ BCMBAL_FLOW_IND_ID_SVC_PORT_ID = 5, /**< Service port ID. */
+ BCMBAL_FLOW_IND_ID_AGG_PORT_ID = 6, /**< Aggregate port ID. */
+ BCMBAL_FLOW_IND_ID_RESOLVE_MAC = 7, /**< Resolve mac. */
+ BCMBAL_FLOW_IND_ID_BASE_TC_ID = 8, /**< Base TCONT ID. */
+ BCMBAL_FLOW_IND_ID_CLASSIFIER = 9, /**< Classifier. */
+ BCMBAL_FLOW_IND_ID_ACTION = 10, /**< Action. */
+ BCMBAL_FLOW_IND_ID_SLA = 11, /**< SLA. */
+ BCMBAL_FLOW_IND_ID_COOKIE = 12, /**< Cookie. */
+ BCMBAL_FLOW_IND_ID_PRIORITY = 13, /**< Priority. */
+ BCMBAL_FLOW_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_flow_ind_id;
+
+/** Identifiers for all properties contained in the flow_key group.
+ */
+typedef enum bcmbal_flow_key_id
+{
+ BCMBAL_FLOW_KEY_ID_FLOW_ID = 0, /**< Flow ID. */
+ BCMBAL_FLOW_KEY_ID_FLOW_TYPE = 1, /**< Flow type. */
+ BCMBAL_FLOW_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_flow_key_id;
+
+/** Identifiers for all properties contained in the flow_stat group.
+ */
+typedef enum bcmbal_flow_stat_id
+{
+ BCMBAL_FLOW_STAT_ID_RX_PACKETS = 0, /**< Received packets. */
+ BCMBAL_FLOW_STAT_ID_RX_BYTES = 1, /**< Received bytes. */
+ BCMBAL_FLOW_STAT_ID_TX_PACKETS = 2, /**< Transmitted packets. */
+ BCMBAL_FLOW_STAT_ID_TX_BYTES = 3, /**< Transmitted bytes. */
+ BCMBAL_FLOW_STAT_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_flow_stat_id;
+
+/** Identifiers for all properties contained in the group_cfg group.
+ */
+typedef enum bcmbal_group_cfg_id
+{
+ BCMBAL_GROUP_CFG_ID_MEMBERS_CMD = 0, /**< Membership operation commands. */
+ BCMBAL_GROUP_CFG_ID_MEMBERS = 1, /**< Member. */
+ BCMBAL_GROUP_CFG_ID_COOKIE = 2, /**< Application cookie. */
+ BCMBAL_GROUP_CFG_ID_FLOWS = 3, /**< List of flows associated with the group . */
+ BCMBAL_GROUP_CFG_ID_OWNER = 4, /**< Owner of the group. */
+ BCMBAL_GROUP_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_group_cfg_id;
+
+/** Identifiers for all properties contained in the group_key group.
+ */
+typedef enum bcmbal_group_key_id
+{
+ BCMBAL_GROUP_KEY_ID_GROUP_ID = 0, /**< Group ID. */
+ BCMBAL_GROUP_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_group_key_id;
+
+/** Identifiers for all properties contained in the interface_cfg group.
+ */
+typedef enum bcmbal_interface_cfg_id
+{
+ BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_INTERFACE_CFG_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID= 2, /**< Minimum aggregate port ID. */
+ BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID= 3, /**< Minimum service port ID. */
+ BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE = 4, /**< Transceiver type. */
+ BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE = 5, /**< Downstream unknown packet action. */
+ BCMBAL_INTERFACE_CFG_ID_MTU = 6, /**< MTU. */
+ BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL = 7, /**< Flow control. */
+ BCMBAL_INTERFACE_CFG_ID_DS_TM = 8, /**< Downstream scheduler and shaper. */
+ BCMBAL_INTERFACE_CFG_ID_US_TM = 9, /**< Upstream scheduler and shaper. */
+ BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST = 10, /**< Sub-term id list. */
+ BCMBAL_INTERFACE_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_interface_cfg_id;
+
+/** Identifiers for all properties contained in the interface_ind group.
+ */
+typedef enum bcmbal_interface_ind_id
+{
+ BCMBAL_INTERFACE_IND_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_INTERFACE_IND_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID= 2, /**< Minimum aggregate port ID. */
+ BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID= 3, /**< Minimum service port ID. */
+ BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE = 4, /**< Transceiver type. */
+ BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE = 5, /**< Downstream unknown packet action. */
+ BCMBAL_INTERFACE_IND_ID_MTU = 6, /**< MTU. */
+ BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL = 7, /**< Flow control. */
+ BCMBAL_INTERFACE_IND_ID_DS_TM = 8, /**< Downstream scheduler and shaper. */
+ BCMBAL_INTERFACE_IND_ID_US_TM = 9, /**< Upstream scheduler and shaper. */
+ BCMBAL_INTERFACE_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_interface_ind_id;
+
+/** Identifiers for all properties contained in the interface_key group.
+ */
+typedef enum bcmbal_interface_key_id
+{
+ BCMBAL_INTERFACE_KEY_ID_INTF_ID = 0, /**< intf_id. */
+ BCMBAL_INTERFACE_KEY_ID_INTF_TYPE = 1, /**< intf_type. */
+ BCMBAL_INTERFACE_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_interface_key_id;
+
+/** Identifiers for all properties contained in the interface_stat group.
+ */
+typedef enum bcmbal_interface_stat_id
+{
+ BCMBAL_INTERFACE_STAT_ID_RX_PACKETS = 0, /**< Recieved packets. */
+ BCMBAL_INTERFACE_STAT_ID_RX_BYTES = 1, /**< Received bytes. */
+ BCMBAL_INTERFACE_STAT_ID_TX_PACKETS = 2, /**< Transmitted packets. */
+ BCMBAL_INTERFACE_STAT_ID_TX_BYTES = 3, /**< Transmitted bytes. */
+ BCMBAL_INTERFACE_STAT_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_interface_stat_id;
+
+/** Identifiers for all properties contained in the packet_cfg group.
+ */
+typedef enum bcmbal_packet_cfg_id
+{
+ BCMBAL_PACKET_CFG_ID_FLOW_ID = 0, /**< Flow Id. */
+ BCMBAL_PACKET_CFG_ID_FLOW_TYPE = 1, /**< Flow Type. */
+ BCMBAL_PACKET_CFG_ID_INTF_ID = 2, /**< Interface ID. */
+ BCMBAL_PACKET_CFG_ID_INTF_TYPE = 3, /**< Interface Type. */
+ BCMBAL_PACKET_CFG_ID_SVC_PORT = 4, /**< Service Port. */
+ BCMBAL_PACKET_CFG_ID_FLOW_COOKIE = 5, /**< Flow Cookie. */
+ BCMBAL_PACKET_CFG_ID_PKT = 6, /**< Packet Data. */
+ BCMBAL_PACKET_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_packet_cfg_id;
+
+/** Identifiers for all properties contained in the packet_ind group.
+ */
+typedef enum bcmbal_packet_ind_id
+{
+ BCMBAL_PACKET_IND_ID_FLOW_ID = 0, /**< Flow Id. */
+ BCMBAL_PACKET_IND_ID_FLOW_TYPE = 1, /**< Flow Type. */
+ BCMBAL_PACKET_IND_ID_INTF_ID = 2, /**< Interface ID. */
+ BCMBAL_PACKET_IND_ID_INTF_TYPE = 3, /**< Interface Type. */
+ BCMBAL_PACKET_IND_ID_SVC_PORT = 4, /**< Service Port. */
+ BCMBAL_PACKET_IND_ID_FLOW_COOKIE = 5, /**< Flow Cookie. */
+ BCMBAL_PACKET_IND_ID_PKT = 6, /**< Packet Data. */
+ BCMBAL_PACKET_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_packet_ind_id;
+
+/** Identifiers for all properties contained in the packet_key group.
+ */
+typedef enum bcmbal_packet_key_id
+{
+ BCMBAL_PACKET_KEY_ID_RESERVED = 0, /**< Reserved key field. */
+ BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST = 1, /**< Packet destination. */
+ BCMBAL_PACKET_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_packet_key_id;
+
+/** Identifiers for all properties contained in the subscriber_terminal_cfg
+ * group.
+ */
+typedef enum bcmbal_subscriber_terminal_cfg_id
+{
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER = 2, /**< Serial number. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD = 3, /**< Password. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID = 4, /**< Registration id. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID = 5, /**< Service port ID. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS = 6, /**< MAC address. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM = 7, /**< Downstream scheduler and shaper. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM = 8, /**< Upstream scheduler and shaper. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST = 9, /**< svc_port_id list. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST = 10, /**< agg_port_id list. */
+ BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_subscriber_terminal_cfg_id;
+
+/** Identifiers for all properties contained in the subscriber_terminal_ind
+ * group.
+ */
+typedef enum bcmbal_subscriber_terminal_ind_id
+{
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE = 0, /**< Administrative state. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS = 1, /**< Operational status. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER = 2, /**< Serial number. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD = 3, /**< Password. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID = 4, /**< Registration id. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID = 5, /**< Service port ID. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS = 6, /**< MAC address. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM = 7, /**< Downstream scheduler and shaper. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM = 8, /**< Upstream scheduler and shaper. */
+ BCMBAL_SUBSCRIBER_TERMINAL_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_subscriber_terminal_ind_id;
+
+/** Identifiers for all properties contained in the subscriber_terminal_key
+ * group.
+ */
+typedef enum bcmbal_subscriber_terminal_key_id
+{
+ BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID = 0, /**< sub_term_id. */
+ BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID = 1, /**< intf_id. */
+ BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_subscriber_terminal_key_id;
+
+/** Identifiers for all properties contained in the subscriber_terminal_stat
+ * group.
+ */
+typedef enum bcmbal_subscriber_terminal_stat_id
+{
+ BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS = 0, /**< Received packets. */
+ BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES = 1, /**< Received bytes. */
+ BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS = 2, /**< Transmitted packets. */
+ BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES = 3, /**< Transmitted bytes. */
+ BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_subscriber_terminal_stat_id;
+
+/** Identifiers for all properties contained in the tm_queue_cfg group.
+ */
+typedef enum bcmbal_tm_queue_cfg_id
+{
+ BCMBAL_TM_QUEUE_CFG_ID_PRIORITY = 0, /**< priority. */
+ BCMBAL_TM_QUEUE_CFG_ID_WEIGHT = 1, /**< weight. */
+ BCMBAL_TM_QUEUE_CFG_ID_RATE = 2, /**< rate. */
+ BCMBAL_TM_QUEUE_CFG_ID_BAC = 3, /**< bac. */
+ BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE = 4, /**< creation_mode. */
+ BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT = 5, /**< ref_count. */
+ BCMBAL_TM_QUEUE_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_queue_cfg_id;
+
+/** Identifiers for all properties contained in the tm_queue_ind group.
+ */
+typedef enum bcmbal_tm_queue_ind_id
+{
+ BCMBAL_TM_QUEUE_IND_ID_RET = 0, /**< ret. */
+ BCMBAL_TM_QUEUE_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_queue_ind_id;
+
+/** Identifiers for all properties contained in the tm_queue_key group.
+ */
+typedef enum bcmbal_tm_queue_key_id
+{
+ BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID = 0, /**< sched_id. */
+ BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR = 1, /**< sched dir. */
+ BCMBAL_TM_QUEUE_KEY_ID_ID = 2, /**< id. */
+ BCMBAL_TM_QUEUE_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_queue_key_id;
+
+/** Identifiers for all properties contained in the tm_queue_stat group.
+ */
+typedef enum bcmbal_tm_queue_stat_id
+{
+ BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK = 0, /**< packets_ok. */
+ BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK = 1, /**< bytes_ok. */
+ BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED = 2, /**< packets_discarded. */
+ BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED = 3, /**< bytes_discarded. */
+ BCMBAL_TM_QUEUE_STAT_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_queue_stat_id;
+
+/** Identifiers for all properties contained in the tm_sched_cfg group.
+ */
+typedef enum bcmbal_tm_sched_cfg_id
+{
+ BCMBAL_TM_SCHED_CFG_ID_OWNER = 0, /**< owner. */
+ BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE = 1, /**< type. */
+ BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT = 2, /**< parent. */
+ BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE = 3, /**< child_type. */
+ BCMBAL_TM_SCHED_CFG_ID_RATE = 4, /**< rate. */
+ BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA = 5, /**< tcont_sla. */
+ BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE = 6, /**< creation_mode. */
+ BCMBAL_TM_SCHED_CFG_ID_QUEUES = 7, /**< queues. */
+ BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS = 8, /**< sub_scheds. */
+ BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES = 9, /**< num_priorities. */
+ BCMBAL_TM_SCHED_CFG_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_cfg_id;
+
+/** Identifiers for all properties contained in the tm_sched_ind group.
+ */
+typedef enum bcmbal_tm_sched_ind_id
+{
+ BCMBAL_TM_SCHED_IND_ID_RET = 0, /**< ret. */
+ BCMBAL_TM_SCHED_IND_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_ind_id;
+
+/** Identifiers for all properties contained in the tm_sched_key group.
+ */
+typedef enum bcmbal_tm_sched_key_id
+{
+ BCMBAL_TM_SCHED_KEY_ID_DIR = 0, /**< dir. */
+ BCMBAL_TM_SCHED_KEY_ID_ID = 1, /**< id. */
+ BCMBAL_TM_SCHED_KEY_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_key_id;
+
+/** All object tags for all objects in the system.
+ */
+typedef enum bcmbal_obj_tag
+{
+ BCMBAL_OBJ_TAG__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_obj_tag;
+
+/** Identifiers for all objects in the system.
+ */
+typedef enum bcmbal_obj_id
+{
+ BCMBAL_OBJ_ID__BEGIN,
+ BCMBAL_OBJ_ID_ACCESS_TERMINAL = 0, /**< BAL Access Terminal */
+ BCMBAL_OBJ_ID_FLOW = 1, /**< BAL Flow */
+ BCMBAL_OBJ_ID_GROUP = 2, /**< BAL Group */
+ BCMBAL_OBJ_ID_INTERFACE = 3, /**< BAL Interface */
+ BCMBAL_OBJ_ID_PACKET = 4, /**< packet */
+ BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL = 5, /**< BAL Subscriber Terminal */
+ BCMBAL_OBJ_ID_TM_QUEUE = 6, /**< tm_queue */
+ BCMBAL_OBJ_ID_TM_SCHED = 7, /**< tm_sched */
+ BCMBAL_OBJ_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_obj_id;
+
+/** Identifiers for all possible groups under all objects in the system.
+ */
+typedef enum bcmbal_obj_group_id
+{
+ BCMBAL_OBJ_GROUP_ID__BEGIN,
+ BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_KEY = 0, /**< BAL Access Terminal - key */
+ BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_CFG = 1, /**< BAL Access Terminal - cfg */
+ BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_IND = 2, /**< BAL Access Terminal - Access Terminal Indication */
+ BCMBAL_OBJ_GROUP_ID_FLOW_KEY = 3, /**< BAL Flow - key */
+ BCMBAL_OBJ_GROUP_ID_FLOW_CFG = 4, /**< BAL Flow - cfg */
+ BCMBAL_OBJ_GROUP_ID_FLOW_STAT = 5, /**< BAL Flow - stat */
+ BCMBAL_OBJ_GROUP_ID_FLOW_IND = 6, /**< BAL Flow - Flow Indication */
+ BCMBAL_OBJ_GROUP_ID_GROUP_KEY = 7, /**< BAL Group - key */
+ BCMBAL_OBJ_GROUP_ID_GROUP_CFG = 8, /**< BAL Group - cfg */
+ BCMBAL_OBJ_GROUP_ID_INTERFACE_KEY = 9, /**< BAL Interface - key */
+ BCMBAL_OBJ_GROUP_ID_INTERFACE_CFG = 10, /**< BAL Interface - cfg */
+ BCMBAL_OBJ_GROUP_ID_INTERFACE_STAT = 11, /**< BAL Interface - stat */
+ BCMBAL_OBJ_GROUP_ID_INTERFACE_IND = 12, /**< BAL Interface - Interface Indication */
+ BCMBAL_OBJ_GROUP_ID_PACKET_KEY = 13, /**< packet - key */
+ BCMBAL_OBJ_GROUP_ID_PACKET_CFG = 14, /**< packet - cfg */
+ BCMBAL_OBJ_GROUP_ID_PACKET_IND = 15, /**< packet - Packet indication */
+ BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_KEY = 16, /**< BAL Subscriber Terminal - key */
+ BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_CFG = 17, /**< BAL Subscriber Terminal - cfg */
+ BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_STAT = 18, /**< BAL Subscriber Terminal - stat */
+ BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_IND = 19, /**< BAL Subscriber Terminal - Subscriber Terminal Indication */
+ BCMBAL_OBJ_GROUP_ID_TM_QUEUE_KEY = 20, /**< tm_queue - key */
+ BCMBAL_OBJ_GROUP_ID_TM_QUEUE_CFG = 21, /**< tm_queue - cfg */
+ BCMBAL_OBJ_GROUP_ID_TM_QUEUE_STAT = 22, /**< tm_queue - stat */
+ BCMBAL_OBJ_GROUP_ID_TM_QUEUE_IND = 23, /**< tm_queue - Tm Queue Indication */
+ BCMBAL_OBJ_GROUP_ID_TM_SCHED_KEY = 24, /**< tm_sched - key */
+ BCMBAL_OBJ_GROUP_ID_TM_SCHED_CFG = 25, /**< tm_sched - cfg */
+ BCMBAL_OBJ_GROUP_ID_TM_SCHED_IND = 26, /**< tm_sched - Tm Sched Indication */
+ BCMBAL_OBJ_GROUP_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_obj_group_id;
+
+/** List of all access_terminal groups of type auto.
+ */
+typedef enum bcmbal_access_terminal_auto_id
+{
+ BCMBAL_ACCESS_TERMINAL_AUTO_ID__BEGIN,
+ BCMBAL_ACCESS_TERMINAL_AUTO_ID_IND = 0, /**< Access Terminal Indication. */
+ BCMBAL_ACCESS_TERMINAL_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_access_terminal_auto_id;
+
+/** List of all flow groups of type auto.
+ */
+typedef enum bcmbal_flow_auto_id
+{
+ BCMBAL_FLOW_AUTO_ID__BEGIN,
+ BCMBAL_FLOW_AUTO_ID_IND = 0, /**< Flow Indication. */
+ BCMBAL_FLOW_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_flow_auto_id;
+
+/** List of all interface groups of type auto.
+ */
+typedef enum bcmbal_interface_auto_id
+{
+ BCMBAL_INTERFACE_AUTO_ID__BEGIN,
+ BCMBAL_INTERFACE_AUTO_ID_IND = 0, /**< Interface Indication. */
+ BCMBAL_INTERFACE_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_interface_auto_id;
+
+/** List of all packet groups of type auto.
+ */
+typedef enum bcmbal_packet_auto_id
+{
+ BCMBAL_PACKET_AUTO_ID__BEGIN,
+ BCMBAL_PACKET_AUTO_ID_IND = 0, /**< Packet indication. */
+ BCMBAL_PACKET_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_packet_auto_id;
+
+/** List of all subscriber_terminal groups of type auto.
+ */
+typedef enum bcmbal_subscriber_terminal_auto_id
+{
+ BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID__BEGIN,
+ BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND = 0, /**< Subscriber Terminal Indication. */
+ BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_subscriber_terminal_auto_id;
+
+/** List of all tm_queue groups of type auto.
+ */
+typedef enum bcmbal_tm_queue_auto_id
+{
+ BCMBAL_TM_QUEUE_AUTO_ID__BEGIN,
+ BCMBAL_TM_QUEUE_AUTO_ID_IND = 0, /**< Tm Queue Indication. */
+ BCMBAL_TM_QUEUE_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_queue_auto_id;
+
+/** List of all tm_sched groups of type auto.
+ */
+typedef enum bcmbal_tm_sched_auto_id
+{
+ BCMBAL_TM_SCHED_AUTO_ID__BEGIN,
+ BCMBAL_TM_SCHED_AUTO_ID_IND = 0, /**< Tm Sched Indication. */
+ BCMBAL_TM_SCHED_AUTO_ID__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_auto_id;
+
+#define bcmbal_access_terminal_key_id_all_properties BCMBAL_ACCESS_TERMINAL_KEY_ID__NUM_OF
+#define bcmbal_access_terminal_cfg_id_all_properties BCMBAL_ACCESS_TERMINAL_CFG_ID__NUM_OF
+#define bcmbal_access_terminal_ind_id_all_properties BCMBAL_ACCESS_TERMINAL_IND_ID__NUM_OF
+#define bcmbal_flow_cfg_id_all_properties BCMBAL_FLOW_CFG_ID__NUM_OF
+#define bcmbal_flow_key_id_all_properties BCMBAL_FLOW_KEY_ID__NUM_OF
+#define bcmbal_flow_stat_id_all_properties BCMBAL_FLOW_STAT_ID__NUM_OF
+#define bcmbal_flow_ind_id_all_properties BCMBAL_FLOW_IND_ID__NUM_OF
+#define bcmbal_group_cfg_id_all_properties BCMBAL_GROUP_CFG_ID__NUM_OF
+#define bcmbal_group_key_id_all_properties BCMBAL_GROUP_KEY_ID__NUM_OF
+#define bcmbal_interface_key_id_all_properties BCMBAL_INTERFACE_KEY_ID__NUM_OF
+#define bcmbal_interface_cfg_id_all_properties BCMBAL_INTERFACE_CFG_ID__NUM_OF
+#define bcmbal_interface_stat_id_all_properties BCMBAL_INTERFACE_STAT_ID__NUM_OF
+#define bcmbal_interface_ind_id_all_properties BCMBAL_INTERFACE_IND_ID__NUM_OF
+#define bcmbal_packet_cfg_id_all_properties BCMBAL_PACKET_CFG_ID__NUM_OF
+#define bcmbal_packet_key_id_all_properties BCMBAL_PACKET_KEY_ID__NUM_OF
+#define bcmbal_packet_ind_id_all_properties BCMBAL_PACKET_IND_ID__NUM_OF
+#define bcmbal_subscriber_terminal_key_id_all_properties BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID__NUM_OF
+#define bcmbal_subscriber_terminal_cfg_id_all_properties BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID__NUM_OF
+#define bcmbal_subscriber_terminal_stat_id_all_properties BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID__NUM_OF
+#define bcmbal_subscriber_terminal_ind_id_all_properties BCMBAL_SUBSCRIBER_TERMINAL_IND_ID__NUM_OF
+#define bcmbal_tm_queue_key_id_all_properties BCMBAL_TM_QUEUE_KEY_ID__NUM_OF
+#define bcmbal_tm_queue_cfg_id_all_properties BCMBAL_TM_QUEUE_CFG_ID__NUM_OF
+#define bcmbal_tm_queue_stat_id_all_properties BCMBAL_TM_QUEUE_STAT_ID__NUM_OF
+#define bcmbal_tm_queue_ind_id_all_properties BCMBAL_TM_QUEUE_IND_ID__NUM_OF
+#define bcmbal_tm_sched_key_id_all_properties BCMBAL_TM_SCHED_KEY_ID__NUM_OF
+#define bcmbal_tm_sched_cfg_id_all_properties BCMBAL_TM_SCHED_CFG_ID__NUM_OF
+#define bcmbal_tm_sched_ind_id_all_properties BCMBAL_TM_SCHED_IND_ID__NUM_OF
+
+/* The following are required for the API Init/Set/etc macros */
+#define bcmbal_obj_id__begin BCMBAL_OBJ_ID__BEGIN
+#define bcmbal_obj_id_access_terminal BCMBAL_OBJ_ID_ACCESS_TERMINAL
+#define bcmbal_obj_id_flow BCMBAL_OBJ_ID_FLOW
+#define bcmbal_obj_id_group BCMBAL_OBJ_ID_GROUP
+#define bcmbal_obj_id_interface BCMBAL_OBJ_ID_INTERFACE
+#define bcmbal_obj_id_packet BCMBAL_OBJ_ID_PACKET
+#define bcmbal_obj_id_subscriber_terminal BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL
+#define bcmbal_obj_id_tm_queue BCMBAL_OBJ_ID_TM_QUEUE
+#define bcmbal_obj_id_tm_sched BCMBAL_OBJ_ID_TM_SCHED
+#define bcmbal_obj_id__num_of BCMBAL_OBJ_ID__NUM_OF
+#define bcmbal_access_terminal_auto_id__begin BCMBAL_ACCESS_TERMINAL_AUTO_ID__BEGIN
+#define bcmbal_access_terminal_auto_id_ind BCMBAL_ACCESS_TERMINAL_AUTO_ID_IND
+#define bcmbal_access_terminal_auto_id__num_of BCMBAL_ACCESS_TERMINAL_AUTO_ID__NUM_OF
+#define bcmbal_flow_auto_id__begin BCMBAL_FLOW_AUTO_ID__BEGIN
+#define bcmbal_flow_auto_id_ind BCMBAL_FLOW_AUTO_ID_IND
+#define bcmbal_flow_auto_id__num_of BCMBAL_FLOW_AUTO_ID__NUM_OF
+#define bcmbal_interface_auto_id__begin BCMBAL_INTERFACE_AUTO_ID__BEGIN
+#define bcmbal_interface_auto_id_ind BCMBAL_INTERFACE_AUTO_ID_IND
+#define bcmbal_interface_auto_id__num_of BCMBAL_INTERFACE_AUTO_ID__NUM_OF
+#define bcmbal_packet_auto_id__begin BCMBAL_PACKET_AUTO_ID__BEGIN
+#define bcmbal_packet_auto_id_ind BCMBAL_PACKET_AUTO_ID_IND
+#define bcmbal_packet_auto_id__num_of BCMBAL_PACKET_AUTO_ID__NUM_OF
+#define bcmbal_subscriber_terminal_auto_id__begin BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID__BEGIN
+#define bcmbal_subscriber_terminal_auto_id_ind BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND
+#define bcmbal_subscriber_terminal_auto_id__num_of BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID__NUM_OF
+#define bcmbal_tm_queue_auto_id__begin BCMBAL_TM_QUEUE_AUTO_ID__BEGIN
+#define bcmbal_tm_queue_auto_id_ind BCMBAL_TM_QUEUE_AUTO_ID_IND
+#define bcmbal_tm_queue_auto_id__num_of BCMBAL_TM_QUEUE_AUTO_ID__NUM_OF
+#define bcmbal_tm_sched_auto_id__begin BCMBAL_TM_SCHED_AUTO_ID__BEGIN
+#define bcmbal_tm_sched_auto_id_ind BCMBAL_TM_SCHED_AUTO_ID_IND
+#define bcmbal_tm_sched_auto_id__num_of BCMBAL_TM_SCHED_AUTO_ID__NUM_OF
+#define bcmbal_access_terminal_key_id_access_term_id BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID
+#define bcmbal_access_terminal_key_id__num_of BCMBAL_ACCESS_TERMINAL_KEY_ID__NUM_OF
+#define bcmbal_access_terminal_cfg_id_admin_state BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE
+#define bcmbal_access_terminal_cfg_id_oper_status BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS
+#define bcmbal_access_terminal_cfg_id_iwf_mode BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE
+#define bcmbal_access_terminal_cfg_id__num_of BCMBAL_ACCESS_TERMINAL_CFG_ID__NUM_OF
+#define bcmbal_access_terminal_ind_id_admin_state BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE
+#define bcmbal_access_terminal_ind_id_oper_status BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS
+#define bcmbal_access_terminal_ind_id_iwf_mode BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE
+#define bcmbal_access_terminal_ind_id__num_of BCMBAL_ACCESS_TERMINAL_IND_ID__NUM_OF
+#define bcmbal_flow_key_id_flow_id BCMBAL_FLOW_KEY_ID_FLOW_ID
+#define bcmbal_flow_key_id_flow_type BCMBAL_FLOW_KEY_ID_FLOW_TYPE
+#define bcmbal_flow_key_id__num_of BCMBAL_FLOW_KEY_ID__NUM_OF
+#define bcmbal_flow_cfg_id_admin_state BCMBAL_FLOW_CFG_ID_ADMIN_STATE
+#define bcmbal_flow_cfg_id_oper_status BCMBAL_FLOW_CFG_ID_OPER_STATUS
+#define bcmbal_flow_cfg_id_access_int_id BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID
+#define bcmbal_flow_cfg_id_network_int_id BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID
+#define bcmbal_flow_cfg_id_sub_term_id BCMBAL_FLOW_CFG_ID_SUB_TERM_ID
+#define bcmbal_flow_cfg_id_sub_term_uni_idx BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX
+#define bcmbal_flow_cfg_id_svc_port_id BCMBAL_FLOW_CFG_ID_SVC_PORT_ID
+#define bcmbal_flow_cfg_id_agg_port_id BCMBAL_FLOW_CFG_ID_AGG_PORT_ID
+#define bcmbal_flow_cfg_id_resolve_mac BCMBAL_FLOW_CFG_ID_RESOLVE_MAC
+#define bcmbal_flow_cfg_id_classifier BCMBAL_FLOW_CFG_ID_CLASSIFIER
+#define bcmbal_flow_cfg_id_action BCMBAL_FLOW_CFG_ID_ACTION
+#define bcmbal_flow_cfg_id_sla BCMBAL_FLOW_CFG_ID_SLA
+#define bcmbal_flow_cfg_id_cookie BCMBAL_FLOW_CFG_ID_COOKIE
+#define bcmbal_flow_cfg_id_priority BCMBAL_FLOW_CFG_ID_PRIORITY
+#define bcmbal_flow_cfg_id_group_id BCMBAL_FLOW_CFG_ID_GROUP_ID
+#define bcmbal_flow_cfg_id_queue BCMBAL_FLOW_CFG_ID_QUEUE
+#define bcmbal_flow_cfg_id__num_of BCMBAL_FLOW_CFG_ID__NUM_OF
+#define bcmbal_flow_stat_id_rx_packets BCMBAL_FLOW_STAT_ID_RX_PACKETS
+#define bcmbal_flow_stat_id_rx_bytes BCMBAL_FLOW_STAT_ID_RX_BYTES
+#define bcmbal_flow_stat_id_tx_packets BCMBAL_FLOW_STAT_ID_TX_PACKETS
+#define bcmbal_flow_stat_id_tx_bytes BCMBAL_FLOW_STAT_ID_TX_BYTES
+#define bcmbal_flow_stat_id__num_of BCMBAL_FLOW_STAT_ID__NUM_OF
+#define bcmbal_flow_ind_id_admin_state BCMBAL_FLOW_IND_ID_ADMIN_STATE
+#define bcmbal_flow_ind_id_oper_status BCMBAL_FLOW_IND_ID_OPER_STATUS
+#define bcmbal_flow_ind_id_access_int_id BCMBAL_FLOW_IND_ID_ACCESS_INT_ID
+#define bcmbal_flow_ind_id_network_int_id BCMBAL_FLOW_IND_ID_NETWORK_INT_ID
+#define bcmbal_flow_ind_id_sub_term_id BCMBAL_FLOW_IND_ID_SUB_TERM_ID
+#define bcmbal_flow_ind_id_svc_port_id BCMBAL_FLOW_IND_ID_SVC_PORT_ID
+#define bcmbal_flow_ind_id_agg_port_id BCMBAL_FLOW_IND_ID_AGG_PORT_ID
+#define bcmbal_flow_ind_id_resolve_mac BCMBAL_FLOW_IND_ID_RESOLVE_MAC
+#define bcmbal_flow_ind_id_base_tc_id BCMBAL_FLOW_IND_ID_BASE_TC_ID
+#define bcmbal_flow_ind_id_classifier BCMBAL_FLOW_IND_ID_CLASSIFIER
+#define bcmbal_flow_ind_id_action BCMBAL_FLOW_IND_ID_ACTION
+#define bcmbal_flow_ind_id_sla BCMBAL_FLOW_IND_ID_SLA
+#define bcmbal_flow_ind_id_cookie BCMBAL_FLOW_IND_ID_COOKIE
+#define bcmbal_flow_ind_id_priority BCMBAL_FLOW_IND_ID_PRIORITY
+#define bcmbal_flow_ind_id__num_of BCMBAL_FLOW_IND_ID__NUM_OF
+#define bcmbal_group_key_id_group_id BCMBAL_GROUP_KEY_ID_GROUP_ID
+#define bcmbal_group_key_id__num_of BCMBAL_GROUP_KEY_ID__NUM_OF
+#define bcmbal_group_cfg_id_members_cmd BCMBAL_GROUP_CFG_ID_MEMBERS_CMD
+#define bcmbal_group_cfg_id_members BCMBAL_GROUP_CFG_ID_MEMBERS
+#define bcmbal_group_cfg_id_cookie BCMBAL_GROUP_CFG_ID_COOKIE
+#define bcmbal_group_cfg_id_flows BCMBAL_GROUP_CFG_ID_FLOWS
+#define bcmbal_group_cfg_id_owner BCMBAL_GROUP_CFG_ID_OWNER
+#define bcmbal_group_cfg_id__num_of BCMBAL_GROUP_CFG_ID__NUM_OF
+#define bcmbal_interface_key_id_intf_id BCMBAL_INTERFACE_KEY_ID_INTF_ID
+#define bcmbal_interface_key_id_intf_type BCMBAL_INTERFACE_KEY_ID_INTF_TYPE
+#define bcmbal_interface_key_id__num_of BCMBAL_INTERFACE_KEY_ID__NUM_OF
+#define bcmbal_interface_cfg_id_admin_state BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE
+#define bcmbal_interface_cfg_id_oper_status BCMBAL_INTERFACE_CFG_ID_OPER_STATUS
+#define bcmbal_interface_cfg_id_min_data_agg_port_id BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID
+#define bcmbal_interface_cfg_id_min_data_svc_port_id BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID
+#define bcmbal_interface_cfg_id_transceiver_type BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE
+#define bcmbal_interface_cfg_id_ds_miss_mode BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE
+#define bcmbal_interface_cfg_id_mtu BCMBAL_INTERFACE_CFG_ID_MTU
+#define bcmbal_interface_cfg_id_flow_control BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL
+#define bcmbal_interface_cfg_id_ds_tm BCMBAL_INTERFACE_CFG_ID_DS_TM
+#define bcmbal_interface_cfg_id_us_tm BCMBAL_INTERFACE_CFG_ID_US_TM
+#define bcmbal_interface_cfg_id_sub_term_id_list BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST
+#define bcmbal_interface_cfg_id__num_of BCMBAL_INTERFACE_CFG_ID__NUM_OF
+#define bcmbal_interface_stat_id_rx_packets BCMBAL_INTERFACE_STAT_ID_RX_PACKETS
+#define bcmbal_interface_stat_id_rx_bytes BCMBAL_INTERFACE_STAT_ID_RX_BYTES
+#define bcmbal_interface_stat_id_tx_packets BCMBAL_INTERFACE_STAT_ID_TX_PACKETS
+#define bcmbal_interface_stat_id_tx_bytes BCMBAL_INTERFACE_STAT_ID_TX_BYTES
+#define bcmbal_interface_stat_id__num_of BCMBAL_INTERFACE_STAT_ID__NUM_OF
+#define bcmbal_interface_ind_id_admin_state BCMBAL_INTERFACE_IND_ID_ADMIN_STATE
+#define bcmbal_interface_ind_id_oper_status BCMBAL_INTERFACE_IND_ID_OPER_STATUS
+#define bcmbal_interface_ind_id_min_data_agg_port_id BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID
+#define bcmbal_interface_ind_id_min_data_svc_port_id BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID
+#define bcmbal_interface_ind_id_transceiver_type BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE
+#define bcmbal_interface_ind_id_ds_miss_mode BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE
+#define bcmbal_interface_ind_id_mtu BCMBAL_INTERFACE_IND_ID_MTU
+#define bcmbal_interface_ind_id_flow_control BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL
+#define bcmbal_interface_ind_id_ds_tm BCMBAL_INTERFACE_IND_ID_DS_TM
+#define bcmbal_interface_ind_id_us_tm BCMBAL_INTERFACE_IND_ID_US_TM
+#define bcmbal_interface_ind_id__num_of BCMBAL_INTERFACE_IND_ID__NUM_OF
+#define bcmbal_packet_key_id_reserved BCMBAL_PACKET_KEY_ID_RESERVED
+#define bcmbal_packet_key_id_packet_send_dest BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST
+#define bcmbal_packet_key_id__num_of BCMBAL_PACKET_KEY_ID__NUM_OF
+#define bcmbal_packet_cfg_id_flow_id BCMBAL_PACKET_CFG_ID_FLOW_ID
+#define bcmbal_packet_cfg_id_flow_type BCMBAL_PACKET_CFG_ID_FLOW_TYPE
+#define bcmbal_packet_cfg_id_intf_id BCMBAL_PACKET_CFG_ID_INTF_ID
+#define bcmbal_packet_cfg_id_intf_type BCMBAL_PACKET_CFG_ID_INTF_TYPE
+#define bcmbal_packet_cfg_id_svc_port BCMBAL_PACKET_CFG_ID_SVC_PORT
+#define bcmbal_packet_cfg_id_flow_cookie BCMBAL_PACKET_CFG_ID_FLOW_COOKIE
+#define bcmbal_packet_cfg_id_pkt BCMBAL_PACKET_CFG_ID_PKT
+#define bcmbal_packet_cfg_id__num_of BCMBAL_PACKET_CFG_ID__NUM_OF
+#define bcmbal_packet_ind_id_flow_id BCMBAL_PACKET_IND_ID_FLOW_ID
+#define bcmbal_packet_ind_id_flow_type BCMBAL_PACKET_IND_ID_FLOW_TYPE
+#define bcmbal_packet_ind_id_intf_id BCMBAL_PACKET_IND_ID_INTF_ID
+#define bcmbal_packet_ind_id_intf_type BCMBAL_PACKET_IND_ID_INTF_TYPE
+#define bcmbal_packet_ind_id_svc_port BCMBAL_PACKET_IND_ID_SVC_PORT
+#define bcmbal_packet_ind_id_flow_cookie BCMBAL_PACKET_IND_ID_FLOW_COOKIE
+#define bcmbal_packet_ind_id_pkt BCMBAL_PACKET_IND_ID_PKT
+#define bcmbal_packet_ind_id__num_of BCMBAL_PACKET_IND_ID__NUM_OF
+#define bcmbal_subscriber_terminal_key_id_sub_term_id BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID
+#define bcmbal_subscriber_terminal_key_id_intf_id BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID
+#define bcmbal_subscriber_terminal_key_id__num_of BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID__NUM_OF
+#define bcmbal_subscriber_terminal_cfg_id_admin_state BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE
+#define bcmbal_subscriber_terminal_cfg_id_oper_status BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS
+#define bcmbal_subscriber_terminal_cfg_id_serial_number BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER
+#define bcmbal_subscriber_terminal_cfg_id_password BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD
+#define bcmbal_subscriber_terminal_cfg_id_registration_id BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID
+#define bcmbal_subscriber_terminal_cfg_id_svc_port_id BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID
+#define bcmbal_subscriber_terminal_cfg_id_mac_address BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS
+#define bcmbal_subscriber_terminal_cfg_id_ds_tm BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM
+#define bcmbal_subscriber_terminal_cfg_id_us_tm BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM
+#define bcmbal_subscriber_terminal_cfg_id_svc_port_id_list BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST
+#define bcmbal_subscriber_terminal_cfg_id_agg_port_id_list BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST
+#define bcmbal_subscriber_terminal_cfg_id__num_of BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID__NUM_OF
+#define bcmbal_subscriber_terminal_stat_id_rx_packets BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS
+#define bcmbal_subscriber_terminal_stat_id_rx_bytes BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES
+#define bcmbal_subscriber_terminal_stat_id_tx_packets BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS
+#define bcmbal_subscriber_terminal_stat_id_tx_bytes BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES
+#define bcmbal_subscriber_terminal_stat_id__num_of BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID__NUM_OF
+#define bcmbal_subscriber_terminal_ind_id_admin_state BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE
+#define bcmbal_subscriber_terminal_ind_id_oper_status BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS
+#define bcmbal_subscriber_terminal_ind_id_serial_number BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER
+#define bcmbal_subscriber_terminal_ind_id_password BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD
+#define bcmbal_subscriber_terminal_ind_id_registration_id BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID
+#define bcmbal_subscriber_terminal_ind_id_svc_port_id BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID
+#define bcmbal_subscriber_terminal_ind_id_mac_address BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS
+#define bcmbal_subscriber_terminal_ind_id_ds_tm BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM
+#define bcmbal_subscriber_terminal_ind_id_us_tm BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM
+#define bcmbal_subscriber_terminal_ind_id__num_of BCMBAL_SUBSCRIBER_TERMINAL_IND_ID__NUM_OF
+#define bcmbal_tm_queue_key_id_sched_id BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID
+#define bcmbal_tm_queue_key_id_sched_dir BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR
+#define bcmbal_tm_queue_key_id_id BCMBAL_TM_QUEUE_KEY_ID_ID
+#define bcmbal_tm_queue_key_id__num_of BCMBAL_TM_QUEUE_KEY_ID__NUM_OF
+#define bcmbal_tm_queue_cfg_id_priority BCMBAL_TM_QUEUE_CFG_ID_PRIORITY
+#define bcmbal_tm_queue_cfg_id_weight BCMBAL_TM_QUEUE_CFG_ID_WEIGHT
+#define bcmbal_tm_queue_cfg_id_rate BCMBAL_TM_QUEUE_CFG_ID_RATE
+#define bcmbal_tm_queue_cfg_id_bac BCMBAL_TM_QUEUE_CFG_ID_BAC
+#define bcmbal_tm_queue_cfg_id_creation_mode BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE
+#define bcmbal_tm_queue_cfg_id_ref_count BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT
+#define bcmbal_tm_queue_cfg_id__num_of BCMBAL_TM_QUEUE_CFG_ID__NUM_OF
+#define bcmbal_tm_queue_stat_id_packets_ok BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK
+#define bcmbal_tm_queue_stat_id_bytes_ok BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK
+#define bcmbal_tm_queue_stat_id_packets_discarded BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED
+#define bcmbal_tm_queue_stat_id_bytes_discarded BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED
+#define bcmbal_tm_queue_stat_id__num_of BCMBAL_TM_QUEUE_STAT_ID__NUM_OF
+#define bcmbal_tm_queue_ind_id_ret BCMBAL_TM_QUEUE_IND_ID_RET
+#define bcmbal_tm_queue_ind_id__num_of BCMBAL_TM_QUEUE_IND_ID__NUM_OF
+#define bcmbal_tm_sched_key_id_dir BCMBAL_TM_SCHED_KEY_ID_DIR
+#define bcmbal_tm_sched_key_id_id BCMBAL_TM_SCHED_KEY_ID_ID
+#define bcmbal_tm_sched_key_id__num_of BCMBAL_TM_SCHED_KEY_ID__NUM_OF
+#define bcmbal_tm_sched_cfg_id_owner BCMBAL_TM_SCHED_CFG_ID_OWNER
+#define bcmbal_tm_sched_cfg_id_sched_type BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE
+#define bcmbal_tm_sched_cfg_id_sched_parent BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT
+#define bcmbal_tm_sched_cfg_id_sched_child_type BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE
+#define bcmbal_tm_sched_cfg_id_rate BCMBAL_TM_SCHED_CFG_ID_RATE
+#define bcmbal_tm_sched_cfg_id_tcont_sla BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA
+#define bcmbal_tm_sched_cfg_id_creation_mode BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE
+#define bcmbal_tm_sched_cfg_id_queues BCMBAL_TM_SCHED_CFG_ID_QUEUES
+#define bcmbal_tm_sched_cfg_id_sub_scheds BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS
+#define bcmbal_tm_sched_cfg_id_num_priorities BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES
+#define bcmbal_tm_sched_cfg_id__num_of BCMBAL_TM_SCHED_CFG_ID__NUM_OF
+#define bcmbal_tm_sched_ind_id_ret BCMBAL_TM_SCHED_IND_ID_RET
+#define bcmbal_tm_sched_ind_id__num_of BCMBAL_TM_SCHED_IND_ID__NUM_OF
+
+/** Checks whether the given object type has the given tag.
+ *
+ * \return true if the given object has the given tag, false otherwise
+ */
+bcmos_bool bcmbal_obj_has_tag(bcmbal_obj_id obj, bcmbal_obj_tag tag);
+
+#define BCMBAL_OBJ_ID_ANY ((bcmbal_obj_id) UINT16_MAX)
+
+/** @} */
+#endif /* BAL_MODEL_IDS_H_ */
diff --git a/bal_release/src/common/include/bal_model_types.h b/bal_release/src/common/include/bal_model_types.h
new file mode 100644
index 0000000..af683fc
--- /dev/null
+++ b/bal_release/src/common/include/bal_model_types.h
@@ -0,0 +1,1154 @@
+#ifndef BAL_MODEL_TYPES
+#define BAL_MODEL_TYPES
+
+#include <bcmos_system.h>
+#include "bal_obj.h"
+
+/** \defgroup object_model_data_types BAL Object Model Data Types
+ * @{
+ */
+typedef uint32_t bcmbal_access_id; /**< bcmbal_access_id: typed alias for a 32-bit unsigned integer. */
+typedef uint16_t bcmbal_aggregation_port_id; /**< bcmbal_aggregation_port_id: typed alias for a 16-bit unsigned integer. */
+typedef uint64_t bcmbal_cookie; /**< bcmbal_cookie: typed alias for a 64-bit unsigned integer. */
+typedef uint32_t bcmbal_intf_id; /**< bcmbal_intf_id: typed alias for a 32-bit unsigned integer. */
+typedef uint32_t bcmbal_sub_id; /**< bcmbal_sub_id: typed alias for a 32-bit unsigned integer. */
+#define BCMBAL_SUB_ID_UNKNOWN ((bcmbal_sub_id) 65535UL)
+typedef uint32_t bcmbal_flow_id; /**< bcmbal_flow_id: typed alias for a 32-bit unsigned integer. */
+typedef uint32_t bcmbal_group_id; /**< bcmbal_group_id: typed alias for a 32-bit unsigned integer. */
+typedef uint16_t bcmbal_service_port_id; /**< bcmbal_service_port_id: typed alias for a 16-bit unsigned integer. */
+typedef uint32_t bcmbal_tm_sched_id; /**< bcmbal_tm_sched_id: typed alias for a 32-bit unsigned integer. */
+#define BCMBAL_TM_SCHED_ID_UNKNOWN ((bcmbal_tm_sched_id) 65535UL)
+typedef uint8_t bcmbal_tm_queue_id; /**< bcmbal_tm_queue_id: typed alias for a 8-bit unsigned integer. */
+typedef uint8_t bcmbal_percent; /**< bcmbal_percent: typed alias for a 8-bit unsigned integer. */
+typedef uint8_t bcmbal_tm_priority; /**< bcmbal_tm_priority: typed alias for a 8-bit unsigned integer. */
+typedef uint16_t bcmbal_tm_sched_id_index; /**< bcmbal_tm_sched_id_index: typed alias for a 16-bit unsigned integer. */
+typedef uint8_t bcmbal_tm_weight; /**< bcmbal_tm_weight: typed alias for a 8-bit unsigned integer. */
+
+/** action ID.
+ */
+typedef enum bcmbal_action_id
+{
+ BCMBAL_ACTION_ID_NONE = 0,
+ BCMBAL_ACTION_ID_CMDS_BITMASK = 0x0001, /**< Commands bitmask. */
+ BCMBAL_ACTION_ID_O_VID = 0x0002, /**< Outer vid. */
+ BCMBAL_ACTION_ID_O_PBITS = 0x0004, /**< Outer pbits. */
+ BCMBAL_ACTION_ID_O_TPID = 0x0008, /**< Outer tpid. */
+ BCMBAL_ACTION_ID_I_VID = 0x0010, /**< Inner vid. */
+ BCMBAL_ACTION_ID_I_PBITS = 0x0020, /**< Inner pbits. */
+ BCMBAL_ACTION_ID_I_TPID = 0x0040, /**< Inner tpid. */
+ BCMBAL_ACTION_ID_ALL = 0x007F /**< All fields */
+} bcmbal_action_id;
+
+/** action_cmd_id.
+ */
+typedef enum bcmbal_action_cmd_id
+{
+ BCMBAL_ACTION_CMD_ID_NONE = 0,
+ BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG = 0x0001, /**< Add outer tag. */
+ BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG = 0x0002, /**< Remove outer tag. */
+ BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG = 0x0004, /**< Translate outer tag. */
+ BCMBAL_ACTION_CMD_ID_XLATE_TWO_TAGS = 0x0008, /**< Translate two tags. */
+ BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST = 0x0010, /**< Used to satisfy TR-156 Issue 3 R-111 */
+ BCMBAL_ACTION_CMD_ID_DISCARD_DS_UNKNOWN = 0x0020, /**< Used to satisfy TR-156 Issue 3 R-109 */
+ BCMBAL_ACTION_CMD_ID_ADD_TWO_TAGS = 0x0040, /**< Add two tags. */
+ BCMBAL_ACTION_CMD_ID_REMOVE_TWO_TAGS = 0x0080, /**< Remove two tags. */
+ BCMBAL_ACTION_CMD_ID_REMARK_PBITS = 0x0100, /**< Set the outer tag pbits */
+ BCMBAL_ACTION_CMD_ID_COPY_PBITS = 0x0200, /**< Copy the inner pbits to outer pbits */
+ BCMBAL_ACTION_CMD_ID_REVERSE_COPY_PBITS = 0x0400, /**< Copy the outer pbits to inner pbits */
+ BCMBAL_ACTION_CMD_ID_DSCP_TO_PBITS = 0x0800, /**< Copy the L4 DSCP to outer pbits */
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST = 0x1000 /**< Not a valid action for a group object member */
+} bcmbal_action_cmd_id;
+
+/** classifier ID.
+ */
+typedef enum bcmbal_classifier_id
+{
+ BCMBAL_CLASSIFIER_ID_NONE = 0,
+ BCMBAL_CLASSIFIER_ID_O_TPID = 0x0001, /**< Outer TPID of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_O_VID = 0x0002, /**< Outer VID of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_I_TPID = 0x0004, /**< Inner TPID of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_I_VID = 0x0008, /**< Inner VID of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_O_PBITS = 0x0010, /**< Outer PBITS of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_I_PBITS = 0x0020, /**< Inner PBITS of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_ETHER_TYPE = 0x0040, /**< Ethertype of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_DST_MAC = 0x0080, /**< Destination MAC address of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_SRC_MAC = 0x0100, /**< Source MAC address of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_IP_PROTO = 0x0200, /**< IP protocol of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_DST_IP = 0x0400, /**< Destination IP address of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_SRC_IP = 0x0800, /**< Source IP address of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_SRC_PORT = 0x1000, /**< Source port of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_DST_PORT = 0x2000, /**< Destination port of the packet to be classified */
+ BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE = 0x4000, /**< The tag type of the ingress packets */
+ BCMBAL_CLASSIFIER_ID_ALL = 0x7FFF /**< All fields */
+} bcmbal_classifier_id;
+
+/** Packet tag type.
+ */
+typedef enum bcmbal_pkt_tag_type
+{
+ BCMBAL_PKT_TAG_TYPE_NONE = 0,
+ BCMBAL_PKT_TAG_TYPE_UNTAGGED = 0x0001, /**< Untagged. */
+ BCMBAL_PKT_TAG_TYPE_SINGLE_TAG = 0x0002, /**< Single tag. */
+ BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG = 0x0004 /**< Double tag. */
+} bcmbal_pkt_tag_type;
+
+/** Generic enable/disable enumeration
+ */
+typedef enum bcmbal_control
+{
+ BCMBAL_CONTROL_DISABLE = 0, /**< disable. */
+ BCMBAL_CONTROL_ENABLE = 1, /**< enable. */
+ BCMBAL_CONTROL__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_control;
+
+/** Destination type.
+ */
+typedef enum bcmbal_dest_type
+{
+ BCMBAL_DEST_TYPE_NNI = 1, /**< for packets being sent to the NNI */
+ BCMBAL_DEST_TYPE_SUB_TERM = 2, /**< for packets being sent to a subscriber terminal */
+ BCMBAL_DEST_TYPE_HOST = 3 /**< for packet indications received from NNI or SUB_TERM and being sent to the host */
+} bcmbal_dest_type;
+
+/** Downstrean action for unknown packets.
+ */
+typedef enum bcmbal_ds_miss_mode
+{
+ BCMBAL_DS_MISS_MODE_DISCARD = 0, /**< Discard. */
+ BCMBAL_DS_MISS_MODE_BROADCAST = 1, /**< Broadcast. */
+ BCMBAL_DS_MISS_MODE_VID = 2, /**< Vid. */
+ BCMBAL_DS_MISS_MODE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_ds_miss_mode;
+
+/** Extra BW Eligibility Type
+ */
+typedef enum bcmbal_extra_bw_eligibility_type
+{
+ BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NONE = 0, /**< None */
+ BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NOT_ASSURED= 1, /**< Not assured */
+ BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_BEST_EFFORT= 2, /**< Best effort */
+ BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_extra_bw_eligibility_type;
+
+/** Flow Type.
+ */
+typedef enum bcmbal_flow_type
+{
+ BCMBAL_FLOW_TYPE_UPSTREAM = 1, /**< Upstream flow */
+ BCMBAL_FLOW_TYPE_DOWNSTREAM = 2, /**< Downstream Flow */
+ BCMBAL_FLOW_TYPE_BROADCAST = 3, /**< Broadcast Flow */
+ BCMBAL_FLOW_TYPE_MULTICAST = 4 /**< Multicast Flow */
+} bcmbal_flow_type;
+
+/** Member operation type.
+ */
+typedef enum bcmbal_group_member_cmd
+{
+ BCMBAL_GROUP_MEMBER_CMD_ADD_MEMBERS = 1, /**< Add new members. */
+ BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS = 2, /**< Remove existing members. */
+ BCMBAL_GROUP_MEMBER_CMD_SET_MEMBERS = 3 /**< Replace members with new set. */
+} bcmbal_group_member_cmd;
+
+/** owner of the group
+ */
+typedef enum bcmbal_group_owner
+{
+ BCMBAL_GROUP_OWNER_NONE = 0, /**< no owner */
+ BCMBAL_GROUP_OWNER_MULTICAST = 1, /**< used as multicast group */
+ BCMBAL_GROUP_OWNER_UNICAST = 2, /**< used as unicast group */
+ BCMBAL_GROUP_OWNER__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_group_owner;
+
+/** Interface type.
+ */
+typedef enum bcmbal_intf_type
+{
+ BCMBAL_INTF_TYPE_NNI = 0, /**< NNI Interface. */
+ BCMBAL_INTF_TYPE_PON = 1, /**< POIN Interface. */
+ BCMBAL_INTF_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_intf_type;
+
+/** Interworking Function Mode.
+ */
+typedef enum bcmbal_iwf_mode
+{
+ BCMBAL_IWF_MODE_DIRECT_MAPPING = 0, /**< Direct mapping. */
+ BCMBAL_IWF_MODE_PER_FLOW = 1, /**< Per flow . */
+ BCMBAL_IWF_MODE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_iwf_mode;
+
+/** SLA ID.
+ */
+typedef enum bcmbal_sla_id
+{
+ BCMBAL_SLA_ID_NONE = 0,
+ BCMBAL_SLA_ID_MIN_RATE = 0x0001, /**< The minimal rate for this flow, in kilobits per second (optional) */
+ BCMBAL_SLA_ID_MAX_RATE = 0x0002, /**< The maximum rate for this flow, in kilobits per second (optional) */
+ BCMBAL_SLA_ID_ALL = 0x0003 /**< All fields */
+} bcmbal_sla_id;
+
+/** Admin state values for access terminal object
+ */
+typedef enum bcmbal_state
+{
+ BCMBAL_STATE_UP = 1, /**< Admin state up */
+ BCMBAL_STATE_DOWN = 2, /**< Admin state down */
+ BCMBAL_STATE_TESTING = 3 /**< Admin state testing */
+} bcmbal_state;
+
+/** Oper status values
+ */
+typedef enum bcmbal_status
+{
+ BCMBAL_STATUS_UP = 1, /**< Oper status up */
+ BCMBAL_STATUS_DOWN = 2, /**< Oper status down */
+ BCMBAL_STATUS_TESTING = 3, /**< Oper status testing */
+ BCMBAL_STATUS_NOT_PRESENT = 4, /**< Oper status not present */
+ BCMBAL_STATUS_LOWER_LAYER_DOWN = 5, /**< Oper status lower layer down */
+ BCMBAL_STATUS_UNKNOWN = 6 /**< Oper status unknown */
+} bcmbal_status;
+
+/** Buffer Admission Control Type
+ */
+typedef enum bcmbal_tm_bac_type
+{
+ BCMBAL_TM_BAC_TYPE_TAILDROP = 0, /**< Taildrop */
+ BCMBAL_TM_BAC_TYPE_WTAILDROP = 1, /**< Weighted taildrop */
+ BCMBAL_TM_BAC_TYPE_RED = 2, /**< Random Early Discard */
+ BCMBAL_TM_BAC_TYPE_WRED = 3, /**< Weighted Random Early Discard */
+ BCMBAL_TM_BAC_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_bac_type;
+
+/** TM Creation Mode
+ */
+typedef enum bcmbal_tm_creation_mode
+{
+ BCMBAL_TM_CREATION_MODE_MANUAL = 0, /**< tm object created manually */
+ BCMBAL_TM_CREATION_MODE_AUTO = 1, /**< tm object created automatically */
+ BCMBAL_TM_CREATION_MODE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_creation_mode;
+
+/** Scheduling Level for the Children TM
+ */
+typedef enum bcmbal_tm_sched_child_type
+{
+ BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE = 0, /**< Queue-level scheduler */
+ BCMBAL_TM_SCHED_CHILD_TYPE_SCHED = 1, /**< Scheduler-level scheduler */
+ BCMBAL_TM_SCHED_CHILD_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_child_type;
+
+/** Traffic Direction
+ */
+typedef enum bcmbal_tm_sched_dir
+{
+ BCMBAL_TM_SCHED_DIR_US = 1, /**< Upstream */
+ BCMBAL_TM_SCHED_DIR_DS = 2 /**< Downstream */
+} bcmbal_tm_sched_dir;
+
+/** TM Scheduler Owner Type
+ */
+typedef enum bcmbal_tm_sched_owner_type
+{
+ BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED = 0, /**< Undefined */
+ BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE = 1, /**< Interface */
+ BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM = 2, /**< Subscriber terminal */
+ BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT = 3, /**< TM scheduler is owned by aggregation port */
+ BCMBAL_TM_SCHED_OWNER_TYPE_UNI = 4, /**< TM scheduler is owned by UNI port */
+ BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL = 5, /**< Other unspecified owner */
+ BCMBAL_TM_SCHED_OWNER_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_owner_type;
+
+/** tm_sched_owner agg_port ID.
+ */
+typedef enum bcmbal_tm_sched_owner_agg_port_id
+{
+ BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_NONE = 0,
+ BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID = 0x0001, /**< PON interface id */
+ BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID = 0x0002, /**< Subscriber terminal id */
+ BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID = 0x0004, /**< Aggregation port id */
+ BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_ALL = 0x0007 /**< All fields */
+} bcmbal_tm_sched_owner_agg_port_id;
+
+/** tm_sched_parent ID.
+ */
+typedef enum bcmbal_tm_sched_parent_id
+{
+ BCMBAL_TM_SCHED_PARENT_ID_NONE = 0,
+ BCMBAL_TM_SCHED_PARENT_ID_SCHED_ID = 0x0001, /**< Parent scheduler id */
+ BCMBAL_TM_SCHED_PARENT_ID_PRIORITY = 0x0002, /**< Priority */
+ BCMBAL_TM_SCHED_PARENT_ID_WEIGHT = 0x0004, /**< Weight */
+ BCMBAL_TM_SCHED_PARENT_ID_ALL = 0x0007 /**< All fields */
+} bcmbal_tm_sched_parent_id;
+
+/** Scheduler Type
+ */
+typedef enum bcmbal_tm_sched_type
+{
+ BCMBAL_TM_SCHED_TYPE_NONE = 0, /**< NO scheduling */
+ BCMBAL_TM_SCHED_TYPE_WFQ = 1, /**< Weighted Fair Queue */
+ BCMBAL_TM_SCHED_TYPE_SP = 2, /**< Strict Priority */
+ BCMBAL_TM_SCHED_TYPE_SP_WFQ = 3, /**< Hybrid SP + WFQ */
+ BCMBAL_TM_SCHED_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_tm_sched_type;
+
+/** tm_shaping ID.
+ */
+typedef enum bcmbal_tm_shaping_id
+{
+ BCMBAL_TM_SHAPING_ID_NONE = 0,
+ BCMBAL_TM_SHAPING_ID_SBR = 0x0001, /**< Sustained Bit Rate (kbps) */
+ BCMBAL_TM_SHAPING_ID_PBR = 0x0002, /**< Peak Bit Rate (kbps) */
+ BCMBAL_TM_SHAPING_ID_BURST = 0x0004, /**< Max Burst Bytes at Peak Bit Rate */
+ BCMBAL_TM_SHAPING_ID_ALL = 0x0007 /**< All fields */
+} bcmbal_tm_shaping_id;
+
+/** tm_tcont_sla ID.
+ */
+typedef enum bcmbal_tm_tcont_sla_id
+{
+ BCMBAL_TM_TCONT_SLA_ID_NONE = 0,
+ BCMBAL_TM_TCONT_SLA_ID_EXTRA_BW_ELIG = 0x0001, /**< Extra BW eligibility type */
+ BCMBAL_TM_TCONT_SLA_ID_NRT_CBR = 0x0002, /**< NRT CBR */
+ BCMBAL_TM_TCONT_SLA_ID_RT_CBR = 0x0004, /**< RT_CBR */
+ BCMBAL_TM_TCONT_SLA_ID_RT_PROFILE = 0x0008, /**< RT Profile */
+ BCMBAL_TM_TCONT_SLA_ID_NRT_PROFILE = 0x0010, /**< NRT Profile */
+ BCMBAL_TM_TCONT_SLA_ID_ALL = 0x001F /**< All fields */
+} bcmbal_tm_tcont_sla_id;
+
+/** Transceiver types
+ */
+typedef enum bcmbal_trx_type
+{
+ BCMBAL_TRX_TYPE_GPON_SPS_43_48 = 0, /**< gpon_sps_43_48. */
+ BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321 = 1, /**< gpon_sps_sog_4321. */
+ BCMBAL_TRX_TYPE_GPON_LTE_3680_M = 2, /**< gpon_lte_3680_m. */
+ BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS = 3, /**< gpon_source_photonics. */
+ BCMBAL_TRX_TYPE_GPON_LTE_3680_P = 4, /**< gpon_lte_3680_p. */
+ BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC = 5, /**< xgpon_lth_7222_pc. */
+ BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC = 6, /**< xgpon_lth_7226_pc. */
+ BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC = 7, /**< xgpon_lth_5302_pc. */
+ BCMBAL_TRX_TYPE__NUM_OF /**< Number of enum entries, not an entry itself. */
+} bcmbal_trx_type;
+
+#define bcmbal_action_id_none BCMBAL_ACTION_ID_NONE
+#define bcmbal_action_id_cmds_bitmask BCMBAL_ACTION_ID_CMDS_BITMASK
+#define bcmbal_action_id_o_vid BCMBAL_ACTION_ID_O_VID
+#define bcmbal_action_id_o_pbits BCMBAL_ACTION_ID_O_PBITS
+#define bcmbal_action_id_o_tpid BCMBAL_ACTION_ID_O_TPID
+#define bcmbal_action_id_i_vid BCMBAL_ACTION_ID_I_VID
+#define bcmbal_action_id_i_pbits BCMBAL_ACTION_ID_I_PBITS
+#define bcmbal_action_id_i_tpid BCMBAL_ACTION_ID_I_TPID
+#define bcmbal_action_id_all BCMBAL_ACTION_ID_ALL
+#define bcmbal_classifier_id_none BCMBAL_CLASSIFIER_ID_NONE
+#define bcmbal_classifier_id_o_tpid BCMBAL_CLASSIFIER_ID_O_TPID
+#define bcmbal_classifier_id_o_vid BCMBAL_CLASSIFIER_ID_O_VID
+#define bcmbal_classifier_id_i_tpid BCMBAL_CLASSIFIER_ID_I_TPID
+#define bcmbal_classifier_id_i_vid BCMBAL_CLASSIFIER_ID_I_VID
+#define bcmbal_classifier_id_o_pbits BCMBAL_CLASSIFIER_ID_O_PBITS
+#define bcmbal_classifier_id_i_pbits BCMBAL_CLASSIFIER_ID_I_PBITS
+#define bcmbal_classifier_id_ether_type BCMBAL_CLASSIFIER_ID_ETHER_TYPE
+#define bcmbal_classifier_id_dst_mac BCMBAL_CLASSIFIER_ID_DST_MAC
+#define bcmbal_classifier_id_src_mac BCMBAL_CLASSIFIER_ID_SRC_MAC
+#define bcmbal_classifier_id_ip_proto BCMBAL_CLASSIFIER_ID_IP_PROTO
+#define bcmbal_classifier_id_dst_ip BCMBAL_CLASSIFIER_ID_DST_IP
+#define bcmbal_classifier_id_src_ip BCMBAL_CLASSIFIER_ID_SRC_IP
+#define bcmbal_classifier_id_src_port BCMBAL_CLASSIFIER_ID_SRC_PORT
+#define bcmbal_classifier_id_dst_port BCMBAL_CLASSIFIER_ID_DST_PORT
+#define bcmbal_classifier_id_pkt_tag_type BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE
+#define bcmbal_classifier_id_all BCMBAL_CLASSIFIER_ID_ALL
+#define bcmbal_sla_id_none BCMBAL_SLA_ID_NONE
+#define bcmbal_sla_id_min_rate BCMBAL_SLA_ID_MIN_RATE
+#define bcmbal_sla_id_max_rate BCMBAL_SLA_ID_MAX_RATE
+#define bcmbal_sla_id_all BCMBAL_SLA_ID_ALL
+#define bcmbal_tm_sched_owner_agg_port_id_none BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_NONE
+#define bcmbal_tm_sched_owner_agg_port_id_intf_id BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID
+#define bcmbal_tm_sched_owner_agg_port_id_sub_term_id BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID
+#define bcmbal_tm_sched_owner_agg_port_id_agg_port_id BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID
+#define bcmbal_tm_sched_owner_agg_port_id_all BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_ALL
+#define bcmbal_tm_sched_parent_id_none BCMBAL_TM_SCHED_PARENT_ID_NONE
+#define bcmbal_tm_sched_parent_id_sched_id BCMBAL_TM_SCHED_PARENT_ID_SCHED_ID
+#define bcmbal_tm_sched_parent_id_priority BCMBAL_TM_SCHED_PARENT_ID_PRIORITY
+#define bcmbal_tm_sched_parent_id_weight BCMBAL_TM_SCHED_PARENT_ID_WEIGHT
+#define bcmbal_tm_sched_parent_id_all BCMBAL_TM_SCHED_PARENT_ID_ALL
+#define bcmbal_tm_shaping_id_none BCMBAL_TM_SHAPING_ID_NONE
+#define bcmbal_tm_shaping_id_sbr BCMBAL_TM_SHAPING_ID_SBR
+#define bcmbal_tm_shaping_id_pbr BCMBAL_TM_SHAPING_ID_PBR
+#define bcmbal_tm_shaping_id_burst BCMBAL_TM_SHAPING_ID_BURST
+#define bcmbal_tm_shaping_id_all BCMBAL_TM_SHAPING_ID_ALL
+#define bcmbal_tm_tcont_sla_id_none BCMBAL_TM_TCONT_SLA_ID_NONE
+#define bcmbal_tm_tcont_sla_id_extra_bw_elig BCMBAL_TM_TCONT_SLA_ID_EXTRA_BW_ELIG
+#define bcmbal_tm_tcont_sla_id_nrt_cbr BCMBAL_TM_TCONT_SLA_ID_NRT_CBR
+#define bcmbal_tm_tcont_sla_id_rt_cbr BCMBAL_TM_TCONT_SLA_ID_RT_CBR
+#define bcmbal_tm_tcont_sla_id_rt_profile BCMBAL_TM_TCONT_SLA_ID_RT_PROFILE
+#define bcmbal_tm_tcont_sla_id_nrt_profile BCMBAL_TM_TCONT_SLA_ID_NRT_PROFILE
+#define bcmbal_tm_tcont_sla_id_all BCMBAL_TM_TCONT_SLA_ID_ALL
+
+/** action.
+ */
+typedef struct bcmbal_action
+{
+ bcmbal_action_id presence_mask; /**< Presence Mask. */
+ bcmbal_action_cmd_id cmds_bitmask; /**< Commands bitmask. */
+ uint16_t o_vid; /**< Outer vid. */
+ uint8_t o_pbits; /**< Outer pbits. */
+ uint16_t o_tpid; /**< Outer tpid. */
+ uint16_t i_vid; /**< Inner vid. */
+ uint8_t i_pbits; /**< Inner pbits. */
+ uint16_t i_tpid; /**< Inner tpid. */
+} bcmbal_action;
+
+/** Variable-length list of aggregation_port_id.
+ */
+typedef struct bcmbal_aggregation_port_id_list_u8
+{
+ uint8_t len; /**< List length. */
+ bcmbal_aggregation_port_id *val; /**< List contents. */
+} bcmbal_aggregation_port_id_list_u8;
+
+/** classifier.
+ */
+typedef struct bcmbal_classifier
+{
+ bcmbal_classifier_id presence_mask; /**< Presence Mask. */
+ uint16_t o_tpid; /**< Outer TPID of the packet to be classified */
+ uint16_t o_vid; /**< Outer VID of the packet to be classified */
+ uint16_t i_tpid; /**< Inner TPID of the packet to be classified */
+ uint16_t i_vid; /**< Inner VID of the packet to be classified */
+ uint8_t o_pbits; /**< Outer PBITS of the packet to be classified */
+ uint8_t i_pbits; /**< Inner PBITS of the packet to be classified */
+ uint16_t ether_type; /**< Ethertype of the packet to be classified */
+ bcmos_mac_address dst_mac; /**< Destination MAC address of the packet to be classified */
+ bcmos_mac_address src_mac; /**< Source MAC address of the packet to be classified */
+ uint8_t ip_proto; /**< IP protocol of the packet to be classified */
+ bcmos_ipv4_address dst_ip; /**< Destination IP address of the packet to be classified */
+ bcmos_ipv4_address src_ip; /**< Source IP address of the packet to be classified */
+ uint16_t src_port; /**< Source port of the packet to be classified */
+ uint16_t dst_port; /**< Destination port of the packet to be classified */
+ bcmbal_pkt_tag_type pkt_tag_type; /**< The tag type of the ingress packets */
+} bcmbal_classifier;
+
+/** Packet destination.
+ */
+typedef struct bcmbal_dest
+{
+ bcmbal_dest_type type; /**< packet destination. */
+ union
+ {
+ struct
+ {
+ bcmbal_intf_id int_id; /**< Interface ID. */
+ } nni;
+
+ struct
+ {
+ bcmbal_sub_id sub_term_id; /**< Subscriber terminal ID. */
+ uint16_t sub_term_uni; /**< Subscriber terminal UNI. */
+ uint16_t int_id; /**< Interface ID. */
+ } sub_term;
+ } u;
+} bcmbal_dest;
+
+/** Variable-length list of flow_id.
+ */
+typedef struct bcmbal_flow_id_list_u32
+{
+ uint32_t len; /**< List length. */
+ bcmbal_flow_id *val; /**< List contents. */
+} bcmbal_flow_id_list_u32;
+
+/** Queue Reference
+ */
+typedef struct bcmbal_tm_queue_ref
+{
+ bcmbal_tm_sched_id sched_id; /**< Scheduler (tm_sched) ID */
+ bcmbal_tm_queue_id queue_id; /**< Queue ID */
+} bcmbal_tm_queue_ref;
+
+/** Group Member Info.
+ */
+typedef struct bcmbal_group_member_info
+{
+ bcmbal_intf_id intf_id; /**< Access interface id for this member */
+ bcmbal_service_port_id svc_port_id; /**< The multicast "GEM" for this member */
+ bcmbal_action action; /**< VLAN actions */
+ bcmbal_tm_queue_ref queue; /**< Egress queue */
+} bcmbal_group_member_info;
+
+/** Variable-length list of group_member_info.
+ */
+typedef struct bcmbal_group_member_info_list_u16
+{
+ uint16_t len; /**< List length. */
+ bcmbal_group_member_info *val; /**< List contents. */
+} bcmbal_group_member_info_list_u16;
+
+/** Password.
+ */
+typedef struct bcmbal_password
+{
+ uint8_t arr[10]; /**< Array. */
+} bcmbal_password;
+
+/** Registration id.
+ */
+typedef struct bcmbal_registration_id
+{
+ uint8_t arr[36]; /**< ONU registration ID */
+} bcmbal_registration_id;
+
+/** Serial number.
+ */
+typedef struct bcmbal_serial_number
+{
+ uint8_t vendor_id[4]; /**< vendor id. */
+ uint8_t vendor_specific[4]; /**< vendor specific. */
+} bcmbal_serial_number;
+
+/** Variable-length list of service_port_id.
+ */
+typedef struct bcmbal_service_port_id_list_u8
+{
+ uint8_t len; /**< List length. */
+ bcmbal_service_port_id *val; /**< List contents. */
+} bcmbal_service_port_id_list_u8;
+
+/** SLA.
+ */
+typedef struct bcmbal_sla
+{
+ bcmbal_sla_id presence_mask; /**< Presence Mask. */
+ uint32_t min_rate; /**< The minimal rate for this flow, in kilobits per second (optional) */
+ uint32_t max_rate; /**< The maximum rate for this flow, in kilobits per second (optional) */
+} bcmbal_sla;
+
+/** Variable-length list of sub_id.
+ */
+typedef struct bcmbal_sub_id_list_u16
+{
+ uint16_t len; /**< List length. */
+ bcmbal_sub_id *val; /**< List contents. */
+} bcmbal_sub_id_list_u16;
+
+/** Random Early Discard Configuration
+ */
+typedef struct bcmbal_tm_red
+{
+ bcmbal_percent min_threshold; /**< Min threshold in percent of max queue size */
+ bcmbal_percent max_threshold; /**< Max threshold in percent of max queue size */
+ bcmbal_percent max_probability; /**< Discard probability for occupancy between min_threshold and max_threshold */
+} bcmbal_tm_red;
+
+/** Queue Buffer Admission Control
+ */
+typedef struct bcmbal_tm_bac
+{
+ bcmbal_tm_bac_type type; /**< Buffer Admission Control Type */
+ union
+ {
+ struct
+ {
+ uint32_t max_size; /**< max number of packets in the queue */
+ } taildrop;
+
+ struct
+ {
+ bcmbal_tm_red red; /**< Random Early Discard configuration */
+ } red;
+
+ struct
+ {
+ bcmbal_tm_red green; /**< Green Random Early Discard Configuration */
+ bcmbal_tm_red yellow; /**< Yellow Random Early Discard Configuration */
+ bcmbal_tm_red red; /**< Red Random Early Discard Configuration */
+ } wred;
+ } u;
+} bcmbal_tm_bac;
+
+/** Variable-length list of tm_queue_id.
+ */
+typedef struct bcmbal_tm_queue_id_list_u8
+{
+ uint8_t len; /**< List length. */
+ bcmbal_tm_queue_id *val; /**< List contents. */
+} bcmbal_tm_queue_id_list_u8;
+
+/** Variable-length list of tm_sched_id.
+ */
+typedef struct bcmbal_tm_sched_id_list_u8
+{
+ uint8_t len; /**< List length. */
+ bcmbal_tm_sched_id *val; /**< List contents. */
+} bcmbal_tm_sched_id_list_u8;
+
+/** TM Scheduler Owner
+ */
+typedef struct bcmbal_tm_sched_owner
+{
+ bcmbal_tm_sched_owner_type type; /**< Owner type */
+ union
+ {
+ struct
+ {
+ bcmbal_intf_type intf_type; /**< Interface Type */
+ bcmbal_intf_id intf_id; /**< Interface ID */
+ } interface;
+
+ struct
+ {
+ bcmbal_intf_id intf_id; /**< PON interface id */
+ bcmbal_sub_id sub_term_id; /**< Subscriber terminal ID */
+ } sub_term;
+
+ struct
+ {
+ bcmbal_tm_sched_owner_agg_port_id presence_mask; /**< Presence Mask. */
+ uint8_t intf_id; /**< PON interface id */
+ bcmbal_sub_id sub_term_id; /**< Subscriber terminal id */
+ bcmbal_aggregation_port_id agg_port_id; /**< Aggregation port id */
+ } agg_port;
+
+ struct
+ {
+ uint8_t intf_id; /**< PON interface id */
+ bcmbal_sub_id sub_term_id; /**< Subscriber terminal id */
+ uint8_t idx; /**< Index at subscriber terminal */
+ } uni;
+
+ struct
+ {
+ uint32_t idx; /**< Owner index */
+ } virtual;
+ } u;
+} bcmbal_tm_sched_owner;
+
+/** Scheduling Parent Connect Point
+ */
+typedef struct bcmbal_tm_sched_parent
+{
+ bcmbal_tm_sched_parent_id presence_mask; /**< Presence Mask. */
+ bcmbal_tm_sched_id sched_id; /**< Parent scheduler id */
+ bcmbal_tm_priority priority; /**< Priority */
+ bcmbal_tm_weight weight; /**< Weight */
+} bcmbal_tm_sched_parent;
+
+/** Shaping Parameters
+ */
+typedef struct bcmbal_tm_shaping
+{
+ bcmbal_tm_shaping_id presence_mask; /**< Presence Mask. */
+ uint32_t sbr; /**< Sustained Bit Rate (kbps) */
+ uint32_t pbr; /**< Peak Bit Rate (kbps) */
+ uint32_t burst; /**< Max Burst Bytes at Peak Bit Rate */
+} bcmbal_tm_shaping;
+
+/** ITU-PON Extended SLA Parameters
+ */
+typedef struct bcmbal_tm_tcont_sla
+{
+ bcmbal_tm_tcont_sla_id presence_mask; /**< Presence Mask. */
+ bcmbal_extra_bw_eligibility_type extra_bw_elig; /**< Extra BW eligibility type */
+ uint8_t nrt_cbr; /**< NRT CBR */
+ uint8_t rt_cbr; /**< RT_CBR */
+ uint8_t rt_profile; /**< RT Profile */
+ uint8_t nrt_profile; /**< NRT Profile */
+} bcmbal_tm_tcont_sla;
+
+/** Variable-length list of U8.
+ */
+typedef struct bcmbal_u8_list_u32
+{
+ uint32_t len; /**< List length. */
+ uint8_t *val; /**< List contents. */
+} bcmbal_u8_list_u32;
+
+/** Structure definition for the "key" group of the "access_terminal" object.
+ */
+typedef struct bcmbal_access_terminal_key
+{
+ bcmbal_access_id access_term_id; /**< Reserved (set to 0) */
+} bcmbal_access_terminal_key;
+
+/** Structure definition for the "cfg" group of the "access_terminal" object.
+ */
+typedef struct bcmbal_access_terminal_cfg_data
+{
+ bcmbal_state admin_state; /**< Administrative state */
+ bcmbal_status oper_status; /**< Operational status */
+ bcmbal_iwf_mode iwf_mode; /**< The interworking mode */
+} bcmbal_access_terminal_cfg_data;
+
+/** Transport message definition for "cfg" group of "access_terminal" object.
+ */
+typedef struct bcmbal_access_terminal_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_access_terminal_key key; /**< Object key. */
+ bcmbal_access_terminal_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_access_terminal_cfg;
+
+/** Structure definition for the "ind" group of the "access_terminal" object.
+ */
+typedef struct bcmbal_access_terminal_ind_data
+{
+ bcmbal_state admin_state; /**< Current administrative state */
+ bcmbal_status oper_status; /**< Current operational status */
+ bcmbal_iwf_mode iwf_mode; /**< The interworking mode */
+} bcmbal_access_terminal_ind_data;
+
+/** Transport message definition for "ind" group of "access_terminal" object.
+ */
+typedef struct bcmbal_access_terminal_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_access_terminal_key key; /**< Object key. */
+ bcmbal_access_terminal_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_access_terminal_ind;
+
+/** Structure definition for the "key" group of the "flow" object.
+ */
+typedef struct bcmbal_flow_key
+{
+ bcmbal_flow_id flow_id; /**< The ID of the flow object instance being referenced */
+ bcmbal_flow_type flow_type; /**< The type of the flow, Upstream, Downstream, Broadcast or Multicast */
+} bcmbal_flow_key;
+
+/** Structure definition for the "cfg" group of the "flow" object.
+ */
+typedef struct bcmbal_flow_cfg_data
+{
+ bcmbal_state admin_state; /**< Administrative state */
+ bcmbal_status oper_status; /**< Operational status */
+ bcmbal_intf_id access_int_id; /**< The ID of the subscriber side interface; i.e. PON */
+ bcmbal_intf_id network_int_id; /**< The ID of the network side interface; i.e. NNI */
+ bcmbal_sub_id sub_term_id; /**< The ID of the subsccriber terminal device */
+ uint8_t sub_term_uni_idx; /**< The index of the subsccriber terminal uni port the flow is related to */
+ bcmbal_service_port_id svc_port_id; /**< The ID of the service port (for GPON/XGPON - GEM ID) */
+ bcmbal_aggregation_port_id agg_port_id; /**< The ID of the aggregate port (for GPON/XGPON - ALLOC ID) */
+ bcmos_bool resolve_mac; /**< A flag indicating if the MAC address table should be used in DS GEM resolution */
+ bcmbal_classifier classifier; /**< The classifier for this flow */
+ bcmbal_action action; /**< The action associated with the flow */
+ bcmbal_sla sla; /**< SLA parameters for this flow */
+ bcmbal_cookie cookie; /**< Application cookie */
+ uint16_t priority; /**< Priority for this flow in case of multiple match. */
+ bcmbal_group_id group_id; /**< RW - The multicast group associated with this flow, valid for type MULTICAST only */
+ bcmbal_tm_queue_ref queue; /**< Egress queue */
+} bcmbal_flow_cfg_data;
+
+/** Transport message definition for "cfg" group of "flow" object.
+ */
+typedef struct bcmbal_flow_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_flow_key key; /**< Object key. */
+ bcmbal_flow_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_flow_cfg;
+
+/** Structure definition for the "stat" group of the "flow" object.
+ */
+typedef struct bcmbal_flow_stat_data
+{
+ uint64_t rx_packets; /**< Received packets. */
+ uint64_t rx_bytes; /**< Received bytes. */
+ uint64_t tx_packets; /**< Transmitted packets. */
+ uint64_t tx_bytes; /**< Transmitted bytes. */
+} bcmbal_flow_stat_data;
+
+/** Transport message definition for "stat" group of "flow" object.
+ */
+typedef struct bcmbal_flow_stat
+{
+ bcmbal_stat hdr; /**< Transport header. */
+ bcmbal_flow_key key; /**< Object key. */
+ bcmbal_flow_stat_data data; /**< All properties that must be set by the user. */
+} bcmbal_flow_stat;
+
+/** Structure definition for the "ind" group of the "flow" object.
+ */
+typedef struct bcmbal_flow_ind_data
+{
+ bcmbal_state admin_state; /**< Administrative state */
+ bcmbal_status oper_status; /**< Operational Status */
+ uint16_t access_int_id; /**< The ID of the subscriber side interface; i.e. PON */
+ uint16_t network_int_id; /**< The ID of the network side interface; i.e. NNI */
+ uint32_t sub_term_id; /**< The ID of the subsccriber terminal device */
+ uint16_t svc_port_id; /**< The ID of the service port (for GPON/XGPON - GEM ID) */
+ uint16_t agg_port_id; /**< The ID of the aggregate port (for GPON/XGPON - ALLOC ID) */
+ bcmos_bool resolve_mac; /**< A flag indicating if the MAC address table should be used in DS GEM resolution */
+ uint16_t base_tc_id; /**< The base index of the TC object(s) to be used for this flow */
+ bcmbal_classifier classifier; /**< The classifier for this flow */
+ bcmbal_action action; /**< The action associated with the flow */
+ bcmbal_sla sla; /**< SLA parameters for this flow */
+ uint32_t cookie; /**< Application cookie */
+ uint16_t priority; /**< Priority for this flow in case of multiple match. */
+} bcmbal_flow_ind_data;
+
+/** Transport message definition for "ind" group of "flow" object.
+ */
+typedef struct bcmbal_flow_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_flow_key key; /**< Object key. */
+ bcmbal_flow_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_flow_ind;
+
+/** Structure definition for the "key" group of the "group" object.
+ */
+typedef struct bcmbal_group_key
+{
+ bcmbal_group_id group_id; /**< The ID of the group object instance being referenced */
+} bcmbal_group_key;
+
+/** Structure definition for the "cfg" group of the "group" object.
+ */
+typedef struct bcmbal_group_cfg_data
+{
+ bcmbal_group_member_cmd members_cmd; /**< Membership operation commands. */
+ bcmbal_group_member_info_list_u16 members; /**< The list of members associated with this group */
+ bcmbal_cookie cookie; /**< Application cookie */
+ bcmbal_flow_id_list_u32 flows; /**< List of flows associated with this group */
+ bcmbal_group_owner owner; /**< Owner of the group. */
+} bcmbal_group_cfg_data;
+
+/** Transport message definition for "cfg" group of "group" object.
+ */
+typedef struct bcmbal_group_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_group_key key; /**< Object key. */
+ bcmbal_group_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_group_cfg;
+
+/** Structure definition for the "key" group of the "interface" object.
+ */
+typedef struct bcmbal_interface_key
+{
+ uint32_t intf_id; /**< intf_id. */
+ bcmbal_intf_type intf_type; /**< intf_type. */
+} bcmbal_interface_key;
+
+/** Structure definition for the "cfg" group of the "interface" object.
+ */
+typedef struct bcmbal_interface_cfg_data
+{
+ bcmbal_state admin_state; /**< Administrative state */
+ bcmbal_status oper_status; /**< Operational status */
+ bcmbal_aggregation_port_id min_data_agg_port_id; /**< The minimum agg_port_id that is allowed in the system */
+ bcmbal_service_port_id min_data_svc_port_id; /**< The minimum svc_port_id that is allowed in the system */
+ bcmbal_trx_type transceiver_type; /**< The transceiver type used on an interface */
+ bcmbal_ds_miss_mode ds_miss_mode; /**< Defines the action to take for unknown downstream packets */
+ uint16_t mtu; /**< The MTU for an interface */
+ bcmbal_control flow_control; /**< Flow control enable or disable */
+ bcmbal_tm_sched_id ds_tm; /**< Downstream scheduler and shaper */
+ bcmbal_tm_sched_id us_tm; /**< Upstream scheduler and shaper */
+ bcmbal_sub_id_list_u16 sub_term_id_list; /**< A list of subscriber terminal ids configured on this interface */
+} bcmbal_interface_cfg_data;
+
+/** Transport message definition for "cfg" group of "interface" object.
+ */
+typedef struct bcmbal_interface_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_interface_key key; /**< Object key. */
+ bcmbal_interface_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_interface_cfg;
+
+/** Structure definition for the "stat" group of the "interface" object.
+ */
+typedef struct bcmbal_interface_stat_data
+{
+ uint64_t rx_packets; /**< Recieved packets. */
+ uint64_t rx_bytes; /**< Received bytes. */
+ uint64_t tx_packets; /**< Transmitted packets. */
+ uint64_t tx_bytes; /**< Transmitted bytes. */
+} bcmbal_interface_stat_data;
+
+/** Transport message definition for "stat" group of "interface" object.
+ */
+typedef struct bcmbal_interface_stat
+{
+ bcmbal_stat hdr; /**< Transport header. */
+ bcmbal_interface_key key; /**< Object key. */
+ bcmbal_interface_stat_data data; /**< All properties that must be set by the user. */
+} bcmbal_interface_stat;
+
+/** Structure definition for the "ind" group of the "interface" object.
+ */
+typedef struct bcmbal_interface_ind_data
+{
+ bcmbal_state admin_state; /**< Current administrative state */
+ bcmbal_status oper_status; /**< Current operational state */
+ uint16_t min_data_agg_port_id; /**< The minimum agg_port_id that is allowed in the system */
+ uint16_t min_data_svc_port_id; /**< The minimum svc_port_id that is allowed in the system */
+ bcmbal_trx_type transceiver_type; /**< The transceiver type used on an interface */
+ bcmbal_ds_miss_mode ds_miss_mode; /**< Defines the action to take for DS unknown packets */
+ uint16_t mtu; /**< The MTU for an interface */
+ bcmbal_control flow_control; /**< Flow control enable or disable */
+ bcmbal_tm_sched_id ds_tm; /**< Downstream scheduler and shaper */
+ bcmbal_tm_sched_id us_tm; /**< Upstream scheduler and shaper */
+} bcmbal_interface_ind_data;
+
+/** Transport message definition for "ind" group of "interface" object.
+ */
+typedef struct bcmbal_interface_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_interface_key key; /**< Object key. */
+ bcmbal_interface_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_interface_ind;
+
+/** Structure definition for the "key" group of the "packet" object.
+ */
+typedef struct bcmbal_packet_key
+{
+ uint32_t reserved; /**< Reserved key field. */
+ bcmbal_dest packet_send_dest; /**< Packet destination. */
+} bcmbal_packet_key;
+
+/** Structure definition for the "cfg" group of the "packet" object.
+ */
+typedef struct bcmbal_packet_cfg_data
+{
+ bcmbal_flow_id flow_id; /**< N/A for sending a packet */
+ bcmbal_flow_type flow_type; /**< Flow Type. */
+ bcmbal_intf_id intf_id; /**< Interface ID. */
+ bcmbal_intf_type intf_type; /**< Interface Type. */
+ bcmbal_service_port_id svc_port; /**< N/A for sending a packet */
+ bcmbal_cookie flow_cookie; /**< N/A for sending a packet */
+ bcmbal_u8_list_u32 pkt; /**< Packet Data. */
+} bcmbal_packet_cfg_data;
+
+/** Transport message definition for "cfg" group of "packet" object.
+ */
+typedef struct bcmbal_packet_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_packet_key key; /**< Object key. */
+ bcmbal_packet_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_packet_cfg;
+
+/** Structure definition for the "ind" group of the "packet" object.
+ */
+typedef struct bcmbal_packet_ind_data
+{
+ bcmbal_flow_id flow_id; /**< N/A for sending a packet */
+ bcmbal_flow_type flow_type; /**< Flow Type. */
+ bcmbal_intf_id intf_id; /**< Interface ID. */
+ bcmbal_intf_type intf_type; /**< Interface Type. */
+ bcmbal_service_port_id svc_port; /**< N/A for sending a packet */
+ bcmbal_cookie flow_cookie; /**< N/A for sending a packet */
+ bcmbal_u8_list_u32 pkt; /**< Packet Data. */
+} bcmbal_packet_ind_data;
+
+/** Transport message definition for "ind" group of "packet" object.
+ */
+typedef struct bcmbal_packet_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_packet_key key; /**< Object key. */
+ bcmbal_packet_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_packet_ind;
+
+/** Structure definition for the "key" group of the "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_key
+{
+ bcmbal_sub_id sub_term_id; /**< sub_term_id. */
+ bcmbal_intf_id intf_id; /**< intf_id. */
+} bcmbal_subscriber_terminal_key;
+
+/** Structure definition for the "cfg" group of the "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_cfg_data
+{
+ bcmbal_state admin_state; /**< Administrative state */
+ bcmbal_status oper_status; /**< Operational status */
+ bcmbal_serial_number serial_number; /**< The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal */
+ bcmbal_password password; /**< The password of a GPON subscriber terminal */
+ bcmbal_registration_id registration_id; /**< ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal */
+ bcmbal_service_port_id svc_port_id; /**< The management service port ID (for PON, the ONU ID) */
+ bcmos_mac_address mac_address; /**< The Ethernet MAC address of an EPON subscriber terminal */
+ bcmbal_tm_sched_id ds_tm; /**< Downstream scheduler and shaper */
+ bcmbal_tm_sched_id us_tm; /**< Upstream scheduler and shaper */
+ bcmbal_service_port_id_list_u8 svc_port_id_list; /**< A list of bearer traffic svc_port_ids associated with this subscriber terminal */
+ bcmbal_aggregation_port_id_list_u8 agg_port_id_list; /**< A list of aggr_port_ids associated with this subscriber terminal */
+} bcmbal_subscriber_terminal_cfg_data;
+
+/** Transport message definition for "cfg" group of "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_subscriber_terminal_key key; /**< Object key. */
+ bcmbal_subscriber_terminal_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_subscriber_terminal_cfg;
+
+/** Structure definition for the "stat" group of the "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_stat_data
+{
+ uint64_t rx_packets; /**< Received packets on specified object */
+ uint64_t rx_bytes; /**< Received bytes on specified object */
+ uint64_t tx_packets; /**< Transmitted packets on specified object */
+ uint64_t tx_bytes; /**< Transmittted bytes on specified object */
+} bcmbal_subscriber_terminal_stat_data;
+
+/** Transport message definition for "stat" group of "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_stat
+{
+ bcmbal_stat hdr; /**< Transport header. */
+ bcmbal_subscriber_terminal_key key; /**< Object key. */
+ bcmbal_subscriber_terminal_stat_data data; /**< All properties that must be set by the user. */
+} bcmbal_subscriber_terminal_stat;
+
+/** Structure definition for the "ind" group of the "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_ind_data
+{
+ bcmbal_state admin_state; /**< Current administrative state */
+ bcmbal_status oper_status; /**< Current operational status */
+ bcmbal_serial_number serial_number; /**< The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal */
+ bcmbal_password password; /**< The password of a GPON subscriber terminal */
+ bcmbal_registration_id registration_id; /**< ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal */
+ uint16_t svc_port_id; /**< The service port ID (for PON, the ONU ID) */
+ bcmos_mac_address mac_address; /**< The Ethernet MAC address of an epon subscriber terminal */
+ bcmbal_tm_sched_id ds_tm; /**< Downstream scheduler and shaper */
+ bcmbal_tm_sched_id us_tm; /**< Upstream scheduler and shaper */
+} bcmbal_subscriber_terminal_ind_data;
+
+/** Transport message definition for "ind" group of "subscriber_terminal"
+ * object.
+ */
+typedef struct bcmbal_subscriber_terminal_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_subscriber_terminal_key key; /**< Object key. */
+ bcmbal_subscriber_terminal_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_subscriber_terminal_ind;
+
+/** Structure definition for the "key" group of the "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_key
+{
+ bcmbal_tm_sched_id sched_id; /**< Scheduler that owns the queue */
+ bcmbal_tm_sched_dir sched_dir; /**< sched dir. */
+ bcmbal_tm_queue_id id; /**< Queue id */
+} bcmbal_tm_queue_key;
+
+/** Structure definition for the "cfg" group of the "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_cfg_data
+{
+ bcmbal_tm_priority priority; /**< Scheduling priority */
+ bcmbal_tm_weight weight; /**< Scheduling weight */
+ bcmbal_tm_shaping rate; /**< Rate shaping parameters */
+ bcmbal_tm_bac bac; /**< Buffer admission control */
+ bcmbal_tm_creation_mode creation_mode; /**< Creation mode */
+ uint8_t ref_count; /**< reference count (flows) */
+} bcmbal_tm_queue_cfg_data;
+
+/** Transport message definition for "cfg" group of "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_tm_queue_key key; /**< Object key. */
+ bcmbal_tm_queue_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_tm_queue_cfg;
+
+/** Structure definition for the "stat" group of the "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_stat_data
+{
+ uint64_t packets_ok; /**< Packets transmitted succewssfully */
+ uint64_t bytes_ok; /**< Bytes transmitted successfully */
+ uint64_t packets_discarded; /**< Packets discarded */
+ uint64_t bytes_discarded; /**< Bytes discarded */
+} bcmbal_tm_queue_stat_data;
+
+/** Transport message definition for "stat" group of "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_stat
+{
+ bcmbal_stat hdr; /**< Transport header. */
+ bcmbal_tm_queue_key key; /**< Object key. */
+ bcmbal_tm_queue_stat_data data; /**< All properties that must be set by the user. */
+} bcmbal_tm_queue_stat;
+
+/** Structure definition for the "ind" group of the "tm_queue" object.
+ *
+ * Tm Queue Indication
+ */
+typedef struct bcmbal_tm_queue_ind_data
+{
+ uint32_t ret; /**< ret */
+} bcmbal_tm_queue_ind_data;
+
+/** Transport message definition for "ind" group of "tm_queue" object.
+ */
+typedef struct bcmbal_tm_queue_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_tm_queue_key key; /**< Object key. */
+ bcmbal_tm_queue_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_tm_queue_ind;
+
+/** Structure definition for the "key" group of the "tm_sched" object.
+ */
+typedef struct bcmbal_tm_sched_key
+{
+ bcmbal_tm_sched_dir dir; /**< Traffic direction */
+ bcmbal_tm_sched_id id; /**< ID */
+} bcmbal_tm_sched_key;
+
+/** Structure definition for the "cfg" group of the "tm_sched" object.
+ */
+typedef struct bcmbal_tm_sched_cfg_data
+{
+ bcmbal_tm_sched_owner owner; /**< owner. */
+ bcmbal_tm_sched_type sched_type; /**< Scheduler type */
+ bcmbal_tm_sched_parent sched_parent; /**< Scheduling parameters for parent scheduler */
+ bcmbal_tm_sched_child_type sched_child_type; /**< Scheduling level for children tm */
+ bcmbal_tm_shaping rate; /**< Rate shaping parameters */
+ bcmbal_tm_tcont_sla tcont_sla; /**< Additional SLA parameters for agg_port owner */
+ bcmbal_tm_creation_mode creation_mode; /**< Creation mode */
+ bcmbal_tm_queue_id_list_u8 queues; /**< Subsidiary queues */
+ bcmbal_tm_sched_id_list_u8 sub_scheds; /**< Subsidiary schedulers */
+ uint8_t num_priorities; /**< Max number of strict priority scheduling elements */
+} bcmbal_tm_sched_cfg_data;
+
+/** Transport message definition for "cfg" group of "tm_sched" object.
+ */
+typedef struct bcmbal_tm_sched_cfg
+{
+ bcmbal_cfg hdr; /**< Transport header. */
+ bcmbal_tm_sched_key key; /**< Object key. */
+ bcmbal_tm_sched_cfg_data data; /**< All properties that must be set by the user. */
+} bcmbal_tm_sched_cfg;
+
+/** Structure definition for the "ind" group of the "tm_sched" object.
+ *
+ * Tm Sched Indication
+ */
+typedef struct bcmbal_tm_sched_ind_data
+{
+ uint32_t ret; /**< ret */
+} bcmbal_tm_sched_ind_data;
+
+/** Transport message definition for "ind" group of "tm_sched" object.
+ */
+typedef struct bcmbal_tm_sched_ind
+{
+ bcmbal_auto hdr; /**< Transport header. */
+ bcmbal_tm_sched_key key; /**< Object key. */
+ bcmbal_tm_sched_ind_data data; /**< All properties that must be set by the user. */
+} bcmbal_tm_sched_ind;
+
+/** @} */
+#endif /* BAL_MODEL_TYPES */
diff --git a/bal_release/src/common/include/bal_msg.h b/bal_release/src/common/include/bal_msg.h
new file mode 100644
index 0000000..4ea85c5
--- /dev/null
+++ b/bal_release/src/common/include/bal_msg.h
@@ -0,0 +1,349 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/* Define the top level Doxygen groups. */
+
+/**
+ * @defgroup core BAL Core Engine
+ *
+ * @defgroup apps BAL Utils
+ *
+ * @defgroup lib BAL Libraries
+ *
+ */
+
+/**
+ * @file bal_msg.h
+ *
+ * @brief Include files and miscellaneous macros for the BAL messaging
+ *
+ */
+
+#ifndef BALMSG_H
+#define BALMSG_H
+
+#include <bal_objs.h>
+#include <bal_msg_type.h>
+
+
+/*******************************************************************
+ **
+ ** BAL message header helpers
+ **
+ *******************************************************************
+ */
+
+/*
+ * Underlying msg_send timeout units in uS (micro seconds)
+ */
+#define BCMBAL_MSG_TIMEOUT_1_SEC (1000000)
+
+/*
+ * Get a pointer to the message payload given the bcmos_msg pointer
+ */
+static inline void *bcmbal_payload_ptr_get(bal_comm_msg_hdr *_m)
+{
+ /* payload starts from BAL communication header */
+ return (void *)_m;
+}
+
+/*
+ * Get a pointer to the BAL header given the message payload pointer
+ */
+static inline bal_comm_msg_hdr *bcmbal_bal_hdr_get(void *_msg_payload_ptr)
+{
+ /* payload starts from BAL communication header */
+ return (bal_comm_msg_hdr *)_msg_payload_ptr;
+}
+
+/*
+ * Get a pointer to the BAL header given the bcmos header pointer
+ */
+static inline bal_comm_msg_hdr *bcmbal_bal_hdr_get_by_bcmos_hdr(bcmos_msg *m)
+{
+ return container_of(m, bal_comm_msg_hdr, m);
+}
+
+/*
+ * Get a pointer to the BCMOS header given the message payload pointer
+ */
+static inline bcmos_msg *bcmbal_bcmos_hdr_get(void *_msg_payload_ptr)
+{
+ return &(bcmbal_bal_hdr_get(_msg_payload_ptr)->m);
+}
+
+/*
+ * Set the BAL header parameters given the message payload pointer
+ */
+static inline void bcmbal_msg_hdr_set(void *_msg_payload_ptr,
+ bcmos_msg_id _type_major,
+ bcmbal_msg_type _type_minor,
+ bal_subsystem _sender_subsys,
+ bcmbal_obj_id _msg_id_obj,
+ uint16_t _msg_id_oper,
+ uint32_t _ex_id)
+{
+ bcmos_msg *os_msg = bcmbal_bcmos_hdr_get(_msg_payload_ptr);
+ bal_comm_msg_hdr *bal_hdr = bcmbal_bal_hdr_get(_msg_payload_ptr);
+
+ /*
+ * set up the bcmos_msg header fields
+ */
+ os_msg->data = (void *)((char *)(bcmbal_bcmos_hdr_get(_msg_payload_ptr)) + sizeof(bcmos_msg));
+ os_msg->start = os_msg->data;
+ os_msg->type = _type_major;
+ os_msg->instance = 0;
+ os_msg->sender = BCMOS_MODULE_ID_NONE; /* doesn't matter */
+
+ /*
+ * set up the bal msg header fields
+ */
+ bal_hdr->version_major = BAL_HDR_VERSION_MAJOR;
+ bal_hdr->version_minor = BAL_HDR_VERSION_MINOR;
+ bal_hdr->msg_type = _type_minor;
+ bal_hdr->msg_id = ((bal_hdr->msg_id & 0x0000FFFF) | ((_msg_id_oper & 0x0000FFFF) << 16));
+ bal_hdr->msg_id = ((bal_hdr->msg_id & 0xFFFF0000) | (_msg_id_obj & 0x0000FFFF));
+ bal_hdr->ex_id = _ex_id;
+ bal_hdr->sender = _sender_subsys;
+ bal_hdr->timestamp = bcmos_timestamp();
+}
+
+/*
+ * Get the sender field in the BAL header given the message pointer
+ */
+static inline bal_subsystem bcmbal_sender_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->sender;
+}
+
+/*
+ * Set the sender field in the BAL header given the message pointer
+ */
+static inline void bcmbal_sender_set(void *_msg_payload_ptr, bal_subsystem _sender_subsys)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->sender = _sender_subsys;
+}
+
+/*
+ * Get the top level type field in the BAL header given the message pointer
+ */
+static inline bcmos_msg_id bcmbal_type_major_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bcmos_hdr_get(_msg_payload_ptr)->type;
+}
+
+/*
+ * Set the top level type field in the BAL header given the message pointer
+ */
+static inline void bcmbal_type_major_set(void *_msg_payload_ptr, bcmos_msg_id _type_major)
+{
+ bcmbal_bcmos_hdr_get(_msg_payload_ptr)->type = _type_major;
+}
+
+/*
+ * Get the inner type field in the BAL header given the message pointer
+ */
+static inline bcmbal_msg_type bcmbal_type_minor_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_type;
+}
+
+/*
+ * Set the inner type field in the BAL header given the message pointer
+ */
+static inline void bcmbal_type_minor_set(void *_msg_payload_ptr, bcmbal_msg_type _type_minor)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_type = _type_minor;
+}
+
+
+/*
+ * Get the msg_id_oper field in the BAL header given the message pointer
+ */
+static inline uint16_t bcmbal_msg_id_oper_get(void *_msg_payload_ptr)
+{
+ return ((bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id & 0xFFFF0000) >> 16);
+}
+
+/*
+ * Set the msg_id_oper field in the BAL header given the message pointer
+ */
+static inline void bcmbal_msg_id_oper_set(void *_msg_payload_ptr, uint16_t _msg_id_oper)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id =
+ ((bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id & 0x0000FFFF) | ((_msg_id_oper & 0x0000FFFF) << 16));
+}
+
+/*
+ * Get the msg_id_obj field in the BAL header given the message pointer
+ */
+static inline bcmbal_obj_id bcmbal_msg_id_obj_get(void *_msg_payload_ptr)
+{
+ return (bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id & 0x0000FFFF );
+}
+
+/*
+ * Set the msg_id_obj field in the BAL header given the message pointer
+ */
+static inline void bcmbal_msg_id_obj_set(void *_msg_payload_ptr, bcmbal_obj_id _msg_id_obj)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id =
+ ((bcmbal_bal_hdr_get(_msg_payload_ptr)->msg_id & 0xFFFF0000) | (_msg_id_obj & 0x0000FFFF));
+}
+
+/*
+ * Get the ex_id field in the BAL header given the message pointer
+ */
+static inline uint32_t bcmbal_ex_id_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->ex_id;
+}
+
+/*
+ * Set the ex_id field in the BAL header given the message pointer
+ */
+static inline void bcmbal_ex_id_set(void *_msg_payload_ptr, uint32_t _ex_id)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->ex_id = _ex_id;
+}
+
+/*
+ * Get the major version field in the BAL header given the message pointer
+ */
+static inline uint16_t bcmbal_major_version_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->version_major;
+}
+
+/*
+ * Set the major version field in the BAL header given the message pointer
+ */
+static inline void bcmbal_major_version_set(void *_msg_payload_ptr, uint16_t _version_major)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->version_major = _version_major;
+}
+
+/*
+ * Get the minor version field in the BAL header given the message pointer
+ */
+static inline uint16_t bcmbal_minor_version_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->version_minor;
+}
+
+/*
+ * Set the minor version field in the BAL header given the message pointer
+ */
+static inline void bcmbal_minor_version_set(void *_msg_payload_ptr, uint16_t _version_major)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->version_major = _version_major;
+}
+
+/*
+ * Get the scratchpad field in the BAL header given the message pointer
+ */
+static inline void *bcmbal_scratchpad_get(void *_msg_payload_ptr)
+{
+ return bcmbal_bal_hdr_get(_msg_payload_ptr)->scratchpad;
+}
+
+/*
+ * Set the scratchpad field in the BAL header given the message pointer
+ */
+static inline void bcmbal_scratchpad_set(void *_msg_payload_ptr, void *_scratchpad)
+{
+ bcmbal_bal_hdr_get(_msg_payload_ptr)->scratchpad = _scratchpad;
+}
+
+/*
+ * Allocate a BAL message given the payload pointer
+ */
+static inline void *bcmbal_msg_calloc(uint32_t _msg_payload_size)
+{
+ /* Payload includes comm header */
+ bal_comm_msg_hdr *m = bcmos_calloc(_msg_payload_size);
+ if (NULL == m)
+ return NULL;
+ return bcmbal_payload_ptr_get(m);
+}
+
+/*
+ * Free a BAL message given the payload pointer
+ */
+static inline void bcmbal_msg_free(void *msg)
+{
+ return bcmos_msg_free(bcmbal_bcmos_hdr_get(msg));
+}
+
+/*
+ * External functions implemented in bal_msg.c
+ */
+
+/*
+ * Clone BAL message
+ * Returns payload_ptr of the clone
+ */
+void *bcmbal_msg_clone(void *bal_obj);
+
+/*
+ * Send a BAL message given the payload pointer
+ */
+bcmos_errno bcmbal_msg_send(bcmos_msg_queue *queue, void *msg_payload, bcmos_msg_send_flags flags);
+
+/*
+ * Call callback in the context of the target module and pass it the BAL message pointer
+ */
+bcmos_errno bcmbal_msg_call(void *msg_payload, bcmos_module_id module, F_bcmos_msg_handler cb, bcmos_msg_send_flags flags);
+
+/*
+ * Receive a BAL message given the payload pointer
+ *
+ * NOTE: The timeout argument is in units of uS (micro seconds). Use the #defined timeout values above.
+ *
+ */
+bcmos_errno bcmbal_msg_recv(bcmos_msg_queue *queue, uint32_t timeout, void **msg_payload);
+
+/** Get packed bal_comm_msg_hdr length */
+int32_t bcmbal_bal_msg_hdr_get_packed_length(void);
+
+/** Pack a BAL message header to a byte stream */
+bcmos_errno bcmbal_bal_msg_hdr_pack(const bal_comm_msg_hdr *msg, bcmbal_buf *buf);
+
+/** Unpack a BAL message header from a byte stream */
+bcmos_errno bcmbal_bal_msg_hdr_unpack(bal_comm_msg_hdr *msg, bcmbal_buf *buf);
+
+/** Peek exchange_id in the received message without unpacking */
+bcmos_errno bcmbal_bal_msg_peek_ex_id(bcmos_msg *msg, uint32_t *ex_id);
+
+#endif /* #ifndef BALMSG_H */
+
+
+
diff --git a/bal_release/src/common/include/bal_msg_type.h b/bal_release/src/common/include/bal_msg_type.h
new file mode 100644
index 0000000..38e98c6
--- /dev/null
+++ b/bal_release/src/common/include/bal_msg_type.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef _BAL_MSG_TYPE_H_
+#define _BAL_MSG_TYPE_H_
+
+/*
+ * * The BAL message subtype
+ * */
+typedef enum
+{
+ BAL_MSG_TYPE_REQ,
+ BAL_MSG_TYPE_RSP,
+ BAL_MSG_TYPE_ACK,
+ BAL_MSG_TYPE_IND, /**< An INDication message generated as a part of a protocol exchange */
+ BAL_MSG_TYPE_AUTO_IND, /**< An asynchronous autonomous INDication message */
+} bcmbal_msg_type;
+
+static __attribute__ ((unused)) char *bcmbal_msg_t_str[] =
+{
+ "BAL_MSG_REQ",
+ "BAL_MSG_RSP",
+ "BAL_MSG_ACK",
+ "BAL_MSG_IND", /**< An INDication message generated as a part of a protocol exchange */
+ "BAL_MSG_AUTO_IND" /**< An asynchronous autonomous INDication message */
+};
+
+
+#endif
diff --git a/bal_release/src/common/include/bal_obj.h b/bal_release/src/common/include/bal_obj.h
new file mode 100644
index 0000000..24e8ec2
--- /dev/null
+++ b/bal_release/src/common/include/bal_obj.h
@@ -0,0 +1,205 @@
+#ifndef BAL_OBJ
+#define BAL_OBJ
+
+#include <bcmos_system.h>
+#include <bcmos_errno.h>
+#include "bal_model_ids.h"
+#include "bal_buf.h"
+#include "bal_msg_type.h"
+
+/*
+ * The current BAL header version
+ */
+#define BAL_HDR_VERSION_MAJOR (1)
+#define BAL_HDR_VERSION_MINOR (1)
+
+/*
+ * The BAL common message header
+ */
+typedef struct bal_comm_msg_hdr
+{
+ bcmos_msg m; /**< bcmos message header */
+ uint16_t version_major; /**< Header Major version number */
+ uint16_t version_minor; /**< Header Minor version number */
+ bcmbal_msg_type msg_type; /**< Request / Response / Ack / Indication */
+ uint32_t msg_id; /**< Message ID – the ID of the message (subID under the message type) */
+ uint32_t ex_id; /**< Exchange ID for message tracking between endpoints */
+ bal_subsystem sender; /**< Sender subsystem - used for additional validation */
+ uint32_t timestamp; /**< Timestamp when the message was sent */
+ bcmos_sem sem; /**< Semaphore used for inter-thread communication */
+ void* scratchpad; /**< Scratchpad used for inter-thread communication */
+ uint8_t payload[]; /**< Payload follows the header */
+} bal_comm_msg_hdr;
+
+/** Version of Object definitions */
+#define BCMBAL_OBJ_VERSION 2 /**< The current version number */
+typedef uint32_t bcmbal_object_ver; /**< The attribute type in the object info structure */
+
+/** Bitmask of object attributes that are specified in an object (1 = specified, 0 = not specified) */
+typedef uint64_t bcmbal_presence_mask;
+
+/** Presence mask indicating all fields present */
+#define BCMBAL_PRESENCE_MASK_ALL ((bcmbal_presence_mask)0xFFFFFFFFFFFFFFFF)
+
+/** Helper type to determine what the data format of a message should look like */
+typedef enum bcmbal_mgt_group
+{
+ BCMBAL_MGT_GROUP_KEY, /**< Key that uniquely identifies object instance */
+ BCMBAL_MGT_GROUP_CFG, /**< Configuration (get/set/clear) */
+ BCMBAL_MGT_GROUP_STAT, /**< Statistics */
+ BCMBAL_MGT_GROUP_AUTO, /**< Autonomous indications */
+ BCMBAL_MGT_GROUP_AUTO_CFG, /**< Autonomous indication configuration */
+ BCMBAL_MGT_GROUP__NUM_OF
+} bcmbal_mgt_group;
+
+/** Object message type. Can be a combination of flags. */
+typedef enum bcmbal_obj_msg_type
+{
+ BCMBAL_OBJ_MSG_TYPE_GET = 0x01, /**< Get configuration parameters */
+ BCMBAL_OBJ_MSG_TYPE_SET = 0x02, /**< Set configuration parameters */
+ BCMBAL_OBJ_MSG_TYPE_CLEAR = 0x04, /**< Clear configuration parameters */
+} bcmbal_obj_msg_type;
+
+/** Object message direction - request or response. */
+typedef enum bcmbal_obj_msg_dir
+{
+ BCMBAL_OBJ_MSG_DIR_REQUEST,
+ BCMBAL_OBJ_MSG_DIR_RESPONSE
+} bcmbal_obj_msg_dir;
+
+#define BCMBAL_OBJ_INIT_VAL 0xdeadbeef /**< The value of the obj_init_val after macro initialization */
+
+/** Information common to all BAL objects */
+typedef struct bcmbal_obj
+{
+ bal_comm_msg_hdr comm_hdr; /**< Communication header */
+ bcmbal_object_ver version; /**< Version of the Object definition/structure */
+ bcmbal_obj_id obj_type; /**< An enumerated ID associated with the object being specified */
+ bcmbal_mgt_group group; /**< Management group */
+ uint16_t subgroup; /**< Subgroup for indications */
+ bcmbal_obj_msg_type type; /**< Type (e.g. get / set / clear) */
+ bcmbal_obj_msg_dir dir; /**< Direction - request / response */
+ bcmos_errno status; /**< BAL status code (BCM_ERR_OK–success, error code otherwise) */
+ bcmbal_presence_mask presence_mask; /**< Indicates which attribute parameters are present */
+
+ /* The following fields are internal. They are not sent on the line */
+ bcmos_bool is_inprogress; /**< RO - When set to TRUE: Object is changing state internally */
+ void *list_buf; /**< Memory buffer in which to store variable-sized lists when unpacking */
+ uint32_t list_buf_size; /**< Number of bytes in the variable-sized list buffer */
+ uint32_t obj_init_val; /**< An field that is set on INIT macro call, and checked by the API */
+} bcmbal_obj;
+
+/** Information structure for use with BAL configuration API (get/set/clear) */
+typedef struct bcmbal_cfg
+{
+ bcmbal_obj hdr;
+} bcmbal_cfg;
+
+/** Information structure for BAL statistics API */
+typedef struct bcmbal_stat
+{
+ bcmbal_obj hdr;
+} bcmbal_stat;
+
+/** Information structure for BAL indications */
+typedef struct bcmbal_auto
+{
+ bcmbal_obj hdr;
+} bcmbal_auto;
+
+/** Information structure for BAL indication configuration API */
+typedef struct bcmbal_auto_cfg
+{
+ bcmbal_obj hdr;
+} bcmbal_auto_cfg;
+
+/** Whether we pack the entire structure of a message */
+static inline bcmos_bool bcmbal_obj_msg_should_pack_data(const bcmbal_obj *msg)
+{
+ switch (msg->group)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ case BCMBAL_MGT_GROUP_STAT:
+ case BCMBAL_MGT_GROUP_AUTO_CFG:
+ if ((msg->type & BCMBAL_OBJ_MSG_TYPE_GET))
+ {
+ return (msg->dir == BCMBAL_OBJ_MSG_DIR_RESPONSE);
+ }
+ else if ((msg->type & BCMBAL_OBJ_MSG_TYPE_SET))
+ {
+ return (msg->dir == BCMBAL_OBJ_MSG_DIR_REQUEST);
+ }
+ else
+ {
+ return BCMOS_FALSE;
+ }
+
+ default:
+ return BCMOS_TRUE;
+ }
+}
+
+/** Get the packed length of the header portion of an object message */
+static inline int32_t bcmbal_obj_msg_hdr_get_packed_length(void)
+{
+ return 24;
+}
+
+/** Pack a message header to a byte stream */
+static inline bcmos_errno bcmbal_obj_msg_hdr_pack(const bcmbal_obj *msg, bcmbal_buf *buf)
+{
+ bcmos_bool ret;
+
+ ret = bcmbal_buf_write_u32(buf, (uint32_t)msg->version);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint32_t)msg->obj_type);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->group);
+ ret = ret && bcmbal_buf_write_u16(buf, msg->subgroup);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->type);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->dir);
+ ret = ret && bcmbal_buf_write_s16(buf, (int16_t)msg->status);
+ ret = ret && bcmbal_buf_write_u32(buf, (int32_t)msg->is_inprogress);
+ ret = ret && bcmbal_buf_write_u64(buf, (uint64_t)msg->presence_mask);
+
+ return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
+}
+
+/** Unpack a message header from a byte stream */
+static inline bcmos_errno bcmbal_obj_msg_hdr_unpack(bcmbal_obj *msg, bcmbal_buf *buf)
+{
+ uint32_t version;
+ uint8_t obj_type;
+ uint8_t group;
+ uint16_t subgroup;
+ uint8_t type;
+ uint8_t dir;
+ int16_t status;
+ uint32_t is_inprogress;
+ uint64_t presence_mask;
+ bcmos_bool ret;
+
+ ret = bcmbal_buf_read_u32(buf, &version);
+ ret = ret && bcmbal_buf_read_u8(buf, &obj_type);
+ ret = ret && bcmbal_buf_read_u8(buf, &group);
+ ret = ret && bcmbal_buf_read_u16(buf, &subgroup);
+ ret = ret && bcmbal_buf_read_u8(buf, &type);
+ ret = ret && bcmbal_buf_read_u8(buf, &dir);
+ ret = ret && bcmbal_buf_read_s16(buf, &status);
+ ret = ret && bcmbal_buf_read_u32(buf, &is_inprogress);
+ ret = ret && bcmbal_buf_read_u64(buf, &presence_mask);
+ if (ret)
+ {
+ msg->version = (bcmbal_object_ver)version;
+ msg->obj_type = (bcmbal_obj_id)obj_type;
+ msg->group = (bcmbal_mgt_group)group;
+ msg->subgroup = subgroup;
+ msg->type = (bcmbal_obj_msg_type)type;
+ msg->dir = (bcmbal_obj_msg_dir)dir;
+ msg->status = (bcmos_errno)status;
+ msg->is_inprogress = (bcmos_bool)is_inprogress;
+ msg->presence_mask = (bcmbal_presence_mask)presence_mask;
+ }
+
+ return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
+}
+
+#endif /* BAL_OBJ */
diff --git a/bal_release/src/common/include/bal_objs.h b/bal_release/src/common/include/bal_objs.h
new file mode 100644
index 0000000..6a13cce
--- /dev/null
+++ b/bal_release/src/common/include/bal_objs.h
@@ -0,0 +1,985 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_objs.h
+ * @brief The file provides an enumeration of all BAL objects
+ *
+ */
+#ifndef BALOBJS_H
+#define BALOBJS_H
+
+#include <bcmolt_host_api.h>
+#include "bal_common.h"
+#include "bal_model_ids.h"
+#include "bal_model_types.h"
+
+/** \ingroup api
+ * @{
+ */
+
+static char *bal_obj_str[] =
+{
+ [bcmbal_obj_id_access_terminal] = "access_terminal object",
+ [bcmbal_obj_id_interface] = "interface object",
+ [bcmbal_obj_id_subscriber_terminal] = "subscriber_terminal object",
+ [bcmbal_obj_id_flow] = "flow object",
+ [bcmbal_obj_id_packet] = "packet object",
+ [bcmbal_obj_id_group] = "group object",
+ [bcmbal_obj_id_tm_sched] = "scheduler object",
+ [bcmbal_obj_id_tm_queue] = "queue object",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (BCMBAL_OBJ_ID__NUM_OF == (sizeof (bal_obj_str) / sizeof (char *)), bcmbal_obj_id);
+
+static inline char *bcmbal_objtype_str(bcmbal_obj_id obj)
+{
+ return (BCMBAL_OBJ_ID__NUM_OF >= obj) ? bal_obj_str[obj] : "unknown";
+}
+
+#define BCMBAL_FLOW_PRIORITY_MAX 65535
+#define BCMBAL_FLOW_PRIORITY_MIN 0
+#define BAL_FLOW_DEFAULT_PRIORITY 10
+
+/*
+ * ------------------------------------------------------------------
+ *
+ * Internal BCMBAL macros used to manipulate the BAL object elements
+ *
+ * ------------------------------------------------------------------
+ */
+
+/* Initialize request. Internal macro
+ * \ingroup api
+ * \param[in] _h Message header
+ * \param[in] _obj Object name (i.e. flow)
+ * \param[in] _grp message type
+ * \param[in] _subgrp message subgroup
+ */
+#define _BCMBAL_REQ_INIT(_h, _obj, _grp, _subgrp) \
+ (_h)->obj_init_val = BCMBAL_OBJ_INIT_VAL; \
+ (_h)->version = BCMBAL_OBJ_VERSION; \
+ (_h)->status = BCM_ERR_OK; \
+ (_h)->presence_mask = 0; \
+ (_h)->obj_type = bcmbal_obj_id_ ## _obj; \
+ (_h)->group = _grp; \
+ (_h)->subgroup = _subgrp;
+
+/** Initialize set structure
+ * \ingroup api
+ * \param[in] _s Set structure
+ * \param[in] _obj Object name (i.e. flow)
+ * \param[in] _key Object key
+ */
+#define BCMBAL_CFG_INIT(_s, _obj, _key) \
+ do { \
+ bcmbal_ ## _obj ## _cfg *_x_ = _s; \
+ memset(_x_, 0, sizeof(*_x_)); \
+ _BCMBAL_REQ_INIT(&((_x_)->hdr.hdr), _obj, BCMBAL_MGT_GROUP_CFG, 0); \
+ (_x_)->key = _key; \
+ } while (0)
+
+/** Initialize statistics structure
+ * \ingroup api
+ * \param[in] _s Statistics structure
+ * \param[in] _obj Object name (i.e. flow)
+ * \param[in] _key Object key
+ */
+#define BCMBAL_STAT_INIT(_s, _obj, _key) \
+ do { \
+ bcmbal_ ## _obj ## _stat *_x_ = _s; \
+ memset(_x_, 0, sizeof(*_x_)); \
+ _BCMBAL_REQ_INIT(&((_x_)->hdr.hdr), _obj, BCMBAL_MGT_GROUP_STAT, 0); \
+ (_x_)->key = _key; \
+ } while (0)
+
+/** Set the memory buffer to use for variable-sized lists within a cfg get
+ * \ingroup api
+ * \param[in] _s Configuration structure
+ * \param[in] _obj Object type
+ * \param[in] _buf Pointer to a location in memory in which to store the lists
+ * \param[in] _len Length of the buffer pointed to by _buf
+ */
+#define BCMBAL_CFG_LIST_BUF_SET(_s, _obj, _buf, _len) \
+ do { \
+ bcmbal_ ## _obj ## _cfg *_x_ = _s; \
+ _x_->hdr.hdr.list_buf = _buf; \
+ _x_->hdr.hdr.list_buf_size = _len; \
+ } while (0)
+
+/* Set the object progress state
+ * \ingroup api
+ * \param[in] _s Object structure
+ * \param[in] _p New object in-progress state: BCMOS_TRUE, or BCMOS_FALSE
+ */
+#define BCMBAL_OBJ_IN_PROGRESS_SET(_s, _p) ((_s)->hdr.hdr.is_inprogress = _p )
+
+/* Return the object progress state
+ * \ingroup api
+ * \param[in] _s Object structure
+ */
+#define BCMBAL_OBJ_IN_PROGRESS_GET(_s) ((_s)->hdr.hdr.is_inprogress)
+
+/* Internal macro: Get a bitmask given a property ID enum */
+#define BCMBAL_PROP_MASK_GET(_obj, _grp, _p) \
+ (bcmbal_ ## _obj ## _grp ## _id_ ## _p == bcmbal_ ## _obj ## _grp ## _id_all_properties ? \
+ ((1ULL << (uint64_t)bcmbal_ ## _obj ## _grp ## _id_ ## _p) - 1) : \
+ (1ULL << (uint64_t)bcmbal_ ## _obj ## _grp ## _id_ ## _p))
+
+
+/* Macro: Indicate that configuration property is present - USE WITH CAUTION */
+#define BCMBAL_PROP_SET_PRESENT(_m, _obj, _grp, _p) \
+ do { \
+ (_m)->hdr.hdr.presence_mask |= BCMBAL_PROP_MASK_GET(_obj, _grp, _p); \
+ } while (0)
+
+/* Internal macro: Indicate that configuration property is not present */
+#define BCMBAL_PROP_CLEAR_PRESENT(_m, _obj, _grp, _p) \
+ do { \
+ (_m)->hdr.hdr.presence_mask &= ~(BCMBAL_PROP_MASK_GET(_obj, _grp, _p));\
+ } while (0)
+
+/* Internal macro: check if property is present */
+#define _BCMBAL_PROP_IS_PRESENT(_m, _obj, _grp, _p) \
+ (((_m)->hdr.hdr.presence_mask & BCMBAL_PROP_MASK_GET(_obj, _grp, _p)) ? \
+ BCMOS_TRUE : BCMOS_FALSE)
+
+/** Set configuration property in message structure
+ * \ingroup api
+ * \param[in] _m Configuration structure
+ * \param[in] _obj Object type
+ * \param[in] _p Property name
+ * \param[in] _v Property value
+ */
+#define BCMBAL_CFG_PROP_SET(_m, _obj, _p, _v) \
+ do { \
+ BCMBAL_PROP_SET_PRESENT(_m, _obj, _cfg, _p);\
+ (_m)->data._p = (_v);\
+ } while (0)
+
+/** Indicate that configuration property should be read
+ * \ingroup api
+ * \param[in] _m Configuration structure
+ * \param[in] _obj Object type
+ * \param[in] _p Property name
+ */
+#define BCMBAL_CFG_PROP_GET(_m, _obj, _p) BCMBAL_PROP_SET_PRESENT(_m, _obj, _cfg, _p)
+
+/** clear object property in message structure
+ * \ingroup api
+ * \param[in] _m Object structure pointer
+ * \param[in] _obj Object name (i.e. flow)
+ * \param[in] _p Attribute name (i.e. admin_state)
+ */
+#define BCMBAL_CFG_PROP_CLEAR(_m, _obj, _p) \
+ do { \
+ BCMBAL_PROP_CLEAR_PRESENT(_m, _obj, _cfg, _p); \
+ memset(&((_m)->data._p), 0, sizeof((_m)->data._p)); \
+ } while (0)
+
+/** Check if configuration property is set in message structure
+ * \ingroup api
+ * \param[in] _m Configuration structure
+ * \param[in] _obj Object type
+ * \param[in] _p Property name
+ */
+#define BCMBAL_CFG_PROP_IS_SET(_m, _obj, _p) _BCMBAL_PROP_IS_PRESENT(_m, _obj, _cfg, _p)
+
+/** Indicate that statistic property should be read
+ * \ingroup api
+ * \param[in] _m Configuration structure
+ * \param[in] _obj Object type
+ * \param[in] _p Property name
+ */
+#define BCMBAL_STAT_PROP_GET(_m, _obj, _p) BCMBAL_PROP_SET_PRESENT(_m, _obj, _stat, _p)
+
+/** Check if statistic property is set in message structure
+ * \ingroup api
+ * \param[in] _m Statistic structure
+ * \param[in] _obj Object type
+ * \param[in] _p Property name
+ */
+#define BCMBAL_STAT_PROP_IS_SET(_m, _obj, _p) _BCMBAL_PROP_IS_PRESENT(_m, _obj, _stat, _p)
+
+
+/***********************************************************************************
+ **
+ ** Macros for setting attribute values where an attribute supports a presence_mask
+ **
+ ***********************************************************************************
+ **/
+
+/* Internal macro: Get a bitmask given a attribute element property ID enum */
+#define BCMBAL_ATTRIBUTE_PROP_MASK_GET(_attr, _p) bcmbal_ ## _attr ## _id_ ## _p
+
+/* Internal macro: Indicate that configuration property is present */
+#define _BCMBAL_ATTRIBUTE_PROP_SET_PRESENT(p_attr, _attr,_p) \
+ do { \
+ (p_attr)->presence_mask |= BCMBAL_ATTRIBUTE_PROP_MASK_GET(_attr, _p); \
+ } while (0)
+
+/* Internal macro: Indicate that configuration property is not present */
+#define _BCMBAL_ATTRIBUTE_PROP_CLEAR_PRESENT(p_attr, _attr,_p) \
+ do { \
+ (p_attr)->presence_mask &= ~(BCMBAL_ATTRIBUTE_PROP_MASK_GET(_attr, _p)); \
+ } while (0)
+
+/** Set attribute element property in message structure
+ * \param[in] _p_attr Attribute structure pointer
+ * \param[in] _attr Attribute name
+ * \param[in] _p Element name (i.e. o_tpid)
+ * \param[in] _v Element value
+ */
+#define BCMBAL_ATTRIBUTE_PROP_SET(_p_attr, _attr, _p, _v) \
+ do { \
+ _BCMBAL_ATTRIBUTE_PROP_SET_PRESENT(_p_attr, _attr, _p); \
+ (_p_attr)->_p = (_v); \
+ } while (0)
+
+/** Clear attribute element property in message structure
+ * \param[in] _p_attr Attribute structure pointer
+ * \param[in] _attr Attribute name
+ * \param[in] _p Element name (i.e. o_tpid)
+ */
+#define BCMBAL_ATTRIBUTE_PROP_CLEAR(_p_attr, _attr, _p) \
+ do { \
+ _BCMBAL_ATTRIBUTE_PROP_CLEAR_PRESENT(_p_attr, _attr, _p); \
+ memset(&((_p_attr)->_p), 0, sizeof((_p_attr)->_p)); \
+ } while (0)
+
+
+/* Internal macro: check if an attribute element is present */
+#define _BCMBAL_ATTRIBUTE_PROP_IS_PRESENT(_p_attr, _attr, _p) \
+ (((_p_attr)->presence_mask & BCMBAL_ATTRIBUTE_PROP_MASK_GET(_attr, _p)) ? \
+ BCMOS_TRUE : BCMOS_FALSE)
+
+/** Check if attribute element property is set in message structure
+ * \param[in] _p_attr Attribute structure pointer
+ * \param[in] _attr Attribute name
+ * \param[in] _p Element name (i.e. o_tpid)
+ */
+#define BCMBAL_ATTRIBUTE_PROP_IS_SET(_p_attr, _attr, _p) _BCMBAL_ATTRIBUTE_PROP_IS_PRESENT(_p_attr, _attr, _p)
+
+
+/*
+ * ------------------------------------------------------------------
+ *
+ * Internal BCMBAL macros used to manipulate cmds_bitmask of action parameters
+ *
+ * ------------------------------------------------------------------
+ */
+
+/** Check if action cmd id is set in action structure
+ * \param[in] _m Object structure pointer
+ * \param[in] _b cmd Id bitmask
+ */
+#define BCMBAL_ACTION_CMD_ID_IS_SET(_m, _b) \
+ (((_m)->cmds_bitmask & (_b)) ? \
+ BCMOS_TRUE : BCMOS_FALSE)
+
+/** Set action cmd id in action structure
+ * \param[in] _m Object structure pointer
+ * \param[in] _b cmd Id bitmask
+ */
+#define BCMBAL_ACTION_CMD_ID_SET(_m, _b) \
+ do { \
+ (_m)->cmds_bitmask |= (_b);\
+ } while (0)
+
+
+/** Clear action cmd id in action structure
+ * \param[in] _m Object structure pointer
+ * \param[in] _b cmd Id bitmask
+ */
+#define BCMBAL_ACTION_CMD_ID_CLEAR(_m, _b) \
+ do { \
+ (_m)->cmds_bitmask &= ~(_b);\
+ } while (0)
+
+
+
+static inline void bcmbal_flow_object_overlay_w_src_priority(bcmbal_flow_cfg *dstobj, bcmbal_flow_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, admin_state))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, admin_state, srcobj->data.admin_state);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, access_int_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, access_int_id, srcobj->data.access_int_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, network_int_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, network_int_id, srcobj->data.network_int_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, sub_term_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, sub_term_id, srcobj->data.sub_term_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, svc_port_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, svc_port_id, srcobj->data.svc_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, agg_port_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, agg_port_id, srcobj->data.agg_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, resolve_mac))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, resolve_mac, srcobj->data.resolve_mac);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, queue))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, queue, srcobj->data.queue);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, action))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, action, srcobj->data.action);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, classifier))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, classifier, srcobj->data.classifier);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, sla))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, sla, srcobj->data.sla);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, group_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, group_id, srcobj->data.group_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, cookie))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, flow, cookie, srcobj->data.cookie);
+ }
+}
+
+static inline void bcmbal_flow_object_overlay_w_dst_priority(bcmbal_flow_cfg *dstobj, bcmbal_flow_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety,
+ * except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source and are not already set in the dst object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, admin_state))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, admin_state))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, admin_state, srcobj->data.admin_state);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, access_int_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, access_int_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, access_int_id, srcobj->data.access_int_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, network_int_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, network_int_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, network_int_id, srcobj->data.network_int_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, sub_term_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, sub_term_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, sub_term_id, srcobj->data.sub_term_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, svc_port_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, svc_port_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, svc_port_id, srcobj->data.svc_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, agg_port_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, agg_port_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, agg_port_id, srcobj->data.agg_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, resolve_mac))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, resolve_mac))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, resolve_mac, srcobj->data.resolve_mac);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, queue))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, queue))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, queue, srcobj->data.queue);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, action))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, action))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, action, srcobj->data.action);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, classifier))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, classifier))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, classifier, srcobj->data.classifier);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, sla))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, sla))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, sla, srcobj->data.sla);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, group_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, group_id))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, group_id, srcobj->data.group_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, flow, cookie))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, flow, cookie))
+ BCMBAL_CFG_PROP_SET(dstobj, flow, cookie, srcobj->data.cookie);
+ }
+}
+
+static inline void bcmbal_sub_term_object_overlay_w_src_priority(bcmbal_subscriber_terminal_cfg *dstobj,
+ bcmbal_subscriber_terminal_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, admin_state))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, admin_state, srcobj->data.admin_state);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, serial_number))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, serial_number, srcobj->data.serial_number);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, password))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, password, srcobj->data.password);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, registration_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, registration_id, srcobj->data.registration_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, svc_port_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, svc_port_id, srcobj->data.svc_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, ds_tm))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, ds_tm, srcobj->data.ds_tm);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, us_tm))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, us_tm, srcobj->data.us_tm);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, mac_address))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, mac_address, srcobj->data.mac_address);
+ }
+}
+
+static inline void bcmbal_sub_term_object_overlay_w_dst_priority(bcmbal_subscriber_terminal_cfg *dstobj,
+ bcmbal_subscriber_terminal_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, admin_state))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, admin_state))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, admin_state, srcobj->data.admin_state);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, serial_number))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, serial_number))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, serial_number, srcobj->data.serial_number);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, password))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, password))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, password, srcobj->data.password);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, registration_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, registration_id))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, registration_id, srcobj->data.registration_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, svc_port_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, svc_port_id))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, svc_port_id, srcobj->data.svc_port_id);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, ds_tm))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, ds_tm))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, ds_tm, srcobj->data.ds_tm);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, us_tm))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, us_tm))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, us_tm, srcobj->data.us_tm);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, subscriber_terminal, mac_address))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, subscriber_terminal, mac_address))
+ BCMBAL_CFG_PROP_SET(dstobj, subscriber_terminal, mac_address, srcobj->data.mac_address);
+ }
+}
+
+static inline void bcmbal_tm_sched_object_overlay_w_src_priority(bcmbal_tm_sched_cfg *dstobj, bcmbal_tm_sched_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, owner))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, owner, srcobj->data.owner);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_type))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_type, srcobj->data.sched_type);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_parent))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_parent, srcobj->data.sched_parent);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_child_type))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_child_type, srcobj->data.sched_child_type);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, rate))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, rate, srcobj->data.rate);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, tcont_sla))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, tcont_sla, srcobj->data.tcont_sla);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, creation_mode))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, creation_mode, srcobj->data.creation_mode);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, num_priorities))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, num_priorities, srcobj->data.num_priorities);
+ }
+
+}
+
+
+
+static inline void bcmbal_tm_sched_object_overlay_w_dst_priority(bcmbal_tm_sched_cfg *dstobj, bcmbal_tm_sched_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety,
+ * except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source and are not already set in the dst object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, owner))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, owner))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, owner, srcobj->data.owner);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_type))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, sched_type))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_type, srcobj->data.sched_type);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_parent))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, sched_parent))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_parent, srcobj->data.sched_parent);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, sched_child_type))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, sched_child_type))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, sched_child_type, srcobj->data.sched_child_type);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, rate))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, rate))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, rate, srcobj->data.rate);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, tcont_sla))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, tcont_sla))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, tcont_sla, srcobj->data.tcont_sla);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_sched, creation_mode))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, tm_sched, creation_mode))
+ BCMBAL_CFG_PROP_SET(dstobj, tm_sched, creation_mode, srcobj->data.creation_mode);
+ }
+
+}
+
+
+static inline void bcmbal_tm_queue_object_overlay(bcmbal_tm_queue_cfg *dstobj, bcmbal_tm_queue_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_queue, priority))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_queue, priority, srcobj->data.priority);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_queue, weight))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_queue, weight, srcobj->data.weight);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_queue, rate))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_queue, rate, srcobj->data.rate);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, tm_queue, bac))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, tm_queue, bac, srcobj->data.bac);
+ }
+}
+
+static inline bcmos_errno bal_obj_key_str_get(bcmbal_obj *obj, char *p_obj_key_str)
+{
+ BUG_ON(NULL == p_obj_key_str);
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ switch (obj->obj_type)
+ {
+
+ case (BCMBAL_OBJ_ID_ACCESS_TERMINAL):
+ {
+ sprintf(p_obj_key_str, "unit:%d",
+ ((bcmbal_access_terminal_cfg *)obj)->key.access_term_id);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_INTERFACE):
+ {
+ sprintf(p_obj_key_str, "intf_id:%d, type:%s",
+ ((bcmbal_interface_cfg *)obj)->key.intf_id,
+ ((bcmbal_interface_cfg *)obj)->key.intf_type == BCMBAL_INTF_TYPE_NNI ? "NNI" :
+ ((bcmbal_interface_cfg *)obj)->key.intf_type == BCMBAL_INTF_TYPE_PON ? "PON" :
+ "???"
+ );
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL):
+ {
+ sprintf(p_obj_key_str, "sub_term_id:%d, intf_id:%d",
+ ((bcmbal_subscriber_terminal_cfg *)obj)->key.sub_term_id,
+ ((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_FLOW):
+ {
+ sprintf(p_obj_key_str, "flow_id:%d, type:%s",
+ ((bcmbal_flow_cfg *)obj)->key.flow_id,
+ ((bcmbal_flow_cfg *)obj)->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "upstream" :
+ ((bcmbal_flow_cfg *)obj)->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM ? "downstream" :
+ ((bcmbal_flow_cfg *)obj)->key.flow_type == BCMBAL_FLOW_TYPE_BROADCAST ? "broadcast" :
+ ((bcmbal_flow_cfg *)obj)->key.flow_type == BCMBAL_FLOW_TYPE_MULTICAST ? "multicast" :
+ "???"
+ );
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_GROUP):
+ {
+ sprintf(p_obj_key_str, "group_id:%d",
+ ((bcmbal_group_cfg *)obj)->key.group_id);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_TM_SCHED):
+ {
+ sprintf(p_obj_key_str, "dir:%s, id:%d",
+ ((bcmbal_tm_sched_cfg *)obj)->key.dir == BCMBAL_TM_SCHED_DIR_US ? "upstream" :
+ ((bcmbal_tm_sched_cfg *)obj)->key.dir == BCMBAL_TM_SCHED_DIR_DS ? "downstream" :
+ "???",
+ ((bcmbal_tm_sched_cfg *)obj)->key.id
+ );
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_TM_QUEUE):
+ {
+ sprintf(p_obj_key_str, "sched_id:%d, sched_dir:%s, id:%d",
+ ((bcmbal_tm_queue_cfg *)obj)->key.sched_id,
+ ((bcmbal_tm_queue_cfg *)obj)->key.sched_dir == BCMBAL_TM_SCHED_DIR_US ? "upstream" :
+ ((bcmbal_tm_queue_cfg *)obj)->key.sched_dir == BCMBAL_TM_SCHED_DIR_DS ? "downstream" :
+ "???",
+ ((bcmbal_tm_queue_cfg *)obj)->key.id
+ );
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_PACKET):
+ {
+ sprintf(p_obj_key_str, " ");
+ break;
+ }
+
+ default:
+ sprintf(p_obj_key_str, " ");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ return ret;
+}
+
+static inline void bcmbal_interface_object_overlay_w_dst_priority(bcmbal_interface_cfg *dstobj, bcmbal_interface_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety,
+ * except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source and are not already set in the dst object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, admin_state))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, admin_state))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, admin_state, srcobj->data.admin_state);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, min_data_agg_port_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, min_data_agg_port_id))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, min_data_agg_port_id, srcobj->data.min_data_agg_port_id);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, min_data_svc_port_id))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, min_data_svc_port_id))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, min_data_svc_port_id, srcobj->data.min_data_svc_port_id);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, transceiver_type))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, transceiver_type))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, transceiver_type, srcobj->data.transceiver_type);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, ds_miss_mode))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, ds_miss_mode))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, ds_miss_mode, srcobj->data.ds_miss_mode);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, mtu))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, mtu))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, mtu, srcobj->data.mtu);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, flow_control))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, flow_control))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, flow_control, srcobj->data.flow_control);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, ds_tm))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, ds_tm))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, ds_tm, srcobj->data.ds_tm);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, us_tm))
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(dstobj, interface, us_tm))
+ BCMBAL_CFG_PROP_SET(dstobj, interface, us_tm, srcobj->data.us_tm);
+ }
+}
+
+
+static inline void bcmbal_interface_object_overlay_w_src_priority(bcmbal_interface_cfg *dstobj,
+ bcmbal_interface_cfg *srcobj)
+{
+ BUG_ON(NULL == dstobj);
+ BUG_ON(NULL == srcobj);
+
+ bcmbal_presence_mask dest_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ dest_presence_mask = dstobj->hdr.hdr.presence_mask;
+ dstobj->hdr = srcobj->hdr;
+ dstobj->key = srcobj->key;
+ dstobj->hdr.hdr.presence_mask = dest_presence_mask;
+
+ /* Now copy only the fields that have been specified in the source object */
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, admin_state))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, admin_state, srcobj->data.admin_state);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, min_data_agg_port_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, min_data_agg_port_id, srcobj->data.min_data_agg_port_id);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, min_data_svc_port_id))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, min_data_svc_port_id, srcobj->data.min_data_svc_port_id);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, transceiver_type))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, transceiver_type, srcobj->data.transceiver_type);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, ds_miss_mode))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, ds_miss_mode, srcobj->data.ds_miss_mode);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, mtu))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, mtu, srcobj->data.mtu);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, flow_control))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, flow_control, srcobj->data.flow_control);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, ds_tm))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, ds_tm, srcobj->data.ds_tm);
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(srcobj, interface, us_tm))
+ {
+ BCMBAL_CFG_PROP_SET(dstobj, interface, us_tm, srcobj->data.us_tm);
+ }
+
+}
+/*@}*/
+
+
+#endif /* BALOBJS_H */
diff --git a/bal_release/src/common/include/bal_osmsg.h b/bal_release/src/common/include/bal_osmsg.h
new file mode 100644
index 0000000..e5caf85
--- /dev/null
+++ b/bal_release/src/common/include/bal_osmsg.h
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_osmsg.h
+ * @brief BAL Message data structure definitions
+ *
+ */
+#ifndef BAL_OSMSG_H_
+#define BAL_OSMSG_H_
+/*
+ * Message structures.
+ * Going to be generated from object model and moved elsewhere
+ */
+
+/* BAL subsystem */
+typedef enum
+{
+ BAL_SUBSYSTEM_CORE,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BAL_SUBSYSTEM_SWITCH_UTIL,
+ BAL_SUBSYSTEM_PUBLIC_API,
+
+ BAL_SUBSYSTEM__NUM_OF
+} bal_subsystem;
+
+
+__attribute__ ((unused)) static const char *subsystem_str[] =
+{
+ "BAL Core",
+ "BAL Mac Util",
+ "BAL Switch Util",
+ "BAL Public API"
+};
+
+/** BAL OS message
+ * \ingroup system_msg
+ */
+typedef enum
+{
+ BCMOS_MSG_ID__BEGIN,
+
+ /* Messages used internally by OS abstraction. Do not touch */
+ BCMOS_MSG_ID_INTERNAL_TIMER, /**< Internal "timer message" type */
+ BCMOS_MSG_ID_INTERNAL_EVENT, /**< Internal "event message" type */
+ BCMOS_MSG_ID_INTERNAL_IPC,
+
+ /* Application messages */
+ BCMOS_MSG_ID_IPC_PING, /*** Inter-process communication ping */
+
+ /* Core/Switch util messages */
+ BCMBAL_SWITCH_UTIL_MSG,
+
+ /* Core/Mac util messages */
+ BCMBAL_MAC_UTIL_MSG,
+
+ /* Core<->Public API messages */
+ BCMBAL_MGMT_MSG,
+
+ /* Core->Public API indication messages (both auto and "normal") */
+ BCMBAL_MGMT_API_IND_MSG,
+
+ BCMOS_MSG_ID_EON_PROXY_RX,
+ BCMOS_MSG_ID_EON_DESTROY_STATE,
+
+ BCMOS_MSG_ID_EPON_OAM_PROXY_RX,
+ BCMOS_MSG_ID_EPON_OAM_TIMEOUT,
+
+ BCMOS_MSG_ID_OMCI_TRANSPORT_SEND,
+
+ BCMOS_MSG_ID__END,
+ BCMOS_MSG_ID__FORCE16 = 0x7fff
+} bcmos_msg_id;
+
+
+#endif /* BAL_OSMSG_H_ */
diff --git a/bal_release/src/common/include/bal_utils_msg.h b/bal_release/src/common/include/bal_utils_msg.h
new file mode 100644
index 0000000..d6721fc
--- /dev/null
+++ b/bal_release/src/common/include/bal_utils_msg.h
@@ -0,0 +1,180 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+The message format will look like the following
+
+ -----------------------------------------------------------------------------------
+ | BAL Header | | Payload Data |
+ ----------------------------------|------------------------------------------------
+ | *bcmos_header | | App Header | |
+ -----------------------------------------------------------------------------------
+ | | | version | |
+ | type | msg_type | obj_key | bal_util_ind_flow_t |
+ | | msg_id | status | |
+ -----------------------------------------------------------------------------------
+
+ *The bcmos Header is actually the first field of BAL Header structure (bal_comm_msg_hdr_t)
+
+ type can be:
+ BCMBAL_SWITCH_UTIL_MSG
+ BCMBAL_MAC_UTIL_MSG
+
+ msg_type can be:
+ BAL_MSG_IND,
+ BAL_MSG_AUTO_IND
+
+ msg_id is module specific, but contains two 16 bits fields (OBJECT_ID, OPERATION_ID)
+ see bal_objs.h for OBJECT_ID details
+ The OPERATION_ID should be unique within the OBJECT - see example below
+ bal_msg.h
+
+ status is for indication message to show general results. The value is bcmos_errno.
+
+*********************************************************************************/
+
+/**
+ * @file bal_utils_msg.h
+ *
+ * @brief Common header for messages sent between Utils and Core
+ *
+ * @ingroup apps
+ */
+
+#ifndef _BAL_UTIL_MSG_H_
+#define _BAL_UTIL_MSG_H_
+
+/*@{*/
+
+#include <bal_msg.h>
+#include <stdint.h>
+
+#define BAL_UTIL_MSG_VERSION 1
+
+/* access terminal request list,
+ */
+typedef enum
+{
+ BAL_UTIL_OPER_ACC_TERM_CONNECT,
+ BAL_UTIL_OPER_ACC_TERM_DISCONNECT
+} bal_util_oper_acc_term;
+
+/* subscriber terminal request list,
+ */
+typedef enum
+{
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ BAL_UTIL_OPER_SUB_TERM_CLEAR,
+ BAL_UTIL_OPER_SUB_TERM_DISCOVERY
+} bal_util_oper_sub_term;
+
+/* interface request list,
+ */
+typedef enum
+{
+ BAL_UTIL_OPER_IF_UP,
+ BAL_UTIL_OPER_IF_DOWN
+} bal_util_oper_if;
+
+/* flow request list,
+ */
+typedef enum
+{
+ BAL_UTIL_OPER_FLOW_ADD,
+ BAL_UTIL_OPER_FLOW_REMOVE,
+ BAL_UTIL_OPER_FLOW_CLEAR
+} bal_util_oper_flow;
+
+typedef enum
+{
+ BAL_UTIL_FLOW_IND_SEND_NONE,
+ BAL_UTIL_FLOW_IND_SEND_SUCCESS,
+ BAL_UTIL_FLOW_IND_SEND_FAIL
+} bal_util_flow_ind;
+
+/* group request list,
+ */
+typedef enum
+{
+ BAL_UTIL_OPER_GROUP_CREATE,
+ BAL_UTIL_OPER_GROUP_ADD,
+ BAL_UTIL_OPER_GROUP_REMOVE,
+ BAL_UTIL_OPER_GROUP_SET,
+ BAL_UTIL_OPER_GROUP_DESTROY
+} bal_util_oper_group;
+
+typedef enum
+{
+ BAL_UTIL_OPER_AGG_PORT_ADD,
+ BAL_UTIL_OPER_AGG_PORT_REMOVE,
+ BAL_UTIL_OPER_AGG_PORT_CLEAR
+} bal_util_oper_agg_port;
+
+/* Macro to retrieve the name string of the GROUP oper */
+#define BCMBAL_UTIL_GROUP_OPER_STR_GET(__op_type__) \
+ ( BAL_UTIL_OPER_GROUP_CREATE == __op_type__ ) ? "create" : \
+ ( BAL_UTIL_OPER_GROUP_ADD == __op_type__ ) ? "add" : \
+ ( BAL_UTIL_OPER_GROUP_REMOVE == __op_type__ ) ? "remove" : \
+ ( BAL_UTIL_OPER_GROUP_SET == __op_type__ ) ? "set" : \
+ ( BAL_UTIL_OPER_GROUP_DESTROY == __op_type__ ) ? "destroy" : \
+ "unknown"
+
+/* bal_app_msg_obj_key_t allow applications to id which instance of object
+ * this message should be processed
+ */
+typedef union bal_util_msg_obj_key
+{
+ bcmbal_access_terminal_key acc_term_key;
+ bcmbal_interface_key if_key;
+ bcmbal_subscriber_terminal_key sub_term_key;
+ bcmbal_flow_key flow_key;
+ bcmbal_group_key group_key;
+ bcmbal_tm_sched_key tm_sched_key;
+} bal_util_msg_obj_key;
+
+#define BCMBAL_INVALID_TUNNEL_ID 0xffffffff
+
+ /* indication message header */
+ typedef struct bal_util_msg_ind
+ {
+ bal_comm_msg_hdr comm_hdr; /* Communication header */
+ uint32_t version; /* version of the app message format */
+ bal_util_msg_obj_key obj_key;
+ int32_t status; /* bcmos_errno */
+ /* Optional custom BAL MAC/SWITCH UTIL indication data follows */
+ char data[0];
+ } bal_util_msg_ind;
+
+ /* auto indication message header */
+ typedef bal_util_msg_ind bal_util_msg_auto_ind;
+
+#endif /* _BAL_UTIL_MSG_H */
diff --git a/bal_release/src/common/include/bal_version.h b/bal_release/src/common/include/bal_version.h
new file mode 100644
index 0000000..533ff6b
--- /dev/null
+++ b/bal_release/src/common/include/bal_version.h
@@ -0,0 +1,44 @@
+/*************************************************************
+ * DO NOT EDIT! THIS FILE WAS AUTO GENERATED. DO NOT EDIT! *
+ *************************************************************/
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2017:DUAL/GPL:standard
+ *
+ * Copyright (c) 2017 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#if !defined(BAL_VERSION_H)
+#define BAL_VERSION_H
+
+#define BAL_VERSION "R02.02.01.139177"
+#define BAL_VERSION_STR_LEN (17)
+
+#define BAL_BUILD_DATE "Thu Mar 30 18:15:35 IDT 2017"
+#define BAL_BUILD_INFO ""
+
+#endif /* BAL_VERSION_H */
diff --git a/bal_release/src/common/os_abstraction/Makefile b/bal_release/src/common/os_abstraction/Makefile
new file mode 120000
index 0000000..823d78c
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/Makefile
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/Makefile
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_common.c b/bal_release/src/common/os_abstraction/bcmos_common.c
new file mode 120000
index 0000000..eccb2aa
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_common.c
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_common.c
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_common.h b/bal_release/src/common/os_abstraction/bcmos_common.h
new file mode 120000
index 0000000..a31747a
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_common.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_common.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_common2.h b/bal_release/src/common/os_abstraction/bcmos_common2.h
new file mode 120000
index 0000000..b5d6f8f
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_common2.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_common2.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_endian.h b/bal_release/src/common/os_abstraction/bcmos_endian.h
new file mode 120000
index 0000000..3c1036d
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_endian.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_endian.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_errno.c b/bal_release/src/common/os_abstraction/bcmos_errno.c
new file mode 120000
index 0000000..240256f
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_errno.c
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_errno.c
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_errno.h b/bal_release/src/common/os_abstraction/bcmos_errno.h
new file mode 120000
index 0000000..9bac886
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_errno.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_errno.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_hash_table.c b/bal_release/src/common/os_abstraction/bcmos_hash_table.c
new file mode 120000
index 0000000..81cb3c0
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_hash_table.c
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_hash_table.c
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_hash_table.h b/bal_release/src/common/os_abstraction/bcmos_hash_table.h
new file mode 120000
index 0000000..c0111be
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_hash_table.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_hash_table.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_pack.h b/bal_release/src/common/os_abstraction/bcmos_pack.h
new file mode 120000
index 0000000..7582ed1
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_pack.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_pack.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_queue.h b/bal_release/src/common/os_abstraction/bcmos_queue.h
new file mode 120000
index 0000000..cf2d81d
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_queue.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_queue.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_rw_lock.c b/bal_release/src/common/os_abstraction/bcmos_rw_lock.c
new file mode 120000
index 0000000..bee8c23
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_rw_lock.c
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_rw_lock.c
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_rw_lock.h b/bal_release/src/common/os_abstraction/bcmos_rw_lock.h
new file mode 120000
index 0000000..cd9e84d
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_rw_lock.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_rw_lock.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_sysif.h b/bal_release/src/common/os_abstraction/bcmos_sysif.h
new file mode 120000
index 0000000..a9c8db8
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_sysif.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_sysif.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_tree.h b/bal_release/src/common/os_abstraction/bcmos_tree.h
new file mode 120000
index 0000000..62433e7
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_tree.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_tree.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/bcmos_types.h b/bal_release/src/common/os_abstraction/bcmos_types.h
new file mode 120000
index 0000000..5e43582
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/bcmos_types.h
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/bcmos_types.h
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/cfe b/bal_release/src/common/os_abstraction/cfe
new file mode 120000
index 0000000..5dba27e
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/cfe
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/cfe
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/linux b/bal_release/src/common/os_abstraction/linux
new file mode 120000
index 0000000..ee2249d
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/linux
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/linux
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/os_cli b/bal_release/src/common/os_abstraction/os_cli
new file mode 120000
index 0000000..075f9b4
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/os_cli
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/os_cli
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/posix b/bal_release/src/common/os_abstraction/posix
new file mode 120000
index 0000000..9f04fee
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/posix
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/posix
\ No newline at end of file
diff --git a/bal_release/src/common/os_abstraction/vxworks55 b/bal_release/src/common/os_abstraction/vxworks55
new file mode 120000
index 0000000..5a3b0c5
--- /dev/null
+++ b/bal_release/src/common/os_abstraction/vxworks55
@@ -0,0 +1 @@
+../../../3rdparty/maple/sdk/host_customized/os_abstraction/vxworks55
\ No newline at end of file
diff --git a/bal_release/src/common/utils b/bal_release/src/common/utils
new file mode 120000
index 0000000..1d7a58c
--- /dev/null
+++ b/bal_release/src/common/utils
@@ -0,0 +1 @@
+../../3rdparty/maple/sdk/host_driver/utils
\ No newline at end of file
diff --git a/bal_release/src/core/main/Makefile b/bal_release/src/core/main/Makefile
new file mode 100644
index 0000000..d0a6e02
--- /dev/null
+++ b/bal_release/src/core/main/Makefile
@@ -0,0 +1,39 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL core CLI application
+#
+MOD_NAME = bal_core
+MOD_DEPS = common_include dev_log cli os_cli bal_api bal_api_cli bal_mac_util bal_switch_util bal_app_utils rscmgr balobjmsg topology cmdline
+MOD_DEPS_OPT = omcisvc
+
+MOD_TYPE = lib
+
+srcs = bal_core.c bal_cli.c bal_worker.c acc_term_fsm.c sub_term_fsm.c flow_fsm.c fsm_common.c group_fsm.c tm_sched_fsm.c tm_queue_fsm.c
diff --git a/bal_release/src/core/main/acc_term_fsm.c b/bal_release/src/core/main/acc_term_fsm.c
new file mode 100644
index 0000000..c4635b9
--- /dev/null
+++ b/bal_release/src/core/main/acc_term_fsm.c
@@ -0,0 +1,2431 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file acc_term_fsm.c
+ * @brief Code to support the BAL access terminal FSM
+ *
+ * @addtogroup access_terminal
+ */
+
+/*@{*/
+
+#define BAL_DBG_PRINT
+
+/*--- project includes ---*/
+#include <bcmos_system.h>
+#include <acc_term_fsm.h>
+#include <bal_msg.h>
+#include <bal_api.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include <bal_osmsg.h>
+#include <fsm_common.h>
+#include <rsc_mgr.h>
+#include <bal_core.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+/*
+ * @brief The logging device ids for the access-terminal and interface
+ */
+static dev_log_id log_id_access_terminal;
+static dev_log_id log_id_interface;
+#endif
+
+
+/*--- local function declarations ---*/
+static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface,
+ void *msg);
+
+static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface,
+ void *msg);
+
+static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser);
+
+static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst, acc_term_fsm_event *p_event);
+
+
+/**
+ * access-terminal FSM helper functions
+ */
+static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event);
+
+static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst);
+
+static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
+ bcmbal_sub_id_list_u16 *sub_term_id_list);
+
+
+static acc_term_inst *access_terminal_get(void);
+static char *interface_type_str_get(bcmbal_intf_type intf_type);
+
+static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info);
+static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key);
+
+#define ACC_TERM_FSM_STATE_ADDING_TIMEOUT (45) /* Seconds */
+
+/*
+ * @brief The definition of an access terminal FSM state processing function
+ */
+typedef bcmos_errno (* acc_term_fsm_state_processor)(acc_term_inst *, void *, acc_term_fsm_event *);
+
+extern bcmbal_config_params bal_config_params;
+
+
+/**
+ * @brief API to get oper status from admin state of an interface
+ */
+bcmbal_status bcmbal_get_intf_oper_status_from_admin_state (bcmbal_state intf_admin_state)
+{
+ switch (intf_admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ return BCMBAL_STATUS_UP;
+ break;
+
+ case BCMBAL_STATE_DOWN:
+ return BCMBAL_STATUS_DOWN;
+ break;
+
+ case BCMBAL_STATE_TESTING:
+ return BCMBAL_STATUS_TESTING;
+ break;
+
+ default:
+ return BCMBAL_STATUS_UP; /* default keep oper status as UP */
+ break;
+ }
+
+ return BCMBAL_STATUS_UP; /* default keep oper status as UP */
+}
+
+
+/**
+ * @brief API to convert port type and id from CLI/Mgmt interface to the internal
+ * index of interface array database.
+ */
+uint32_t bcmbal_port_type_and_id_to_interface_index (bcmbal_intf_type intf_type, bcmbal_intf_id intf_id)
+{
+ switch (intf_type)
+ {
+ case BCMBAL_INTF_TYPE_PON:
+ if (intf_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
+ {
+ return intf_id; /* zero offset for the PON ports */
+ }
+ break;
+
+ case BCMBAL_INTF_TYPE_NNI:
+ if (intf_id < bal_config_params.num_nni_ports)
+ {
+ return (NUM_SUPPORTED_SUBSCRIBER_INTERFACES + intf_id); /* offset-ed for the NNI ports */
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return INVALID_INTERFACE_INDEX;
+
+}
+
+
+/*
+ * @brief The Access terminal FSM state processing array
+ */
+static acc_term_fsm_state_processor access_term_states[ACC_TERM_FSM_STATE__NUM_OF][ACC_TERM_FSM_EVENT_TYPE__NUM_OF] =
+{
+
+ [ACC_TERM_FSM_STATE_NULL] =
+ {
+ /*
+ * Next state: ADDING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_start,
+
+ /*
+ * Next state: NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_ok,
+
+ /*
+ * Next state: NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
+ },
+
+ [ACC_TERM_FSM_STATE_ADDING] =
+ {
+ /*
+ * Next state: ADDING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_pending,
+
+ /*
+ * Next state: ADDING | ADDED
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_adding_process_util_msg,
+
+ /*
+ * Next state: ADDING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_adding_timeout,
+
+ },
+
+ [ACC_TERM_FSM_STATE_ADDED] =
+ {
+ /*
+ * Next state: ADDED
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_ok,
+
+ /*
+ * Next state: REMOVING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_start,
+
+ /*
+ * Next state: ADDING | ADDED
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
+
+ /*
+ * Next state: ADDED
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
+
+ },
+
+ [ACC_TERM_FSM_STATE_REMOVING] =
+ {
+ /*
+ * Next state: REMOVING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_pending,
+
+ /*
+ * Next state: REMOVING | NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_removing_process_util_msg,
+
+ /*
+ * Next state: REMOVING
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_removing_timeout,
+ },
+
+};
+
+static char *state_name_str[] =
+{
+ "ACC_TERM_NULL",
+ "ACC_TERM_ADDING",
+ "ACC_TERM_ADDED",
+ "ACC_TERM_REMOVING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (ACC_TERM_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), acc_term_fsm_state);
+
+static char *acc_term_state_name_get(acc_term_fsm_state state)
+{
+ if(state < ACC_TERM_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "ACC_TERM_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "ACC_TERM_FSM_ACC_TERM_ADMIN_UP_EVENT",
+ "ACC_TERM_FSM_ACC_TERM_ADMIN_DN_EVENT",
+ "ACC_TERM_FSM_INT_ADMIN_UP_EVENT",
+ "ACC_TERM_FSM_INT_ADMIN_DN_EVENT",
+ "ACC_TERM_FSM_UTIL_MSG_EVENT",
+ "ACC_TERM_FSM_UTIL_AUTO_MSG_EVENT",
+ "ACC_TERM_FSM_TIMEOUT_EVENT"
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (ACC_TERM_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), acc_term_fsm_event_type);
+
+static char *acc_term_event_name_get(acc_term_fsm_event_type event)
+{
+ if(event < ACC_TERM_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "ACC_TERM_EVT_UNKNOWN";
+ }
+}
+
+static acc_term_inst single_access_terminal_instance;
+
+/*****************************************************************************/
+/**
+ * @brief A function called to initialize the access-terminal FSM
+ * infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns void
+ *****************************************************************************/
+void access_terminal_fsm_init(void)
+{
+
+#ifdef ENABLE_LOG
+ /* Register the log ids for this FSM */
+ log_id_access_terminal = bcm_dev_log_id_register("ACC_TERM", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_access_terminal == DEV_LOG_INVALID_ID);
+
+ log_id_interface = bcm_dev_log_id_register("INTF", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_interface == DEV_LOG_INVALID_ID);
+#endif
+
+ /*
+ * Initialize the access terminal instance structures
+ */
+ initialize_access_terminal_instance_config(&single_access_terminal_instance);
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing executive function
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst,
+ acc_term_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_fsm_state pre_state;
+ acc_term_fsm_state_processor acc_term_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_acc_term_inst);
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state before transitioning
+ */
+ pre_state = p_acc_term_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ acc_term_state_processor = access_term_states[p_acc_term_inst->fsm_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if (acc_term_state_processor)
+ {
+ ret = acc_term_state_processor(p_acc_term_inst, p_event->msg, p_event);
+ } else
+ {
+ acc_term_fsm_state_err(p_acc_term_inst, p_event->msg, p_event);
+ }
+
+ BCM_LOG(DEBUG, log_id_access_terminal, "*** FSM exec: Event %s, State: %s --> %s\n",
+ acc_term_event_name_get(p_event->event_type),
+ acc_term_state_name_get(pre_state),
+ acc_term_state_name_get(p_acc_term_inst->fsm_state));
+
+ return ret;
+}
+
+bcmos_errno process_access_terminal_util_msg(void *msg_payload)
+{
+ acc_term_inst *p_access_terminal_inst;
+
+ BCM_LOG(INFO, log_id_access_terminal, "ACCESS_TERMINAL indication received from util\n");
+
+ /* Find the specified access terminal instance */
+ p_access_terminal_inst = access_terminal_get();
+
+ if (NULL != p_access_terminal_inst)
+ {
+ acc_term_fsm_event event;
+
+ event.event_type = ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG;
+ event.msg = msg_payload;
+
+ access_terminal_fsm_exec(p_access_terminal_inst, &event);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_interface, "Could not find the ACTIVE access-terminal\n");
+ }
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing for an access-terminal
+ * admin-up command received from the BAL Public API when the specified
+ * access-terminal instance is in the admin-down state (i.e. when
+ * the access-terminal instance FSM is in the NULL state).
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_fsm_state old_state = p_acc_term_inst->fsm_state;
+
+ BCM_LOG(INFO, log_id_access_terminal,
+ "Received an admin UP request from BAL API - bringing access terminal up\n");
+
+ do
+ {
+ /* change access terminal state to ADDING */
+ p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDING;
+
+ /* start the timeout timer for the ADDING state */
+ fsm_timer_start(&p_acc_term_inst->timer_info,
+ p_acc_term_inst,
+ acc_term_fsm_timer_expiry,
+ TIMER_DURATION_IN_SEC(ACC_TERM_FSM_STATE_ADDING_TIMEOUT),
+ log_id_access_terminal);
+
+ /* Validate that the OLT SW version that the Bal was compiled against matches
+ * the SW version of the actual OLT that the Bal works with. We assume that
+ * Device Id 0 has the same version as all other OLT devices */
+ if (!bcmbal_is_mac_in_loopback() &&
+ (BCM_ERR_OK != (ret = mac_util_access_terminal_sw_version_validate((bcmolt_devid) 0))))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_sw_version_validate(() failed. rc=%s\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /* Core calls Mac Utils to set the access-terminal parameters using the applicable SDK calls */
+ if(BCM_ERR_OK != (ret = mac_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT)))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
+ break;
+ }
+
+ }while(0);
+
+ if(BCM_ERR_OK == ret)
+ {
+ /*
+ * The access-terminal object command has succeeded. The current object info
+ * becomes the commanded object info, except for the oper_status. This should
+ * be done atomically
+ */
+ memcpy(&p_acc_term_inst->current_acc_term_obj_info,
+ &p_acc_term_inst->api_req_acc_term_obj_info,
+ sizeof(p_acc_term_inst->api_req_acc_term_obj_info));
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_TRUE);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ oper_status,
+ BCMBAL_STATUS_DOWN);
+ }
+ else
+ {
+ fsm_timer_stop(&p_acc_term_inst->timer_info);
+ p_acc_term_inst->fsm_state = old_state;
+ mgmt_msg_send_balapi_ind(ret, msg, log_id_access_terminal);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing for an access-terminal
+ * admin-up command from the BAL Public API when the specified
+ * access-terminal is already admin-up (i.e. when the specified
+ * access-terminal instance FSM is in the ADDED state).
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Received an admin UP request from BAL API - returning OK to the API"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing for an access-terminal
+ * admin-down command received from the BAL Public API when the specified
+ * access-terminal is admin-up (i.e when the specified access-terminal
+ * instance FSM is in the ADDED state).
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Received an admin DOWN request from BAL API - removing the access terminal\n");
+
+ /*
+ * @todo - complete the DOWN implementation - until then, return an error
+ */
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing for access-terminal
+ * admin-down command from the BAL Public API when the specified
+ * access-terminal is already admin-down.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Received an admin DOWN request from BAL API - returning OK to the API"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to ignore a
+ * received message.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_access_terminal, "Ignoring message from BAL API \n");
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to process an
+ * access-terminal admin-up command from the BAL Public API when the
+ * specified access-terminal is in the REMOVING state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ " Received an admin UP request from BAL API - returning UP_PENDING to the API"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to process an
+ * access-terminal admin-down command from the BAL Public API when the
+ * specified access-terminal FSM is in the REMOVING state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_IN_PROGRESS;
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ " Received an admin DOWN request from BAL API"
+ " - returning IN_PROGRESS to the API - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to process a
+ * message from one of the BAL apps when the specified access-terminal
+ * instance FSM is in the ADDING state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ flow_fsm_state next_state = ACC_TERM_FSM_STATE_NULL;
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_acc_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ ret = ind_msg->status;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "Received an IND message from BAL UTIL (%s) during ADDING state with status %s\n",
+ subsystem_str[bcmbal_sender_get(msg)],
+ bcmos_strerror(ret)
+ );
+ }
+
+ /*
+ * Stop the indication timer
+ */
+ fsm_timer_stop(&p_acc_term_inst->timer_info);
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* Core calls Switch Utils to set the access-terminal parameters using the applicable SDK calls */
+ ret = sw_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT);
+ if (ret)
+ {
+ BCM_LOG(INFO, log_id_access_terminal,
+ "sw_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
+ }
+
+ if(BCM_ERR_OK == ret)
+ {
+ uint32_t logical_pon;
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ oper_status,
+ BCMBAL_STATUS_UP);
+
+ /*
+ * Initialize the resource manager only if at least of the PONs on the device is a GPON/XGPON/XGS/NGPON2 PON
+ */
+ BCM_TOPO_DEV_FOR_EACH_PON(0, logical_pon)
+ {
+ bcm_topo_pon_family pon_family = bcm_topo_pon_get_pon_family(logical_pon);
+
+ if (pon_family == BCM_TOPO_PON_FAMILY_GPON)
+ {
+ rsc_mgr_mac_init();
+ break;
+ }
+ }
+
+ /*
+ * Go to the ADDED state upon success
+ */
+ next_state = ACC_TERM_FSM_STATE_ADDED;
+
+
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_access_terminal,
+ " Failed in state %s;%s\n",
+ acc_term_state_name_get(p_acc_term_inst->fsm_state),
+ bcmos_strerror(ret));
+
+ /*
+ * Automatically return to the NULL state if an error occurs
+ */
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&p_acc_term_inst->current_acc_term_obj_info.hdr,
+ log_id_access_terminal);
+
+
+
+ }
+
+ p_acc_term_inst->fsm_state = next_state;
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to process a
+ * message from one of the BAL apps received when the specified
+ * access-terminal instance FSM is in the REMOVING state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_acc_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ ret = ind_msg->status;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ " Received an IND message from BAL UTIL (%s) during REMOVING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing function to process an
+ * AUTO IND message from one of the BAL apps.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_acc_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(INFO, log_id_access_terminal,
+ " Received an AUTO IND message from BAL UTIL ()\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Interface admin-up command received from the BAL Public API when
+ * the specified interface instance is in the admin-up state.
+ *
+ * @note This handler gets called for both PON and NNI type interfaces
+ *
+ * @param p_interface_inst Pointer to an interface instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface_inst,
+ void *msg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
+
+ BCM_LOG(INFO, log_id_interface,
+ " Received an INTERFACE admin UP request from BAL API"
+ " - bringing interface (%s%d) UP \n",
+ interface_type_str_get(key->intf_type),
+ key->intf_id);
+
+ do
+ {
+ bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
+
+ /*
+ * Create a pointer to the interface instance specified by the user
+ */
+
+ /*
+ * If the user has set the min_data_agg_port_id attribute for the interface, then program the resource manager
+ * with this value. It will also be sent to the MAC device for any required programming there.
+ */
+ if ((BCMBAL_INTF_TYPE_PON == key->intf_type) &&
+ (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_interface_inst->api_req_int_obj_info,
+ interface,
+ min_data_agg_port_id)) &&
+ (BCM_ERR_OK != rsc_mgr_access_int_base_alloc_id_set(key->intf_id,
+ p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id)))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal, "Error while setting base agg_port_id (%d) in the resource manager\n",
+ p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id);
+
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Change the interface admin state of the "current" interface object to up (this is for reporting) */
+ BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
+ interface,
+ admin_state,
+ BCMBAL_STATE_UP);
+
+ /* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
+ ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_UP);
+
+ if (BCM_ERR_OK != ret)
+ {
+ BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
+ interface,
+ admin_state,
+ old_admin_state);
+
+ BCM_LOG(ERROR, log_id_interface,
+ "Error detected by mac_util_interface_set (%s)\n",
+ bcmos_strerror(ret));
+
+ break;
+ }
+ } while (0);
+
+ if (BCM_ERR_OK != ret)
+ {
+ /* report this error to the API */
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_interface);
+ }
+ else
+ {
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
+ }
+
+ return ret;
+ }
+
+/*****************************************************************************/
+/**
+ * @brief Interface admin-up command received from the BAL Public API when
+ * the specified interface instance is in the admin-down state.
+ *
+ * @note This handler gets called for both PON and NNI type interfaces
+ *
+ * @param p_interface_inst Pointer to an interface instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface_inst,
+ void *msg)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
+
+ BCM_LOG(INFO, log_id_interface,
+ " Received an INTERFACE admin DOWN request from BAL API"
+ " - bringing interface (%s%d) DOWN \n",
+ interface_type_str_get(key->intf_type),
+ key->intf_id);
+
+ do
+ {
+ bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
+
+ /*
+ * Create a pointer to the interface instance specified by the user
+ */
+
+ /* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
+ ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_DOWN);
+
+ if (BCM_ERR_OK != ret)
+ {
+
+ BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
+ interface,
+ admin_state,
+ old_admin_state);
+
+ BCM_LOG(ERROR, log_id_interface,
+ "Error detected by mac_util_interface_set (%s)\n",
+ bcmos_strerror(ret));
+
+ break;
+ }
+
+ } while (0);
+
+ /* Change the interface admin state of the current interface info to down */
+ BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
+ interface,
+ admin_state,
+ BCMBAL_STATE_DOWN);
+
+ /* Check for any error and send an indication immediately in that case */
+ if (BCM_ERR_OK != ret)
+ {
+ /* report this error to the API */
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_interface);
+
+ }
+ else
+ {
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The function to process a timer expiry for either the ADDING
+ * states. This function executes an
+ * ACC_TERM_FSM_TIMEOUT_EVENT in the FSM state machine.
+ *
+ * @param timer - A pointer to the timer instance
+ * @param pUser - An opaque pointer to an access terminal instance
+ *
+ * @returns bcmos_timer_rc == BCMOS_TIMER_OK
+ */
+static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser)
+{
+ acc_term_fsm_event acc_term_event;
+
+ /*
+ * Stop the indication timer
+ */
+ fsm_timer_stop(timer);
+
+ BCM_LOG(INFO, log_id_access_terminal,
+ "timer expiry\n");
+
+ /*
+ * A message pointer is always passed inside the event structure. In this case, it is unused
+ */
+ acc_term_event.msg = NULL;
+ acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_TIMEOUT;
+
+ /* Declare this no longer in-progress */
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(((acc_term_inst *)pUser)->current_acc_term_obj_info), BCMOS_FALSE);
+
+ /*
+ * Run the access terminal FSM to process this event
+ */
+ access_terminal_fsm_exec((acc_term_inst *)pUser, &acc_term_event);
+
+ return BCMOS_TIMER_OK;
+
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing a timeout that occurs
+ * when the FSM is in the ADDING state. In this case, the FSM should
+ * just go back to the NULL state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "Error: Received a timeout while in the %s state.\n",
+ acc_term_state_name_get(p_acc_term_inst->fsm_state));
+
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(BCM_ERR_TIMEOUT,
+ (void *)&(p_acc_term_inst->current_acc_term_obj_info.hdr.hdr),
+ log_id_access_terminal);
+
+ /*
+ * Go back to the previous state
+ */
+ p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_NULL;
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM state processing a timeout that occurs
+ * when the FSM is in the REMOVING state. In this case, the FSM should
+ * just go back to the ADDED state.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_access_terminal,
+ "Received a timeout while in the %s state. Going back to the ADDED state\n",
+ acc_term_state_name_get(p_acc_term_inst->fsm_state));
+
+ /*
+ * Go back to the previous state
+ */
+ p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDED;
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The function to process a
+ * message from one of the BAL apps for the specified interface
+ *
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_interface_util_msg(void *msg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ uint32_t interface_index = INVALID_INTERFACE_INDEX;
+ bal_util_msg_ind *ind_msg;
+ acc_term_interface *p_interface_inst;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ " Received an interface IND message from BAL UTIL (%s)\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ if (BCM_ERR_OK == ind_msg->status)
+ {
+ /* first get the index to the interface array from port id/type */
+ interface_index = bcmbal_port_type_and_id_to_interface_index(ind_msg->obj_key.if_key.intf_type,
+ ind_msg->obj_key.if_key.intf_id);
+
+ if (interface_index >= INVALID_INTERFACE_INDEX)
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "INVALID port type/id (%s/%d) to interface index (%d)\n",
+ interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
+ ind_msg->obj_key.if_key.intf_id,
+ interface_index);
+
+ ret = BCM_ERR_PARM;
+ }
+
+ p_interface_inst = &(access_terminal_get()->intf_info.interface[interface_index]);
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* Core calls Switch Utils to set the interface parameters using the applicable SDK call
+ * If a PON port is being set, then the corresponding direct connect switch port is also
+ * set along with it
+ */
+ ret = sw_util_interface_set(p_interface_inst,
+ (p_interface_inst->api_req_int_obj_info.data.admin_state == BCMBAL_STATE_DOWN ?
+ BAL_UTIL_OPER_IF_DOWN : BAL_UTIL_OPER_IF_UP));
+
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "sw_util_interface_set(() failed. rc=%s\n", bcmos_strerror(ret));
+
+ }
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_interface,
+ "Bad interface index: interface type/id (%s/%d) (status: %s)\n",
+ interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
+ ind_msg->obj_key.if_key.intf_id,
+ bcmos_strerror(ind_msg->status));
+ }
+
+
+
+ if(BCM_ERR_OK == ret)
+ {
+ BCM_LOG(DEBUG, log_id_interface,
+ "Setting interface (%d) to %s\n",
+ interface_index,
+ (BCMBAL_STATE_UP == p_interface_inst->api_req_int_obj_info.data.admin_state) ?
+ "UP" : "DOWN");
+
+
+ /*
+ * Interface SET function succeeded, so copy the API request into the
+ * current interface object.
+ */
+
+ bcmbal_interface_object_overlay_w_src_priority(&(p_interface_inst->current_int_obj_info),&(p_interface_inst->api_req_int_obj_info));
+
+ /* Set the status of the current interface that we just configured to the requested state (UP or DOWN) */
+ BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
+ interface,
+ oper_status,
+ bcmbal_get_intf_oper_status_from_admin_state(p_interface_inst->api_req_int_obj_info.data.admin_state));
+
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_interface,
+ "Bad response from switch: Interface type/Id: %s/%d (status:%s) \n",
+ interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
+ ind_msg->obj_key.if_key.intf_id,
+ bcmos_strerror(ind_msg->status));
+
+ }
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_interface,
+ "Bad interface indication from MAC (status:%s)\n",
+ bcmos_strerror(ind_msg->status));
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_FALSE);
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&(p_interface_inst->current_int_obj_info.hdr),
+ log_id_interface);
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Access terminal FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ * @param msg Pointer to a BAL message (MAY BE NULL!)
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
+ void *msg,
+ acc_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "Error encountered processing FSM - BAD EVENT event:%s, state:%s\n",
+ acc_term_event_name_get(p_event->event_type),
+ acc_term_state_name_get(p_acc_term_inst->fsm_state));
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * access-terminal object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_access_terminal_object(void *msg_payload)
+{
+
+ bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
+ acc_term_inst *p_access_terminal_inst;
+ acc_term_fsm_event acc_term_event;
+ bcmbal_obj_msg_type oper_type;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Processing an access-terminal object\n");
+
+ do
+ {
+ /*
+ * Find or create the specified access terminal instance
+ */
+ p_access_terminal_inst = access_terminal_get();
+
+ oper_type = ((bcmbal_access_terminal_cfg *)msg_payload)->hdr.hdr.type;
+
+ /* If the state of the access-terminal is in flux, then reject the SET request */
+ if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
+ BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "The access-terminal is in-progress, SETs are not allowed\n");
+ ret = BCM_ERR_IN_PROGRESS;
+ break;
+ }
+
+ /* Copy the object in the message into local storage */
+ memcpy(&p_access_terminal_inst->api_req_acc_term_obj_info,
+ msg_payload,
+ sizeof(p_access_terminal_inst->api_req_acc_term_obj_info));
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "access_terminal admin state is: %s\n",
+ (BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state) ?
+ "UP" : "DOWN");
+
+ /*
+ * A message pointer is always passed inside the event structure.
+ */
+ acc_term_event.msg = msg_payload;
+
+ /* SET or GET or ...? */
+ switch (oper_type)
+ {
+ case (BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Processing a access-terminal SET REQ mgmt message\n");
+
+ /*
+ * Check if the mandatory access-terminal attributes have been set
+ */
+
+ do
+ {
+
+ /* The admin state attribute is mandatory */
+ if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
+ access_terminal,
+ admin_state))
+ {
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+
+ /*set iwf_mode from the global config parameters*/
+ BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
+ access_terminal,
+ iwf_mode,
+ bcmbal_config_get()->iwf_mode);
+
+ /*
+ * Perform the validation check(s) that the utils require
+ */
+ if(BCM_ERR_OK !=
+ (ret = mac_util_access_terminal_info_validate(&p_access_terminal_inst->api_req_acc_term_obj_info)))
+ {
+ break;
+ }
+ }
+ while(0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret,
+ msg_payload,
+ oper_type,
+ log_id_access_terminal);
+
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
+ ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
+ break;
+ }
+
+ /* Reflect the admin state of the access-terminal according to the commanded admin state */
+ BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->current_acc_term_obj_info,
+ access_terminal,
+ admin_state,
+ p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state);
+
+ if(BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state)
+ {
+
+ acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP;
+ }
+ else
+ {
+ acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN;
+ }
+
+ /*
+ * Run the access terminal FSM to process this event
+ */
+ ret = access_terminal_fsm_exec(p_access_terminal_inst, &acc_term_event);
+ break;
+
+ }
+ case (BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "Processing a access-terminal GET REQ mgmt message\n");
+
+ p_access_terminal_inst->current_acc_term_obj_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_access_terminal_cfg *)msg_payload) = p_access_terminal_inst->current_acc_term_obj_info;
+
+ mgmt_msg_send_balapi_rsp(ret,
+ msg_payload,
+ oper_type,
+ log_id_access_terminal);
+ break;
+
+ }
+ default:
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "Unsupported operation on access-terminal object (%d)\n",
+ bcmbal_msg_id_oper_get(msg_payload));
+
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_access_terminal);
+
+ break;
+ }
+ }
+ }while(0);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve an access-terminal instance
+ *
+ * @returns acc_term_inst_t* A pointer to the found access-terminal instance,
+ * or NULL if one is not found.
+ *****************************************************************************/
+static acc_term_inst *access_terminal_get(void)
+{
+ acc_term_inst *p_acc_term = (acc_term_inst *)NULL;
+
+ p_acc_term = &single_access_terminal_instance;
+
+ return p_acc_term;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve the status of the access-terminal
+ *
+ *
+ * @returns bcmbal_status
+ *****************************************************************************/
+bcmbal_status acc_term_status_get(void)
+{
+ acc_term_inst *p_acc_term_inst;
+
+ p_acc_term_inst = access_terminal_get();
+
+ return p_acc_term_inst->current_acc_term_obj_info.data.oper_status;
+
+}
+
+static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst;
+ bcmbal_tm_sched_key tm_key;
+ switch(p_interface_info->key.intf_type)
+ {
+ case BCMBAL_INTF_TYPE_PON:
+ {
+ /*for active pon interface:
+ ds_tm should be define, - if it is set, validate sched exist and match direction (ds)
+ if not set - will create auto created tm */
+ if(BCMBAL_CFG_PROP_IS_SET(p_interface_info,interface,ds_tm))
+ {
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
+ tm_key.id = p_interface_info->data.ds_tm;
+ p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
+ p_interface_info->key.intf_id, tm_key.id);
+ break;
+ }
+ }
+ else /*auto created sched was removed and no other default sched was set*/
+ {
+ BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+ /* us_tm is optional - if it is set, validate sched exist and match direction (us)*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
+ {
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
+ tm_key.id = p_interface_info->data.us_tm;
+ p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
+ p_interface_info->key.intf_id, tm_key.id);
+ break;
+ }
+ }
+
+ }
+ break;
+
+ case BCMBAL_INTF_TYPE_NNI:
+ {
+ /*for active nni interface:
+ us_tm should be define, -
+ if it is set, validate sched exist and match direction (us)
+ if not set - will create auto created tm
+ */
+ if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
+ {
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
+ tm_key.id = p_interface_info->data.us_tm;
+ p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
+ p_interface_info->key.intf_id, tm_key.id);
+ break;
+ }
+ }
+ else /*auto created sched was removed and no other default sched was set*/
+ {
+ BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
+ break;
+ }
+ /* ds_tm is optional - if it is set, validate sched exist and match direction (ds)*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, ds_tm))
+ {
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
+ tm_key.id = p_interface_info->data.ds_tm;
+ p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
+ p_interface_info->key.intf_id, tm_key.id);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ BCM_LOG(ERROR, log_id_interface, "Invalid intf type (%d) in interface key\n",
+ p_interface_info->key.intf_type);
+ ret = BCM_ERR_PARM;
+ }
+ return ret;
+}
+
+bcmos_errno interface_tm_sched_unset(bcmbal_interface_key intf_key, bcmbal_tm_sched_key sched_key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_interface *p_acc_term_interface = bcmbal_interface_get(intf_key);
+ do
+ {
+ if(NULL == p_acc_term_interface)
+ {
+ BCM_LOG(ERROR, log_id_interface, "no such interface (id = %d dir = %s ) \n",
+ intf_key.intf_id, interface_type_str_get(intf_key.intf_type));
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ if (BCMBAL_TM_SCHED_DIR_US == sched_key.dir)
+ {
+ BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, us_tm);
+ }
+ else
+ {
+ BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, ds_tm);
+ }
+ }while(0);
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to process an interface object message
+ * (SET, GET, CLEAR, STATS) received from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_interface_object(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ bcmbal_interface_cfg *p_intf_cfg = (bcmbal_interface_cfg *)msg_payload;
+ bcmbal_interface_key *p_intf_key;
+ acc_term_inst *p_access_terminal_inst;
+
+ bcmbal_interface_cfg *p_api_req_interface_info;
+ bcmbal_interface_cfg *p_current_interface_info;
+ uint32_t interface_index = INVALID_INTERFACE_INDEX;
+ bcmbal_obj_msg_type oper_type;
+
+ BCM_LOG(DEBUG, log_id_interface,
+ "Processing an interface object\n");
+
+ do
+ {
+ do
+ {
+ oper_type = p_intf_cfg->hdr.hdr.type;
+
+ /*
+ * See if the access terminal is active
+ */
+ p_access_terminal_inst = access_terminal_get();
+
+ if(NULL == p_access_terminal_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "the access-terminal is not active\n");
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* If the state of the access-terminal is in flux, then reject the SET request */
+ if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
+ BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "The access-terminal is in-progress, SETs to an interface are not allowed\n");
+
+ ret = BCM_ERR_IN_PROGRESS;
+ break;
+ }
+
+ /*
+ * Get the interface key from the message
+ */
+ p_intf_key = &p_intf_cfg->key;
+
+ if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_PON)
+ {
+ if(p_intf_key->intf_id > NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "out of range value (%d) detected in interface key for PON\n", p_intf_key->intf_id);
+
+ ret = BCM_ERR_RANGE;
+ break;
+ }
+ }
+ /** @todo check the lower limit also */
+ else if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_NNI)
+ {
+ if( BCMOS_FALSE == bcm_topo_nni_is_valid(p_intf_key->intf_id))
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "out of range value (%d) detected in interface key for NNI\n", p_intf_key->intf_id);
+
+ ret = BCM_ERR_RANGE;
+ break;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "Invalid intf type (%d) in interface key\n", p_intf_key->intf_type);
+
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*
+ * Don't accept interface object references when the associated access-terminal is down
+ *
+ * Interfaces are not even instantiated internally until the access-terminal object to which
+ * they belong is instantiated.
+ */
+ if(BCMBAL_STATE_DOWN == p_access_terminal_inst->current_acc_term_obj_info.data.admin_state)
+ {
+ BCM_LOG(INFO, log_id_interface,
+ "access terminal admin-state is DOWN\n");
+
+ ret = BCM_ERR_INVALID_OP;
+ break;
+ }
+
+ /* Get the index to the interface array from port id/type */
+ interface_index = bcmbal_port_type_and_id_to_interface_index (p_intf_key->intf_type, p_intf_key->intf_id);
+ if (interface_index >= INVALID_INTERFACE_INDEX)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "INVALID port type/id (%s/%d) to interface index (%d) for access terminal\n",
+ interface_type_str_get(p_intf_key->intf_type), p_intf_key->intf_id, interface_index);
+
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*
+ * This is a pointer to the "API interface" structure
+ */
+ p_api_req_interface_info =
+ &(p_access_terminal_inst->intf_info.interface[interface_index].api_req_int_obj_info);
+
+ /*
+ * This is a pointer to the "current interface" structure
+ */
+ p_current_interface_info =
+ &(p_access_terminal_inst->intf_info.interface[interface_index].current_int_obj_info);
+
+ /* If the state of the interface is in flux, then reject the SET request */
+ if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
+ (BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(p_current_interface_info)))
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "The interface is in-progress, SETs are not allowed\n");
+ ret = BCM_ERR_IN_PROGRESS;
+ break;
+ }
+
+ }while(0);
+
+ if(BCM_ERR_OK != ret)
+ {
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
+ break;
+ }
+
+ /*
+ * Fill in the interface info SET data structure
+ */
+ *p_api_req_interface_info = *p_intf_cfg;
+
+ BCM_LOG(DEBUG, log_id_interface,
+ " interface object state from API message is: %d, intf_type: %s intf_id: %d\n",
+ p_api_req_interface_info->data.admin_state,
+ interface_type_str_get(p_api_req_interface_info->key.intf_type),
+ p_api_req_interface_info->key.intf_id);
+
+
+ /* SET or GET or ...? */
+ switch (oper_type)
+ {
+
+ case (BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ BCM_LOG(DEBUG, log_id_interface,
+ "Processing an interface SET REQ mgmt message\n");
+ /*if sched is already set, can not change sched setting using set command, should first delete current sched*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,ds_tm)
+ && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,ds_tm))
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "ds_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
+ p_current_interface_info->data.ds_tm);
+ ret = BCM_ERR_ALREADY;
+ break;
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,us_tm)
+ && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,us_tm))
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "us_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
+ p_current_interface_info->data.us_tm);
+ ret = BCM_ERR_ALREADY;
+ break;
+ }
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
+
+ if(BCM_ERR_OK != ret)
+ {
+ break;
+ }
+
+ /* If this interface is already up, then just return OK */
+ if(BCMBAL_STATE_UP == p_api_req_interface_info->data.admin_state)
+ {
+ if(BCMBAL_STATUS_UP == p_current_interface_info->data.oper_status)
+ {
+ BCM_LOG(DEBUG, log_id_interface,
+ "=====> Received an interface UP for an already UP interface, returning OK\n");
+ break;
+ }
+
+ /*validate and set the interface' tm sched*/
+ bcmbal_interface_object_overlay_w_dst_priority(p_api_req_interface_info,p_current_interface_info);
+ ret = interface_tm_sched_set(p_api_req_interface_info);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface,"Could not set the interface tm sched\n");
+ break;
+ }
+ interface_admin_up_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
+ msg_payload);
+ }
+ else
+ {
+ if(BCMBAL_STATUS_DOWN == p_current_interface_info->data.oper_status)
+ {
+ BCM_LOG(DEBUG, log_id_interface,
+ "=====> Received an interface DOWN for an already DOWN interface, returning OK\n");
+
+ break;
+ }
+
+ interface_admin_dn_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
+ msg_payload);
+
+ }
+
+ break;
+
+ }
+ case (BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+
+ BCM_LOG(DEBUG, log_id_interface,
+ "Processing a interface GET REQ mgmt message\n");
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ p_current_interface_info->hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+
+ bcmbal_sub_id_list_u16 sub_term_id_list = {};
+
+ BCMBAL_CFG_PROP_CLEAR(p_current_interface_info,
+ interface,
+ sub_term_id_list);
+
+ /* If the user requested the list of sub_term_ids for this interface,
+ * and this is a PON interface, then return the list.
+ */
+ if(BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,
+ interface,
+ sub_term_id_list))
+ {
+ if(BCMBAL_INTF_TYPE_PON == p_current_interface_info->key.intf_type)
+ {
+
+ sub_term_id_list_fill(interface_index, &sub_term_id_list);
+
+ /* NOTE: The returned list may be empty */
+ BCMBAL_CFG_PROP_SET(p_current_interface_info,
+ interface,
+ sub_term_id_list,
+ sub_term_id_list);
+
+ }
+ }
+
+ *((bcmbal_interface_cfg *)msg_payload) = *p_current_interface_info;
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
+
+ /* Free the temporary list if it was used */
+ if(sub_term_id_list.val)
+ {
+ bcmos_free(sub_term_id_list.val);
+ }
+
+ break;
+ }
+ default:
+ {
+ BCM_LOG(ERROR, log_id_interface,
+ "Unsupported operation on interface object (%d)\n",
+ bcmbal_msg_id_oper_get(msg_payload));
+
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
+ break;
+ }
+
+ }
+
+ }while (0);
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function called to initialize a single access-terminal instance.
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @param p_acc_term_inst Pointer to an access terminal instance
+ *
+ * @returns void
+ *****************************************************************************/
+static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst)
+{
+ int ii;
+ int intf_id;
+ bcmos_errno ret;
+
+ BUG_ON(NULL == p_acc_term_inst);
+
+ p_acc_term_inst->current_acc_term_obj_info.key.access_term_id = 0;
+
+ BCMBAL_CFG_INIT(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ p_acc_term_inst->current_acc_term_obj_info.key);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ admin_state,
+ BCMBAL_STATE_DOWN);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ oper_status,
+ BCMBAL_STATUS_DOWN);
+
+ BCMBAL_PROP_SET_PRESENT(&p_acc_term_inst->current_acc_term_obj_info,
+ access_terminal,
+ _cfg,
+ iwf_mode);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
+
+ {
+ bcmbal_interface_key key;
+
+ intf_id = 0; /* reset the port id to the starting id value for the PON interfaces */
+
+ key.intf_type = BCMBAL_INTF_TYPE_PON;
+
+ for(ii=0; ii<NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii++)
+ {
+
+ key.intf_id = intf_id;
+
+ p_acc_term_inst->intf_info.interface[ii].num_sub_terms_on_int = 0;
+ TAILQ_INIT(&p_acc_term_inst->intf_info.interface[ii].sub_term_id_list);
+
+ BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ key);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ admin_state,
+ BCMBAL_STATE_DOWN);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ oper_status,
+ BCMBAL_STATUS_DOWN);
+
+ ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for pon if %d", intf_id);
+ break;
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
+
+ intf_id++;
+ }
+
+ intf_id = 0; /* reset the port id to the starting id value for the NNI interfaces */
+
+ key.intf_type = BCMBAL_INTF_TYPE_NNI;
+
+ for(ii=NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii<(NUM_SUPPORTED_SUBSCRIBER_INTERFACES + bal_config_params.num_nni_ports); ii++)
+ {
+
+ key.intf_id = intf_id;
+
+ BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ key);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ admin_state,
+ BCMBAL_STATE_UP);
+
+ BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
+ interface,
+ oper_status,
+ BCMBAL_STATUS_UP);
+
+
+ ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for nni if %d", intf_id);
+ break;
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
+
+ intf_id++;
+ }
+ }
+}
+
+bcmos_errno bcmbal_interface_sub_term_list_entry_add(bcmbal_subscriber_terminal_key sub_term_key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_inst *p_access_terminal_inst;
+ sub_term_id_entry *current_entry;
+ acc_term_interface *p_interface;
+
+ p_access_terminal_inst = access_terminal_get();
+
+ do
+ {
+ /*
+ * If the specified access terminal is not active then it's interfaces are down.
+ */
+ if(NULL == p_access_terminal_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "no such ACTIVE access terminal\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
+
+ /* Check if the id is already on the list before adding it */
+ TAILQ_FOREACH(current_entry,
+ &p_interface->sub_term_id_list,
+ next)
+ {
+ if(current_entry->sub_term_id == sub_term_key.sub_term_id)
+ {
+ return BCM_ERR_ALREADY;
+ }
+ }
+
+ /* Get a new entry and configure it */
+ current_entry = bcmos_calloc(sizeof(sub_term_id_entry));
+
+ if (NULL == current_entry)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ current_entry->sub_term_id = sub_term_key.sub_term_id;
+
+ BCM_LOG(INFO, log_id_access_terminal,
+ "adding sub_term id %u to interface %u\n", sub_term_key.sub_term_id, sub_term_key.intf_id);
+
+ /* Save the entry on the list of subscriber-terminal ids on this interface */
+ TAILQ_INSERT_TAIL(&p_interface->sub_term_id_list,
+ current_entry, next);
+
+ (p_interface->num_sub_terms_on_int)++;
+
+ } while (0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_interface_sub_term_list_entry_remove(bcmbal_subscriber_terminal_key sub_term_key)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ acc_term_inst *p_access_terminal_inst;
+ acc_term_interface *p_interface;
+ sub_term_id_entry *current_entry, *p_temp_entry;
+
+ do
+ {
+ p_access_terminal_inst = access_terminal_get();
+
+ /*
+ * If the specified access terminal is not active then it's interfaces are down.
+ */
+ if(NULL == p_access_terminal_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "no such ACTIVE access terminal\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &p_interface->sub_term_id_list,
+ next,
+ p_temp_entry)
+ {
+ if(current_entry->sub_term_id == sub_term_key.sub_term_id)
+ {
+ /* Remove it from the list of subscriber-terminal ids on this interface */
+ TAILQ_REMOVE(&p_interface->sub_term_id_list,
+ current_entry, next);
+
+ bcmos_free(current_entry);
+
+ (p_interface->num_sub_terms_on_int)--;
+
+ ret = BCM_ERR_OK;
+ break;
+
+ }
+ }
+ } while (0);
+
+ return ret;
+}
+
+static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
+ bcmbal_sub_id_list_u16 *sub_term_id_list)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_inst *p_acc_term_inst;
+ sub_term_id_entry *current_entry = NULL;
+ int ii = 0;
+
+ do
+ {
+ /*
+ * See if the access-terminal is active
+ */
+ p_acc_term_inst = access_terminal_get();
+
+ /*
+ * If the specified access terminal is not active then it's interfaces are down.
+ */
+ if(NULL == p_acc_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "no such ACTIVE access terminal\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* Traverse the list of sub_term_ids recorded and fill in the list to be returned */
+ sub_term_id_list->len = p_acc_term_inst->intf_info.interface[interface_index].num_sub_terms_on_int;
+ sub_term_id_list->val = bcmos_calloc(sizeof(bcmbal_sub_id) * sub_term_id_list->len);
+
+ if (NULL == sub_term_id_list->val)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ TAILQ_FOREACH(current_entry,
+ &p_acc_term_inst->intf_info.interface[interface_index].sub_term_id_list,
+ next)
+ {
+ BCM_LOG(DEBUG, log_id_access_terminal,
+ "adding sub_term_id %u to response at array location %u\n",
+ current_entry->sub_term_id,
+ ii);
+ sub_term_id_list->val[ii++] = current_entry->sub_term_id;
+ }
+
+ } while (0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_interface_tm_get(bcmbal_interface_key key, bcmbal_tm_sched_id *id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ acc_term_inst *p_acc_term_inst;
+ uint32_t interface_index = INVALID_INTERFACE_INDEX;
+
+ do
+ {
+ /* See if the access-terminal is active */
+ p_acc_term_inst = access_terminal_get();
+
+ /* If the specified access terminal is not active then it's interfaces are down. */
+ if(NULL == p_acc_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,"no such ACTIVE access terminal\n");
+ ret = BCM_ERR_NOT_CONNECTED;
+ break;
+ }
+
+ /* If the specified access terminal is down, then it's interfaces are down. */
+ if(BCMBAL_STATE_UP != p_acc_term_inst->current_acc_term_obj_info.data.admin_state)
+ {
+ ret = BCM_ERR_NOT_CONNECTED;
+ break;
+ }
+
+ /* first get the index to the interface array from port id/type */
+ interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
+ if (interface_index >= INVALID_INTERFACE_INDEX)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,"INVALID port type/id (%s/%d) to interface index (%d)\n",
+ interface_type_str_get(key.intf_type), key.intf_id, interface_index);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* Retrieve the relevany default tm sched of the interface */
+ if (BCMBAL_INTF_TYPE_NNI == key.intf_type)
+ {
+ *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.us_tm;
+ }
+ else /*BCMBAL_INTF_TYPE_PON */
+ {
+ *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.ds_tm;
+ }
+ }while(0);
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function that returns the status of the specified interface object
+ *
+ * @param key An interface instance key
+ *
+ * @returns bcmbal_state
+ *****************************************************************************/
+bcmbal_status bcmbal_interface_status_get(bcmbal_interface_key key)
+{
+ bcmbal_state intf_status = BCMBAL_STATUS_DOWN;
+ acc_term_interface *p_acc_term_interface = bcmbal_interface_get(key);
+
+ if(NULL == p_acc_term_interface)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,"no such interface\n");
+ }
+ else
+ {
+ intf_status = p_acc_term_interface->current_int_obj_info.data.oper_status;
+ }
+ return intf_status;
+}
+/*****************************************************************************/
+/**
+ * @brief A function that returns the interface object
+ *
+ * @param key An interface instance key
+ *
+ * @returns acc_term_interface *p_acc_term_interface a pointer to the interface object
+ *****************************************************************************/
+static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key)
+{
+ acc_term_inst *p_acc_term_inst = NULL;
+ acc_term_interface *p_acc_term_interface = NULL;
+ uint32_t interface_index = INVALID_INTERFACE_INDEX;
+
+ do
+ {
+ /*
+ * See if the access-terminal is active
+ */
+ p_acc_term_inst = access_terminal_get();
+
+
+ /*
+ * If the specified access terminal is not active then it's interfaces are down.
+ */
+ if(NULL == p_acc_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "no such ACTIVE access terminal\n");
+ break;
+ }
+
+ /*
+ * Retrieve the interface
+ */
+ /* first get the index to the interface array from port id/type */
+ interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
+ if (interface_index >= INVALID_INTERFACE_INDEX)
+ {
+ BCM_LOG(ERROR, log_id_access_terminal,
+ "INVALID port type/id (%s/%d) to interface index (%d)\n",
+ interface_type_str_get(key.intf_type), key.intf_id, interface_index);
+ break;
+ }
+ p_acc_term_interface = &(p_acc_term_inst->intf_info.interface[interface_index]);
+
+ }while(0);
+
+
+ return p_acc_term_interface;
+}
+
+static char *interface_type_str_get(bcmbal_intf_type intf_type)
+{
+ return intf_type == BCMBAL_INTF_TYPE_NNI ? "NNI" :
+ intf_type == BCMBAL_INTF_TYPE_PON ? "PON" : "UNKNOWN TYPE";
+}
+/*@}*/
diff --git a/bal_release/src/core/main/acc_term_fsm.h b/bal_release/src/core/main/acc_term_fsm.h
new file mode 100644
index 0000000..c2337ae
--- /dev/null
+++ b/bal_release/src/core/main/acc_term_fsm.h
@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file acc_term_fsm.h
+ * @brief Code to support the BAL Access Terminal FSM
+ *
+ * @defgroup access_terminal Access Terminal
+ * @ingroup core
+ */
+
+
+#ifndef ACC_TERM_FSM_H
+#define ACC_TERM_FSM_H
+
+/*@{*/
+
+#include <bcm_topo.h>
+#include <bal_api.h>
+#include <sub_term_fsm.h>
+#include <tm_sched_fsm.h>
+
+
+/** An enumeration of the access-terminal FSM events.
+ */
+typedef enum
+{
+ ACC_TERM_FSM_EVENT_TYPE_NONE = -1,
+ ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP ,
+ ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN ,
+ ACC_TERM_FSM_EVENT_TYPE_INT_ADMIN_UP ,
+ ACC_TERM_FSM_EVENT_TYPE_INT_ADMIN_DN ,
+ ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG ,
+ ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG ,
+ ACC_TERM_FSM_EVENT_TYPE_TIMEOUT ,
+
+
+ ACC_TERM_FSM_EVENT_TYPE__LAST,
+ ACC_TERM_FSM_EVENT_TYPE__NUM_OF
+} acc_term_fsm_event_type;
+
+
+/** An enumeration of the access-terminal FSM states.
+ */
+typedef enum
+{
+ ACC_TERM_FSM_STATE_NONE = -1,
+ ACC_TERM_FSM_STATE_NULL ,
+ ACC_TERM_FSM_STATE_ADDING ,
+ ACC_TERM_FSM_STATE_ADDED ,
+ ACC_TERM_FSM_STATE_REMOVING ,
+
+ ACC_TERM_FSM_STATE__LAST,
+ ACC_TERM_FSM_STATE__NUM_OF
+} acc_term_fsm_state;
+
+/**
+ * A structure that defines the information associated with an
+ * access-terminal FSM event
+ */
+typedef struct acc_term_fsm_event
+{
+ acc_term_fsm_event_type event_type; /**< An FSM event */
+ void *msg; /**< A pointer to the message being processed by the FSM during an event */
+} acc_term_fsm_event;
+
+/**
+ * @brief A temporary set of definitions to support access-terminal interfaces.
+ * This should be replaced by a more generic mapping method.
+ * @note The max PON interface of 16 is a practical limit that access term will support for now.
+ */
+#define NUM_SUPPORTED_SUBSCRIBER_INTERFACES (16)
+#define NUM_SUPPORTED_NNI_INTERFACES (BCM_TOPO_MAX_NNI_PORTS)
+#define NUM_SUPPORTED_INTERFACES (NUM_SUPPORTED_SUBSCRIBER_INTERFACES + NUM_SUPPORTED_NNI_INTERFACES)
+/** invalid interface index - used for any error in mapping port type/id to interface index */
+#define INVALID_INTERFACE_INDEX (NUM_SUPPORTED_INTERFACES)
+
+#define BAL_ACC_TERM_MAX_FLOWS_PER_PON (1024)
+#define BAL_ACC_TERM_MAX_FLOWS (NUM_SUPPORTED_SUBSCRIBER_INTERFACES * BAL_ACC_TERM_MAX_FLOWS_PER_PON)
+
+typedef struct sub_term_id_entry
+{
+ bcmbal_sub_id sub_term_id;
+ TAILQ_ENTRY(sub_term_id_entry) next; /**< TAILQ link */
+}sub_term_id_entry;
+
+/**
+ * Two interface objects associated with the access-terminal.
+ * One stores the API requests, and one records the current
+ * state of the object.
+ */
+typedef struct acc_term_interface
+{
+ bcmbal_interface_cfg current_int_obj_info; /**< The current information for this interface (used for GET) */
+ bcmbal_interface_cfg api_req_int_obj_info; /**< The last interface object info received from the Public API */
+ uint16_t num_sub_terms_on_int; /**< The number of subscriber terminals on this interface */
+ TAILQ_HEAD(sub_term_id_list_head, sub_term_id_entry) sub_term_id_list;
+} acc_term_interface;
+
+/**
+ * The interface key of the instance being manipulated, and an array of interface objects associated
+ * with an access terminal instance.
+ */
+typedef struct acc_term_interface_info
+{
+ acc_term_interface interface[NUM_SUPPORTED_INTERFACES]; /**< All interface instances */
+
+}acc_term_interface_info;
+
+
+/**
+ * An structure defining an access terminal instance and its associated interfaces
+ */
+typedef struct acc_term_inst
+{
+ /**< The current information for this access-terminal (used for GET) */
+ bcmbal_access_terminal_cfg current_acc_term_obj_info;
+
+ /**< The last access-terminal object info received from the Public API */
+ bcmbal_access_terminal_cfg api_req_acc_term_obj_info;
+
+ acc_term_fsm_state fsm_state; /**< The access-terminal FSM state */
+ acc_term_interface_info intf_info; /**< The access-terminal interfaces */
+ bcmos_timer timer_info; /**< A structure used for the state machine timeout timer */
+
+} acc_term_inst;
+
+
+/*--- external function declarations ---*/
+extern bcmos_errno process_access_terminal_object(void *msg_payload);
+
+extern bcmos_errno process_access_terminal_util_msg(void *msg_payload);
+
+extern bcmos_errno process_interface_object(void *msg_payload);
+
+extern bcmos_errno process_interface_util_msg(void *msg_payload);
+
+extern bcmos_errno bcmbal_interface_sub_term_list_add(bcmbal_subscriber_terminal_key sub_term_key);
+
+extern bcmos_errno bcmbal_interface_sub_term_list_remove(bcmbal_subscriber_terminal_key sub_term_key);
+
+extern void access_terminal_fsm_init(void);
+
+extern bcmbal_status bcmbal_interface_status_get(bcmbal_interface_key key);
+
+extern bcmbal_status bcmbal_get_intf_oper_status_from_admin_state (bcmbal_state intf_admin_state);
+
+extern uint32_t bcmbal_port_type_and_id_to_interface_index(bcmbal_intf_type intf_type,
+ bcmbal_intf_id intf_id);
+extern bcmbal_status acc_term_status_get(void);
+
+extern bcmos_errno bcmbal_interface_sub_term_list_entry_add(bcmbal_subscriber_terminal_key sub_term_key);
+
+extern bcmos_errno bcmbal_interface_sub_term_list_entry_remove(bcmbal_subscriber_terminal_key sub_term_key);
+
+extern bcmos_errno bcmbal_interface_tm_get(bcmbal_interface_key key, bcmbal_tm_sched_id *id);
+
+extern bcmos_errno interface_tm_sched_unset(bcmbal_interface_key intf_key, bcmbal_tm_sched_key sched_key);
+
+extern bcmos_errno bcmbal_tm_sched_interface_tm_auto_create(bcmbal_interface_cfg *p_interface_info);
+
+extern bcmos_errno bcmbal_tm_sched_set_interface_owner(bcmbal_interface_key interface_key, tm_sched_inst *p_tm_sched_inst);
+
+extern bcmos_errno bcmbal_tm_sched_set_sub_term_owner( bcmbal_tm_sched_key tm_sched_key, const bcmbal_subscriber_terminal_cfg *p_sub_term_cfg);
+
+
+/*@}*/
+
+#endif /*ACC_TERM_FSM_H */
+
+
diff --git a/bal_release/src/core/main/bal_cli.c b/bal_release/src/core/main/bal_cli.c
new file mode 100644
index 0000000..cd2c389
--- /dev/null
+++ b/bal_release/src/core/main/bal_cli.c
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_cli.c
+ * @brief Sample CLI which is used to exercise the BAL Public API
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+
+#include <bal_common.h>
+
+#include <bal_core.h>
+#include <bal_api.h>
+#include <bal_api_cli.h>
+#include <bcmos_cli.h>
+#include <rsc_mgr_cli.h>
+#include <bal_switch_acc_term.h>
+#include <bal_mac_util.h>
+#include <bal_switch_util.h>
+#include "bal_cli.h"
+
+#ifdef OMCI_SVC
+#include <omci_svc.h>
+#include <omci_svc_cli.h>
+#endif
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+/*
+ * CLI logging device ids
+ */
+dev_log_id log_id_cli;
+
+/* CLI logging for ONU discovery */
+dev_log_id log_id_cli_disc;
+#endif
+bcmcli_session *current_session;
+
+/* user_exit_cb is only supported when BAL is built with a user application
+ * and run as a set of threads in that application (i.e. when bcmbal_init is
+ * called) */
+static bcmbal_exit_cb user_exit_cb;
+static bcmos_task bal_cli_thread;
+
+static const char *bal_iwf_mode_to_str(bcmbal_iwf_mode iwf_mode)
+{
+ static const char *str_table[BCMBAL_IWF_MODE__NUM_OF] =
+ {
+ [BCMBAL_IWF_MODE_DIRECT_MAPPING] = "direct_mapping",
+ [BCMBAL_IWF_MODE_PER_FLOW] = "per_flow",
+ };
+ return (iwf_mode >= BCMBAL_IWF_MODE__NUM_OF) ? "<unknown>" : str_table[iwf_mode];
+}
+
+static const char *bal_intf_maptable_to_str(bal_swapp_port_map_indx intf_maptable)
+{
+ static const char *str_table[BAL_SWAPP_PORT_MAP__NUM_OF] =
+ {
+ [BAL_SWAPP_PORT_MAP_GPON] = "gpon",
+ [BAL_SWAPP_PORT_MAP_GPON_V3] = "gpon v3",
+ [BAL_SWAPP_PORT_MAP_EXP] = "exp",
+ [BAL_SWAPP_PORT_MAP_EXP2] = "exp 2",
+ [BAL_SWAPP_PORT_MAP_SVK4] = "svk4",
+ [BAL_SWAPP_PORT_MAP_EPON_TDMA] = "epon_tdma",
+ [BAL_SWAPP_PORT_MAP_EPON_1G] = "epon_1g",
+ [BAL_SWAPP_PORT_MAP_EPON_10G] = "epon_10g",
+ };
+ return (intf_maptable >= BAL_SWAPP_PORT_MAP__NUM_OF) ? "<unknown>" : str_table[intf_maptable];
+}
+
+/*
+ * show_confif CLI command handler
+ */
+static bcmos_errno bal_show_config_cmd(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ const bcmbal_config_params *bal_config = bcmbal_config_get();
+ bcmolt_devid device_id;
+
+ bcmcli_session_print(session, "interworking mode is : %s\n", bal_iwf_mode_to_str(bal_config->iwf_mode));
+ bcmcli_session_print(session, "switch interface mapping table is : %s\n", bal_intf_maptable_to_str(bal_config->intf_maptable));
+ bcmcli_session_print(session, "mac is %s loopback mode \n", bcmbal_is_mac_in_loopback() ? "IN" : "NOT IN");
+ bcmcli_session_print(session, "number of nni ports is : %d \n", bal_config->num_nni_ports);
+ bcmcli_session_print(session, "port for trapped packets is : %d \n", bal_config->trap_udp_port);
+
+ BCM_TOPO_FOR_EACH_DEV(device_id)
+ {
+ bcmcli_session_print(session, "pon mode of device %d is %s , number of pons is %d\n", device_id,
+ bcm_topo_dev_get_pon_mode_str(device_id),bcm_topo_dev_get_max_pon(device_id));
+ }
+
+ return BCM_ERR_OK;
+}
+
+/* "quit" CLI command handler */
+static int _cmd_quit(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bcmcli_stop(sess);
+ bcmcli_session_print(sess, "BAL core CLI terminated by 'Quit' command\n");
+ return 0;
+}
+
+/* "sleep" CLI command handler */
+static bcmos_errno _cmd_sleep(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bcmos_usleep(parm[0].value.unumber);
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the BAL core debug CLI
+ *
+ * @returns BCM_ERR_OK
+ *
+ *****************************************************************************/
+static bcmos_errno bal_debug_init(void)
+{
+ bcmcli_entry *dir;
+
+ dir = bcmcli_dir_add(NULL, "debug", "BAL core debug CLI", BCMCLI_ACCESS_ADMIN, NULL);
+
+ /* Add the resource manager debug CLI */
+ rsc_mgr_cli_init(dir);
+ mac_util_cli_init(dir);
+
+ /* Add the switch util debug CLI */
+ sw_util_cli_init(dir);
+
+#ifdef OMCI_SVC
+ if (!omci_svc_is_loopback())
+ omci_svc_cli_init(dir);
+#endif
+
+ BCMCLI_MAKE_CMD(dir, "sleep", "Sleep for a specified number of usec", _cmd_sleep,
+ BCMCLI_MAKE_PARM("time to sleep (microseconds)", "time to sleep (microseconds)", BCMCLI_PARM_UDECIMAL, 0));
+
+ BCMCLI_MAKE_CMD_NOPARM(dir, "show_config", "show bal configuration", bal_show_config_cmd);
+
+ /* Add os CLI */
+ bcmos_cli_init(dir);
+
+ return BCM_ERR_OK;
+}
+
+/** BAL Indication callback handler */
+static void api_ind_cb_handler(bcmbal_obj *obj)
+{
+
+ if((BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL == obj->obj_type) &&
+ (BCMBAL_SUB_ID_UNKNOWN == ((bcmbal_subscriber_terminal_cfg *)obj)->key.sub_term_id))
+ {
+ bcmbal_serial_number *p_serial_number =
+ &(((bcmbal_subscriber_terminal_cfg *)obj)->data.serial_number);
+
+ BCM_LOG(DEBUG, log_id_cli_disc, "Discovered ONU serial number "
+ "%2X%2X%2X%2X%1X%1X%1X%1X%1X%1X%1X%1X "
+ "on PON %d\n",
+ p_serial_number->vendor_id[0],
+ p_serial_number->vendor_id[1],
+ p_serial_number->vendor_id[2],
+ p_serial_number->vendor_id[3],
+ p_serial_number->vendor_specific[0]>>4 & 0x0f,
+ p_serial_number->vendor_specific[0] & 0x0f,
+ p_serial_number->vendor_specific[1]>>4 & 0x0f,
+ p_serial_number->vendor_specific[1] & 0x0f,
+ p_serial_number->vendor_specific[2]>>4 & 0x0f,
+ p_serial_number->vendor_specific[2] & 0x0f,
+ p_serial_number->vendor_specific[3]>>4 & 0x0f,
+ p_serial_number->vendor_specific[3] & 0x0f,
+
+ ((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id);
+ }
+ else
+ {
+ char obj_key_str[256];
+
+ bal_obj_key_str_get(obj, obj_key_str);
+
+ BCM_LOG(INFO, log_id_cli,
+ "Processing CLI API \'%s\' IND callback (status is %s), (key is %s)\n",
+ bcmbal_objtype_str(obj->obj_type),
+ bcmos_strerror(obj->status),
+ obj_key_str);
+ }
+
+ return;
+}
+
+/* Execute CLI script */
+bcmos_errno bcmbal_cli_exec_script(const char *filename)
+{
+ char buf[1024];
+ FILE *f;
+
+ f = fopen(filename, "r");
+ if (!f)
+ {
+ printf("Can't open file %s for reading\n", filename);
+ return BCM_ERR_PARM;
+ }
+ while (!bcmcli_is_stopped(current_session) && !feof(f) &&
+ fgets(buf, sizeof(buf)-1, f))
+ {
+ bcmcli_print(current_session, "%s", buf);
+ bcmcli_parse(current_session, buf);
+ }
+ fclose(f);
+ return BCM_ERR_OK;
+}
+
+/* Execute init CLI script if any */
+bcmos_errno bcmbal_cli_exec_init_script(void)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ const char *init_script = bcmbal_config_get()->init_script;
+
+ if (init_script)
+ ret = bcmbal_cli_exec_script(init_script);
+
+ return ret;
+}
+
+/* CLI thread handler */
+static int _bal_cli_thread_handler(long data)
+{
+ char init_string[]="\n";
+ bcmcli_session *sess = current_session;
+
+ /* Switch to interactive mode if not stopped in the init script */
+ if (!bcmcli_is_stopped(sess))
+ {
+ /* Force a CLI command prompt
+ *
+ * The string passed into the parse function
+ * must be modifiable, so a string constant like
+ * bcmcli_parse(current_session, "\n") will not
+ * work.
+ */
+ bcmcli_parse(sess, init_string);
+
+ /* Process user input until EOF or quit command */
+ bcmcli_driver(sess);
+ };
+ BCM_LOG(INFO, log_id_core, "BAL CLI terminated\n");
+
+ /* call the user's exit callback, if any */
+ if(user_exit_cb) (*user_exit_cb)();
+
+ current_session = NULL;
+ bcmcli_session_close(sess);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+ * @brief This function initializes the BAL CLI
+ *
+ * @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise
+ *
+ *****************************************************************************/
+bcmos_errno bcmbal_cli_init(bcmbal_exit_cb exit_cb)
+{
+ const bcmbal_config_params *bal_config = bcmbal_config_get();
+ bcmcli_session_parm mon_session_parm = {};
+ bcmos_task_parm bal_cli_task_p = {};
+ bcmcli_entry *dir;
+ bcmos_errno ret;
+ bcmbal_cb_cfg cb_cfg = {};
+
+ mon_session_parm.access_right = bal_config->access;
+ mon_session_parm.line_edit_mode = bal_config->edit_mode;
+
+#ifdef ENABLE_LOG
+ /*
+ * Initialize the logging context
+ */
+ log_id_cli = bcm_dev_log_id_register("CLI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_cli == DEV_LOG_INVALID_ID);
+
+ log_id_cli_disc = bcm_dev_log_id_register("CLI_DISC", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_cli_disc == DEV_LOG_INVALID_ID);
+#endif
+
+ do
+ {
+ ret = bcmcli_session_open(&mon_session_parm, ¤t_session);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_cli, "Can't open CLI session\n");
+ break;
+ }
+
+ {
+ cb_cfg.obj_type = BCMBAL_OBJ_ID_ANY;
+ cb_cfg.ind_cb_hdlr = (f_bcmbal_ind_handler )api_ind_cb_handler;
+
+ bcmbal_subscribe_ind(&cb_cfg);
+ }
+
+ /* Initialize the bal api cli UI */
+ if(NULL == (dir = bcmcli_dir_add(NULL, "bal", "BAL API access", BCMCLI_ACCESS_ADMIN, NULL)))
+ {
+ BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL API CLI hierarchy\n");
+ break;
+ }
+
+ ret = bcmbal_apicli_add_commands(current_session, dir);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_cli, "Could not initialize the BAL CLI: %s\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /* Initialize the bal "debug" CLI */
+ ret = bal_debug_init();
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Error initializing the bal debug cli\n");
+ break;
+ }
+
+#ifdef ENABLE_LOG
+ /* Add logger CLI */
+ bcm_dev_log_cli_init(NULL);
+#endif
+
+ /* Add "quit" command at the top level */
+ BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", _cmd_quit);
+
+
+ /* Record the user's choice of callback function on our exit (may be NULL!) */
+ user_exit_cb = exit_cb;
+
+ /* Create BAL CLI thread */
+ bal_cli_task_p.name = "bal_cli_thread";
+ bal_cli_task_p.handler = _bal_cli_thread_handler;
+ bal_cli_task_p.priority = TASK_PRIORITY_CLI;
+
+ ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
+ if (BCM_ERR_OK != ret)
+ {
+ bcmos_printf("Couldn't create BAL CLI thread\n");
+ return ret;
+ }
+
+ } while(0);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief This function un-initializes the BAL CLI
+ *
+ * @returns BCM_ERR_OK
+ *
+ *****************************************************************************/
+bcmos_errno bcmbal_cli_finish(void)
+{
+ if (!current_session)
+ return BCM_ERR_OK;
+
+ bcmbal_cli_stop();
+
+ bcmos_task_destroy(&bal_cli_thread);
+
+ bcmbal_api_finish();
+
+ return BCM_ERR_OK;
+}
+
+
+/* Stop CLI */
+void bcmbal_cli_stop(void)
+{
+ if (current_session)
+ {
+ bcmcli_stop(current_session);
+ while (current_session)
+ bcmos_usleep(10000);
+ }
+}
+
+/* Is CLI terminated? */
+bcmos_bool bcmbal_cli_is_terminated(void)
+{
+ return (current_session == NULL) || bcmcli_is_stopped(current_session);
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/bal_cli.h b/bal_release/src/core/main/bal_cli.h
new file mode 100644
index 0000000..c4f19b6
--- /dev/null
+++ b/bal_release/src/core/main/bal_cli.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_cli.h
+ * @brief All functions and definitions supplied by the Sample CLI
+ *
+ */
+
+
+#ifndef BAL_CLI_H
+#define BAL_CLI_H
+
+#include <bcmcli.h>
+#include <bcmos_cli.h>
+#include <bal_core.h>
+/*@{*/
+
+extern bcmos_errno bcmbal_cli_init(bcmbal_exit_cb exit_cb);
+extern void bcmbal_cli_stop(void);
+extern bcmos_errno bcmbal_cli_finish(void);
+extern bcmos_errno bcmbal_cli_exec_init_script(void);
+extern bcmos_errno bcmbal_cli_exec_script(const char *filename);
+extern bcmos_bool bcmbal_cli_is_terminated(void);
+extern bcmcli_session *current_session;
+
+
+/*@}*/
+
+#endif /* BAL_CLI_H */
+
diff --git a/bal_release/src/core/main/bal_core.c b/bal_release/src/core/main/bal_core.c
new file mode 100644
index 0000000..fcc1573
--- /dev/null
+++ b/bal_release/src/core/main/bal_core.c
@@ -0,0 +1,1018 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_core.c
+ * @brief The code that comprises the main entry point and initialization
+ * code for the BAL Core.
+ *
+ * @addtogroup ctrlr
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bcmcli.h>
+#include <bal_switch_util.h>
+#include <bal_mac_util.h>
+#include <bal_version.h>
+#include <cmdline.h>
+#include <bal_core.h>
+#include <bal_cli.h>
+
+#include "rsc_mgr.h"
+#include "bal_worker.h"
+#include "bal_switch_acc_term.h"
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+#endif
+
+#ifdef OMCI_SVC
+#include <omci_svc.h>
+#endif
+
+#if defined(CONFIG_MAC_RPC)
+#define CONFIG_MAC_UTIL_IP_PORT
+#endif
+
+#ifdef ENABLE_LOG
+/*
+ * @brief The Logging device id for the BAL core
+ */
+dev_log_id log_id_core;
+#endif
+
+
+/*--- local function declarations ---*/
+static void welcome_to_bal(void);
+static bcmos_errno bal_core_init(void);
+static void bal_core_finish(void);
+static void bal_parse_config(struct bcmbal_config_params *p_params);
+static bcmos_errno bal_rpc_soc_gen(void);
+
+/*
+ * Worker thread and RX thread(s) data structures
+ */
+static bcmos_task core_worker_thread;
+
+static bcmos_errno _usage(const char *cmd);
+
+#define BAL_CHECK_IP_ARGUMENT(_i, _argc, _option) \
+ do { \
+ if (_i == _argc - 1) \
+ { \
+ printf("Error: IP:port is expected after %s option\n", _option); \
+ return _usage(argv[0]);\
+ }\
+ } while (0)
+
+
+#define CORE_MGMT_IP_PORT_CMDLINE_OPT "-C"
+#define BAL_API_IP_PORT_CMDLINE_OPT "-A"
+#define BAL_MAC_IP_PORT_CMDLINE_OPT "-M"
+#define BAL_SW_IP_CMDLINE_OPT "-S"
+#define BAL_INIT_SCRIPT_OPT "-f"
+#define BAL_LOG_FILE_OPT "-F"
+#define BAL_HELP_OPT "-h"
+#define BAL_LONG_HELP_OPT "--help"
+#define BAL_LEVEL_OPT "-L"
+#define BAL_NO_LOG_OPT "-nl"
+#define BAL_LOG_SYSLOG_OPT "-syslog"
+#define BAL_NO_LINEEDIT_OPT "-ne"
+
+
+/* Command line arguments */
+static cl_argument supported_cl_args[] =
+{
+#ifdef CONFIG_MAC_UTIL_IP_PORT
+ { .short_name = BAL_MAC_IP_PORT_CMDLINE_OPT,
+ .extra_arg = "mac_device_ip:port",
+ .description = "IP address:UDP port where the MAC device listens for RPC messages",
+ .flags = CL_ARGUMENT_FLAG_MANDATORY,
+ .owner = "BAL"
+ },
+#endif
+#ifdef CONFIG_SWITCH_RPC
+ { .short_name = BAL_SW_IP_CMDLINE_OPT,
+ .extra_arg = "switch_ip",
+ .description = "Switch IP address for RPC messages",
+ .flags = CL_ARGUMENT_FLAG_MANDATORY,
+ },
+#endif
+ { .short_name = CORE_MGMT_IP_PORT_CMDLINE_OPT,
+ .extra_arg = "core_mgmt_ip:port",
+ .description = "IP address:UDP port where the core listens for messages from the BAL Public API",
+ },
+ { .short_name = BAL_API_IP_PORT_CMDLINE_OPT,
+ .extra_arg = "al_api_mgmt ip:port",
+ .description = "IP address:UDP port where BAL Public API listens for responses from the core",
+ },
+ { .short_name = BAL_LEVEL_OPT,
+ .extra_arg = "level",
+ .description = "CLI level: guest | admin | debug",
+ },
+ { .short_name = BAL_NO_LINEEDIT_OPT,
+ .description = "Disable line editing",
+ },
+ { .short_name = BAL_INIT_SCRIPT_OPT,
+ .extra_arg = "script_file_name",
+ .description = "Script containing BAL CLI commands",
+ },
+#ifdef ENABLE_LOG
+ { .short_name = BAL_LOG_FILE_OPT,
+ .extra_arg = "log_file_name",
+ .description = "Log into file",
+ },
+ { .long_name = BAL_LOG_SYSLOG_OPT,
+ .description = "Log to syslog",
+ },
+ { .short_name = BAL_NO_LOG_OPT,
+ .description = "Disable logger",
+ },
+#endif
+#ifndef BUILD_OF_AGENT
+ { .short_name = BAL_HELP_OPT,
+ .long_name = BAL_LONG_HELP_OPT,
+ .description = "This help",
+ },
+#endif
+};
+
+/*
+ * The BAL core config file definitions
+ */
+
+#define TOPOLOGY_FILE_NAME "bal_topology.ini"
+#define CONFIG_FILE_NAME "bal_config.ini"
+#define MAX_CONFIG_FILE_LINE_LEN 256
+#define MAX_CONFIG_PARAM_NAME_LEN 64
+#define MAX_CONFIG_PARAM_VALUE_LEN 64
+
+bcmbal_config_params bal_config_params =
+{
+ .iwf_mode = BCMBAL_IWF_MODE_PER_FLOW,
+ .intf_maptable = 2,
+ .num_nni_ports = BCM_TOPO_MAX_NNI_PORTS,
+ /* The interface mapping table default value is set in the switch utilities */
+ .topo_params.pon_mode = BCM_TOPO_PON_MODE_INVALID,
+ /* Default CLI session parameters */
+ .access = BCMCLI_ACCESS_ADMIN,
+ .edit_mode = BCMCLI_LINE_EDIT_DEFAULT,
+};
+static bcmos_bool bal_initialized;
+
+#define RPC_SOC_TEMPLATE_FILE_NAME "rpc.soc.template"
+#define RPC_SOC_FILE_NAME "rpc.soc"
+#define MAX_CMD_LINE_LEN 256
+
+ /*
+ * An enumeration of the possible iwf modes
+ */
+static bcmcli_enum_val iwf_mode_enum[] = {
+ { .name="direct", .val=BCMBAL_IWF_MODE_DIRECT_MAPPING},
+ { .name="per_flow", .val=BCMBAL_IWF_MODE_PER_FLOW},
+ BCMCLI_ENUM_LAST
+};
+
+/**
+ * @brief The Broadcom Ltd logo.
+ */
+static const char *g_p_company_logo =
+"\n\n"
+" *\n"
+" * *\n"
+" * *\n"
+" * *\n"
+" * *\n"
+" * *\n"
+" * *\n"
+" * * * * * *\n"
+" * * * *\n\n"
+"Copyright (c) 2017 Broadcom Ltd\n\n";
+
+
+#ifdef ENABLE_LOG
+/* Create log_id for the core */
+static void bal_core_log_init(void)
+{
+ /* Register the core logging context */
+ log_id_core = bcm_dev_log_id_register("CORE_CTRLR", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_core == DEV_LOG_INVALID_ID);
+
+ bcm_dev_log_level_set_style(DEV_LOG_LEVEL_FATAL, BCM_DEV_LOG_STYLE_BOLD);
+ bcm_dev_log_level_set_style(DEV_LOG_LEVEL_ERROR, BCM_DEV_LOG_STYLE_BOLD);
+
+ BCM_LOG(DEBUG, log_id_core, "BAL Core is starting\n");
+}
+
+/* Initialize logger */
+static int bal_dev_log_time_to_str_cb(uint32_t bal_time, char *time_str, int time_str_size)
+{
+ /* Round timestamp to the nearest ms */
+ uint32_t time_ms = (bal_time + 500) / 1000;
+ return snprintf(time_str, time_str_size, "%05u.%03u", time_ms / 1000, time_ms % 1000);
+}
+#endif
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the system logging subsystem
+ *
+ * This function is executed at system startup time
+ *
+ *****************************************************************************/
+bcmos_errno bcmbal_log_init(void)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ const char *log_file_name = bal_config_params.log_file_name;
+ if (bal_config_params.disable_log)
+ return BCM_ERR_OK;
+ do
+ {
+ if (NULL == log_file_name && !bal_config_params.log_syslog)
+ {
+#define DEV_LOG_SIZE1 1<<20
+#define DEV_LOG_QUEUE_SIZE 1000
+ static uint8_t logger_buf1[DEV_LOG_SIZE1];
+ void *addresses[DEV_LOG_MAX_FILES] = {logger_buf1};
+ uint32_t sizes[DEV_LOG_MAX_FILES] = {sizeof(logger_buf1)};
+ uint32_t flags[DEV_LOG_MAX_FILES] = {BCM_DEV_LOG_FILE_FLAG_WRAP_AROUND};
+ /* Initialize the system logger for the core threads */
+ ret = bcm_dev_log_init_default_logger(addresses,
+ sizes,
+ flags,
+ BCM_SIZEOFARRAY(addresses),
+ 0x4000,
+ TASK_PRIORITY_DEV_LOG,
+ DEV_LOG_QUEUE_SIZE);
+ }
+ else
+ {
+ bcm_dev_log_parm dev_log_parm = {};
+ int nfiles = 0;
+ if (NULL != log_file_name)
+ {
+ dev_log_parm.log_file[nfiles].type = BCM_DEV_LOG_FILE_REGULAR;
+ dev_log_parm.log_file[nfiles].udef_parms = (char *)(long)log_file_name;
+ dev_log_parm.log_file[nfiles].flags = BCM_DEV_LOG_FILE_FLAG_VALID;
+ ++nfiles;
+ };
+ if (bal_config_params.log_syslog)
+ {
+ dev_log_parm.log_file[nfiles].type = BCM_DEV_LOG_FILE_SYSLOG;
+ dev_log_parm.log_file[nfiles].udef_parms = "BAL";
+ dev_log_parm.log_file[nfiles].flags = BCM_DEV_LOG_FILE_FLAG_VALID;
+ ++nfiles;
+ };
+ ret = bcm_dev_log_init_default_logger_ext(&dev_log_parm,
+ nfiles, /* Log into file and/or syslog */
+ 0x4000,
+ TASK_PRIORITY_DEV_LOG,
+ DEV_LOG_QUEUE_SIZE);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ printf("Error initializing logger default values (%s)\n", bcmos_strerror(ret));
+ break;
+ }
+
+ bcm_dev_log_set_time_to_str_cb(bal_dev_log_time_to_str_cb);
+ }
+ while(0);
+#endif /* #ifdef ENABLE_LOG */
+
+ return ret;
+}
+
+
+/* Parse command line parameters */
+bcmos_errno bcmbal_cmdline_parse(int argc, char *argv[])
+{
+ int i;
+
+ if (cl_validate(argc, argv, supported_cl_args, BCM_SIZEOFARRAY(supported_cl_args)) != BCM_ERR_OK)
+ return _usage(argv[0]);
+
+ /*
+ * Parse all optional arguments
+ */
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], CORE_MGMT_IP_PORT_CMDLINE_OPT))
+ {
+ BAL_CHECK_IP_ARGUMENT(i, argc, CORE_MGMT_IP_PORT_CMDLINE_OPT);
+ bal_config_params.core_mgmt_ip_port = argv[++i];
+ }
+ else if (!strcmp(argv[i], BAL_API_IP_PORT_CMDLINE_OPT))
+ {
+ BAL_CHECK_IP_ARGUMENT(i, argc, BAL_API_IP_PORT_CMDLINE_OPT);
+ bal_config_params.balapi_mgmt_ip_port = argv[++i];
+ }
+#ifdef CONFIG_MAC_UTIL_IP_PORT
+ else if (!strcmp(argv[i], BAL_MAC_IP_PORT_CMDLINE_OPT))
+ {
+ /* When we build for x86, this is a necessary argument, because the MAC device is
+ * remote from the BAL core. When we build for WRX, this argument isn't required
+ * because the MAC device is local and the mac_rpc_ip_port value is not used.
+ */
+ BAL_CHECK_IP_ARGUMENT(i, argc, BAL_MAC_IP_PORT_CMDLINE_OPT);
+ bal_config_params.mac_rpc_ip_port = argv[++i];
+ }
+#endif
+#ifdef CONFIG_SWITCH_RPC
+ else if (!strcmp(argv[i], BAL_SW_IP_CMDLINE_OPT))
+ {
+ BAL_CHECK_IP_ARGUMENT(i, argc, BAL_SW_IP_CMDLINE_OPT);
+ bal_config_params.sw_rpc_ip = argv[++i];
+ }
+#endif
+ else if (!strcmp(argv[i], BAL_LEVEL_OPT))
+ {
+ ++i;
+ if (!strcmp(argv[i], "admin"))
+ bal_config_params.access = BCMCLI_ACCESS_ADMIN;
+ else if (!strcmp(argv[i], "guest"))
+ bal_config_params.access = BCMCLI_ACCESS_GUEST;
+ else if (!strcmp(argv[i], "debug"))
+ bal_config_params.access = BCMCLI_ACCESS_DEBUG;
+ else
+ return _usage(argv[0]);
+ }
+ else if (!strcmp(argv[i], BAL_NO_LINEEDIT_OPT))
+ {
+ bal_config_params.edit_mode = BCMCLI_LINE_EDIT_DISABLE;
+ }
+#ifdef ENABLE_LOG
+ else if (!strcmp(argv[i], BAL_NO_LOG_OPT))
+ {
+ bal_config_params.disable_log = BCMOS_TRUE;
+ }
+ else if (!strcmp(argv[i], BAL_LOG_SYSLOG_OPT))
+ {
+ bal_config_params.log_syslog = BCMOS_TRUE;
+ }
+ else if (!strcmp(argv[i], BAL_LOG_FILE_OPT))
+ {
+ if (i == argc - 1)
+ {
+ bcmos_printf("Log file name is expected after %s option\n", BAL_LOG_FILE_OPT);
+ return _usage(argv[0]);
+ }
+ bal_config_params.log_file_name = argv[++i];
+ }
+#endif
+ else if (!strcmp(argv[i], BAL_INIT_SCRIPT_OPT))
+ {
+ if (i == argc - 1)
+ {
+ bcmos_printf("Script file name is expected after %s option\n", BAL_INIT_SCRIPT_OPT);
+ return _usage(argv[0]);
+ }
+ bal_config_params.init_script = argv[++i];
+ }
+ else if (!strcmp(argv[i], BAL_HELP_OPT) || !strcmp(argv[i], BAL_LONG_HELP_OPT))
+ {
+ return _usage(argv[0]);
+ }
+ else
+ {
+ /* We have encountered a non-mandatory command line option
+ * that we don't recognize. This is a fatal error. Print
+ * the proper command line invocation.
+ */
+ printf("Error: unrecognized cmdline option specified (%s)\n", argv[i]);
+ return _usage(argv[0]);
+ }
+ }
+
+ /*
+ * The user MUST specify the mac and switch IP:port for IPC
+ */
+ if (BCMOS_FALSE
+#ifndef BAL_MONOLITHIC
+ || (NULL == bal_config_params.core_mgmt_ip_port) || (NULL == bal_config_params.balapi_mgmt_ip_port)
+#endif
+#ifdef CONFIG_MAC_UTIL_IP_PORT
+ || ((BCMOS_TRUE != bcmbal_is_mac_in_loopback()) && (NULL == bal_config_params.mac_rpc_ip_port))
+#endif
+#ifdef CONFIG_SWITCH_RPC
+ || (NULL == bal_config_params.sw_rpc_ip)
+#endif
+ )
+ {
+ printf("Error: you must enter ALL mandatory cmdline options\n");
+ return _usage(argv[0]);
+ }
+
+ return BCM_ERR_OK;
+}
+
+/* This is BAL initialization function that is called when BAL is compiled
+ * as a library rather than stand-alone application.
+ * \param[in] argc Number of command line parameters
+ * \param[in] argv Command line parameter array
+ * \returns BCM_ERR_OK (0) if successful or error<0 in case of failure
+ */
+bcmos_errno bcmbal_init(void)
+{
+ bcmos_errno ret;
+
+ /* Read the bal config file (bal_config.ini) parameters, if the config file is present */
+ bal_parse_config(&bal_config_params);
+
+ /* Now initialize the system topology */
+ ret = bcm_topo_init((bal_config_params.topo_params.num_of_devs &&
+ bal_config_params.topo_params.num_of_pons_per_dev &&
+ bal_config_params.topo_params.pon_mode != BCM_TOPO_PON_MODE_INVALID) ?
+ &bal_config_params.topo_params : NULL, TOPOLOGY_FILE_NAME);
+
+ if(BCM_ERR_OK != ret)
+ {
+ bcmos_printf("Error initializing the system topology\n");
+ return ret;
+ }
+
+#ifdef ENABLE_LOG
+ bal_core_log_init();
+#endif
+
+ /* Generate rpc.soc from rpc.soc.template */
+ if (BCM_ERR_OK != (ret = bal_rpc_soc_gen()))
+ return ret;
+
+ do
+ {
+
+ /* Initialize the BAL core itself
+ * NOTE: It is assumed that logging has been successfully
+ * initialized before this call is made
+ */
+ ret = bal_core_init();
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Error initializing the bal core\n");
+ break;
+ }
+
+ /* Initialize the switch utilities */
+ ret = sw_util_init();
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Error initializing the bal switch utilities\n");
+ break;
+ }
+
+ /* Initialize the mac utilities */
+ ret = mac_util_init(bal_config_params.mac_rpc_ip_port);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Error initializing the bal mac utilities\n");
+ break;
+ }
+
+ /* Initialize the bal public api */
+ ret = bcmbal_api_init(bal_config_params.balapi_mgmt_ip_port, bal_config_params.core_mgmt_ip_port);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Could not initialize the BAL Public API\n");
+ break;
+ }
+
+ bal_initialized = BCMOS_TRUE;
+
+ /* Print out the welcome banner */
+ welcome_to_bal();
+ }
+ while(0);
+
+ return ret;
+}
+
+void bcmbal_finish(void)
+{
+ bcmbal_cli_finish();
+ if (bal_initialized)
+ bal_core_finish();
+}
+
+/* Top-level init sequence */
+bcmos_errno bcmbal_init_all(int argc, char *argv[], bcmbal_exit_cb exit_cb)
+{
+ bcmos_errno err;
+ err = bcmbal_cmdline_parse(argc, argv);
+ err = (err != BCM_ERR_OK) ? err : bcmos_init();
+ err = (err != BCM_ERR_OK) ? err : bcmbal_log_init();
+ err = (err != BCM_ERR_OK) ? err : bcmbal_init();
+ err = (err != BCM_ERR_OK) ? err : bcmbal_cli_init(exit_cb);
+ return err;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core command line usage function
+ *
+ * A function to display the proper bal_core command line format
+ *
+ * @param cmd A pointer to the command line string that the user entered to
+ * start the BAL core.
+ *
+ * @returns BCM_ERR_PARM - This function is always run as a result of the user
+ * entering an invalid value on the command line.
+ *
+ *****************************************************************************/
+static bcmos_errno _usage(const char *cmd)
+{
+#ifndef BUILD_OF_AGENT
+ /* For SDN_AGENT all parm usage info is printed in the agent's main */
+ cl_print_usage(cmd, NULL, supported_cl_args, BCM_SIZEOFARRAY(supported_cl_args), CL_ARGUMENT_USAGE_FLAG_NONE);
+#endif
+ return BCM_ERR_PARM;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core initialization function
+ *
+ * A function to initialize the BAL core and all its associated threads.
+ *
+ * @returns BCM_ERR_OK, or the return value from first function called
+ * that fails.
+ *
+ *****************************************************************************/
+static bcmos_errno bal_core_init(void)
+{
+ bcmos_task_parm task_p = {};
+ bcmos_module_parm module_p = {};
+ bcmos_errno ret = BCM_ERR_OK;
+ mgmt_queue_addr_ports mgmt_queue_info;
+
+ do
+ {
+ /* Create message queues */
+ mgmt_queue_info.core_mgmt_ip_port = bal_config_params.core_mgmt_ip_port;
+ mgmt_queue_info.balapi_mgmt_ip_port = bal_config_params.balapi_mgmt_ip_port;
+ ret = core_msg_queue_init(&mgmt_queue_info);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create message queues\n");
+ break;
+ }
+
+ /* Create worker thread & modules for mgmt messages */
+ task_p.name = "core_worker";
+ task_p.priority = TASK_PRIORITY_WORKER;
+
+ ret = bcmos_task_create(&core_worker_thread, &task_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create worker thread\n");
+ break;
+ }
+
+ /*
+ * Initialize the worker thread that was just spawned
+ */
+ core_worker_thread_init();
+
+ /*
+ * Now create the module for the worker thread
+ */
+ module_p.qparm.name = "core_worker_mgmt_module";
+ module_p.init = _bal_worker_mgmt_module_init;
+ ret = bcmos_module_create(BCMOS_MODULE_ID_WORKER_MGMT, &core_worker_thread, &module_p);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create mgmt worker module\n");
+ break;
+ }
+
+#ifdef CONFIG_SWITCH_RPC
+ ret = sw_util_pkt_send_init(bal_config_params.sw_rpc_ip, bal_config_params.pkt_send_svr_listen_port);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't initialize the packet send interface ret = %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_core,
+ "\"Packet send\" interface is initialized"
+ " to use server at %s:%d\n",
+ bal_config_params.sw_rpc_ip, bal_config_params.pkt_send_svr_listen_port );
+ }
+#endif
+ }
+ while(0);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core finish function
+ *
+ * A function to clean up the BAL core and all its associated threads on
+ * exit.
+ *
+ * @returns BCM_ERR_OK
+ *
+ *****************************************************************************/
+static void bal_core_finish(void)
+{
+ rsc_mgr_uninit();
+ mac_util_finish();
+ sw_util_finish();
+
+ core_worker_thread_finish();
+
+ bcmos_module_destroy(BCMOS_MODULE_ID_WORKER_MGMT);
+
+ bcmos_task_destroy(&core_worker_thread);
+
+ /* Let logger task have enough time to drain its message queue. */
+#ifdef ENABLE_LOG
+ bcmos_usleep(1000000);
+ bcm_dev_log_destroy();
+#endif
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to print the welcome banner for BAL
+ *
+ * This function is executed at system startup time
+ *
+ *****************************************************************************/
+static void welcome_to_bal(void)
+{
+ time_t tm = time(NULL);
+
+ /* @todo Don't print the welcome banner when running as a daemon */
+
+ printf("%s", g_p_company_logo);
+
+ BCM_LOG(INFO, log_id_core, "*** Welcome to BAL %s version %s (Built: %s)\n",
+#ifndef BUILD_OF_AGENT
+ "",
+#else
+ "OF-Agent",
+#endif
+ BAL_VERSION, BAL_BUILD_DATE);
+ BCM_LOG(INFO, log_id_core, "%s\n", BAL_BUILD_INFO);
+
+ BCM_LOG(INFO, log_id_core, "Time is: %s", asctime(localtime(&tm)));
+
+#ifdef TEST_SW_UTIL_LOOPBACK
+ BCM_LOG(INFO, log_id_core, "----BUILT WITH TEST_SW_UTIL_LOOPBACK\n");
+#endif
+
+ if (BCMOS_TRUE == bcmbal_is_mac_in_loopback())
+ {
+ BCM_LOG(INFO, log_id_core, "----CONFIGURED WITH MAC UTIL LOOPBACK\n");
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A trim helper function
+ *
+ * This function is used to get rid of trailing and leading whitespace
+ * including the "\n" from fgets()
+ *
+ * @param s A pointer to the string that is to be trimmed
+ *
+ * @returns -char *, the trimmed sting
+ *
+ */
+static char *trim (char * s)
+{
+ /* Initialize start, end pointers */
+ int len = strlen(s);
+ char *s1 = s, *s2 = &s[len - 1];
+
+ /* Trim and delimit right side */
+ while ( (isspace (*s2)) && (s2 >= s1) )
+ {
+ s2--;
+ len--;
+ }
+
+ *(s2+1) = '\0';
+
+ /* Trim left side */
+ while ( (isspace (*s1)) && (s1 < s2) )
+ {
+ s1++;
+ len--;
+ }
+
+ /* Copy finished string. Use memmove, as it is guaranteed to correctly handle overlapping strings. */
+ memmove (s, s1, len + 1);
+ return s;
+}
+
+/* A helper function for finding an enum array entry value, given it's name*/
+static long find_val_by_enum_name(bcmcli_enum_val *p_enum_array, const char * name)
+{
+ long val = -1;
+ int ii;
+
+
+ for(ii=0; p_enum_array[ii].name != NULL; ii++)
+ {
+ if(0 == strcmp(name, p_enum_array[ii].name))
+ {
+ val = p_enum_array[ii].val;
+ }
+ }
+
+ return val;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function that reads bal config file
+ *
+ * This function is used to read the bal config file into the
+ * bcmbal_config_params structure.
+ *
+ * The config file is defined to be named "bal_config.ini" and is
+ * of the format:
+ * param_name=param_value
+ *
+ * @param p_params A pointer to the core configuration parameters
+ *
+ * @returns void
+ *
+ */
+static void bal_parse_config(bcmbal_config_params *p_params)
+{
+ char *s, buff[MAX_CONFIG_FILE_LINE_LEN];
+ char name[MAX_CONFIG_PARAM_NAME_LEN], value[MAX_CONFIG_PARAM_VALUE_LEN];
+ FILE *fp = fopen (CONFIG_FILE_NAME, "r");
+
+ if (fp == NULL)
+ {
+ printf("No config file (%s) found\n", CONFIG_FILE_NAME);
+ return;
+ }
+
+ printf("BAL configuration params as read from %s:\n", CONFIG_FILE_NAME);
+
+ /* Read next line */
+ while ((s = fgets (buff, sizeof buff, fp)) != NULL)
+ {
+ /* Skip blank lines and comments */
+ if (buff[0] == '\n' || buff[0] == '#')
+ continue;
+
+ /* Parse name/value pair from line */
+ s = strtok (buff, "=");
+ if (s==NULL)
+ {
+ continue;
+ }
+ else
+ {
+ strncpy (name, s, MAX_CONFIG_PARAM_NAME_LEN);
+ }
+
+ s = strtok (NULL, "=");
+
+ if (s==NULL)
+ {
+ continue;
+ }
+ else
+ {
+ strncpy (value, s, MAX_CONFIG_PARAM_VALUE_LEN);
+ }
+
+ trim (value);
+
+ printf("%s=%s\n", name, value);
+
+ /* Copy into correct entry in parameters struct */
+ if(strcmp(name, "iwf_mode")==0)
+ {
+ p_params->iwf_mode = find_val_by_enum_name(iwf_mode_enum, value);
+ }
+ else if(strcmp(name, "intf_maptable")==0)
+ {
+ uint32_t intf_map_tbl_idx;
+
+ intf_map_tbl_idx = atoi(value);
+
+ if(BCM_ERR_OK != bal_bcm_intf_maptable_set(intf_map_tbl_idx))
+ {
+ printf("error: value (%u) is not a valid index, ignored", intf_map_tbl_idx);
+ }
+ else
+ {
+ p_params->intf_maptable = atoi(value);
+ }
+ }
+ else if(strcmp(name, "trap_udp_port")==0)
+ {
+ uint32_t udp_port;
+
+ udp_port = atoi(value);
+
+ if(BCM_ERR_OK != bal_bcm_trap_rcv_port_set(udp_port))
+ {
+ printf("error: value (%u) is not a valid port, ignored", udp_port);
+ }
+ else
+ {
+ p_params->trap_udp_port = udp_port;
+ }
+ }
+ else if(strcmp(name, "ds_sched_mode")==0)
+ {
+ uint32_t sched_mode;
+
+ sched_mode = atoi(value);
+
+ if(BCM_ERR_OK != bal_bcm_ds_sched_mode_set(sched_mode))
+ {
+ printf("error: value (%u) is not a valid sched mode, ignored", sched_mode);
+ }
+ else
+ {
+ p_params->ds_sched_mode = sched_mode;
+ }
+ }
+ else if(strcmp(name, "num_nni_ports")==0)
+ {
+
+ p_params->num_nni_ports = atoi(value);
+ bcm_topo_dev_set_max_nni(0, p_params->num_nni_ports);
+
+ }
+ else if(strcmp(name, "pkt_send_svr_listen_port")==0)
+ {
+
+ p_params->pkt_send_svr_listen_port = atoi(value);
+
+ }
+ else if(strcmp(name, "topology.num_of_devs")==0)
+ {
+ p_params->topo_params.num_of_devs = atoi(value);
+ }
+ else if(strcmp(name, "topology.num_of_pons_per_dev")==0)
+ {
+ p_params->topo_params.num_of_pons_per_dev = atoi(value);
+ }
+ else if(strcmp(name, "topology.pon_mode")==0)
+ {
+ if(strcmp(value, "gpon")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_GPON;
+ else if(strcmp(value, "xgpon")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_XGPON;
+ else if(strcmp(value, "xgs")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_XGS;
+ else if(strcmp(value, "epon_tdma")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_EPON_TDMA;
+ else if(strcmp(value, "epon_1g")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_EPON_1G;
+ else if(strcmp(value, "epon_10g")==0)
+ p_params->topo_params.pon_mode = BCM_TOPO_PON_MODE_EPON_10G;
+ }
+ else if(strcmp(name, "mac_loopback")==0)
+ {
+ if(strcmp(value, "y")==0)
+ {
+ p_params->loopback_modes_bit_mask |= BIT_FIELD_MAC_IN_LOOPBACK;
+ }
+ }
+#ifdef OMCI_SVC
+ else if(strcmp(name, "omci_loopback")==0)
+ {
+ if(strcmp(value, "y")==0)
+ {
+ omci_svc_set_loopback(BCMOS_TRUE);
+ }
+ }
+#endif
+ else if(strncmp(name, "autoneg_nni", 11)==0)
+ {
+ int intf_id = atoi(name+11);
+ if ((unsigned)intf_id >= BAL_API_MAX_INTF_ID)
+ {
+ printf("error: %s: NNI %d is invalid, ignored", name, intf_id);
+ continue;
+ }
+ if(strcmp(value, "y")==0)
+ {
+ p_params->nni_autoneg_bit_mask |= (1 << intf_id);
+ }
+ }
+
+ else
+ {
+ printf("%s/%s: Unknown name/value config file pair!\n",name, value);
+ }
+ }//while
+
+ printf("\n");
+
+ /* Close file */
+ fclose (fp);
+}
+
+static bcmos_errno bal_rpc_soc_gen(void)
+{
+#ifndef TEST_SW_UTIL_LOOPBACK
+#ifdef CONFIG_SWITCH_RPC
+ char cmd[MAX_CMD_LINE_LEN];
+ FILE *fp = fopen (RPC_SOC_TEMPLATE_FILE_NAME, "r");
+ int rc;
+
+ if (fp == NULL)
+ {
+ printf("%s not found\n", RPC_SOC_TEMPLATE_FILE_NAME);
+ return BCM_ERR_NOENT;
+ }
+ fclose (fp);
+
+ snprintf(cmd, MAX_CMD_LINE_LEN, "sed -e \"s/\\\\\\$DIP\\\\$/%s/\" %s > %s",
+ bal_config_params.sw_rpc_ip, RPC_SOC_TEMPLATE_FILE_NAME, RPC_SOC_FILE_NAME);
+ rc = system(cmd);
+ if (rc || WEXITSTATUS(rc))
+ {
+ printf("Failed to generate %s from %s\n", RPC_SOC_FILE_NAME, RPC_SOC_TEMPLATE_FILE_NAME);
+ return BCM_ERR_INTERNAL;
+ }
+#endif
+#endif
+ return BCM_ERR_OK;
+}
+
+
+uint16_t bcmbal_num_nni_ports_get(void)
+{
+ return bal_config_params.num_nni_ports;
+}
+
+bcmos_bool bcmbal_is_mac_in_loopback(void)
+{
+ return IS_MAC_IN_LOOPBACK(bal_config_params.loopback_modes_bit_mask);
+}
+
+bcmos_bool bcmbal_is_nni_autoneg_on(bcmbal_intf_id intf_id)
+{
+ return IS_NNI_INTF_AUTONEG_ON(bal_config_params.nni_autoneg_bit_mask, intf_id);
+}
+
+/* Get supported command line argument list */
+int bcmbal_supported_args_get(cl_argument supported_args[], int size)
+{
+ int i;
+ for (i=0; i<BCM_SIZEOFARRAY(supported_cl_args); i++)
+ {
+ if (i < size)
+ supported_args[i] = supported_cl_args[i];
+ }
+ return i;
+}
+
+/* Get BAL configuration */
+const bcmbal_config_params *bcmbal_config_get(void)
+{
+ return &bal_config_params;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/bal_core.h b/bal_release/src/core/main/bal_core.h
new file mode 100644
index 0000000..4410c47
--- /dev/null
+++ b/bal_release/src/core/main/bal_core.h
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_core.h
+ * @brief The include files common to all core files
+ *
+ * @addtogroup ctrlr
+ */
+
+
+#ifndef COREMAIN_H
+#define COREMAIN_H
+
+/*@{*/
+#include <bcmos_system.h>
+#include <bal_objs.h>
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+#endif
+#include <bcm_topo.h>
+#include <cmdline.h>
+
+extern dev_log_id log_id_core;
+
+
+#define BIT_FIELD_MAC_IN_LOOPBACK 0x01
+#define BIT_FIELD_SWITCH_IN_LOOPBACK 0x02
+#define IS_MAC_IN_LOOPBACK(config) ((config) & BIT_FIELD_MAC_IN_LOOPBACK)
+#define IS_NNI_INTF_AUTONEG_ON(config, intf) (config & (1 << intf))
+
+typedef struct bcmbal_config_params
+{
+ bcmbal_iwf_mode iwf_mode;
+ uint32_t intf_maptable;
+ uint32_t trap_udp_port;
+ uint16_t num_nni_ports;
+ uint32_t ds_sched_mode;
+ uint32_t pkt_send_svr_listen_port; /* The port number where the bcm.user process listens for packet send messages from the core */
+ uint8_t loopback_modes_bit_mask; /* mac | switch | something else in loopback mode */
+ bcm_topo_params topo_params;
+ uint32_t nni_autoneg_bit_mask; /* NNI autoneg is ON */
+
+ /*
+ * IP:Port strings specifying IP:Port assignments of the queues
+ * required for IPC between BAL components
+ */
+ const char *core_mgmt_ip_port;
+ const char *balapi_mgmt_ip_port;
+ const char *mac_rpc_ip_port;
+ const char *sw_rpc_ip;
+
+ /* CLI session configuration */
+ bcmcli_access_right access;
+ bcmcli_line_edit_mode edit_mode;
+ const char *init_script;
+
+ /* Logger parameters */
+ bcmos_bool disable_log;
+ const char *log_file_name;
+ bcmos_bool log_syslog;
+} bcmbal_config_params;
+
+extern bcmos_errno bcmbal_init(void);
+extern void bcmbal_finish(void);
+extern int bcmbal_supported_args_get(cl_argument supported_args[], int size);
+extern bcmos_errno bcmbal_cmdline_parse(int argc, char *argv[]);
+extern bcmos_errno bcmbal_log_init(void);
+extern const bcmbal_config_params *bcmbal_config_get(void);
+
+typedef void (* bcmbal_exit_cb)(void);
+
+/* Top-level initialization sequence
+ * - parse commend line
+ * - initialize OS abstraction
+ * - initialize logger
+ * - initialize BAL core and utils
+ * - initialize BAL CLI
+ */
+extern bcmos_errno bcmbal_init_all(int argc, char *argv[], bcmbal_exit_cb exit_cb);
+
+extern bcmos_bool bcmbal_is_mac_in_loopback(void);
+
+extern bcmos_bool bcmbal_is_nni_autoneg_on(bcmbal_intf_id intf_id);
+
+/*@}*/
+
+#endif /*COREMAIN_H*/
+
diff --git a/bal_release/src/core/main/bal_worker.c b/bal_release/src/core/main/bal_worker.c
new file mode 100644
index 0000000..98f50be
--- /dev/null
+++ b/bal_release/src/core/main/bal_worker.c
@@ -0,0 +1,793 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_worker.c
+ * @brief Initialization and message handler functions for the BAL Core
+ * worker thread including all core FSM initialization.
+ *
+ * @addtogroup ctrlr
+ */
+
+/*@{*/
+
+/* Project includes */
+#include <bcmos_system.h>
+#include <bal_api.h>
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "acc_term_fsm.h"
+#include "flow_fsm.h"
+#include "group_fsm.h"
+#include "sub_term_fsm.h"
+#include "tm_sched_fsm.h"
+#include "tm_queue_fsm.h"
+#include "fsm_common.h"
+#include "bal_api_worker.h"
+#include "bal_obj_msg_pack_unpack.h"
+
+#include "bal_dpp_acc_term.h"
+#include "rsc_mgr.h"
+
+#include <arpa/inet.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+/*
+ * @brief The logging device id for the core
+ */
+extern dev_log_id log_id_core;
+#endif
+
+/* Local function declarations */
+static void core_mgmt_msg_handler(bcmos_module_id module_id, bcmos_msg *msg);
+static bcmos_errno process_mgmt_msg(void *msg_payload);
+static bcmos_errno process_util_msg(void *msg_payload);
+
+static int _bal_mgmt_rx_handler(long data);
+
+static bcmos_errno process_packet_object(void *msg_payload);
+
+/*
+ * @brief The BAL core management queue. These are the queues through which the core
+ * converses with the Public API. The remote endpoint of these queues are the
+ * BAL API backend.
+ */
+static bcmos_msg_queue core_mgmt_queue;
+static bcmos_msg_queue core_api_queue;
+static bcmos_msg_queue core_api_ind_queue;
+bcmos_msg_queue *p_bal_core_queue;
+bcmos_msg_queue *p_bal_core_to_api_queue;
+bcmos_msg_queue *p_bal_core_to_api_ind_queue;
+
+/*
+ * @brief The rx thread for management message reception
+ */
+static bcmos_task rx_mgmt_thread;
+
+/*****************************************************************************/
+/**
+ * @brief Initialize the worker thread
+ *
+ * A Worker module function that initializes all of the data structures and
+ * FSMs associated with the BAL core. This function called from bal_core_init
+ * during BAL core startup.
+ *
+ *****************************************************************************/
+void core_worker_thread_init(void)
+{
+ /*
+ * Initialize all of the worker thread hosted FSMs and the resource manager
+ */
+
+ rsc_mgr_init();
+
+ tm_queue_fsm_init();
+
+ tm_sched_fsm_init();
+
+ access_terminal_fsm_init();
+
+ flow_fsm_init();
+
+ sub_term_fsm_init();
+
+ group_fsm_init();
+
+
+ return;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Finish the worker thread
+ *
+ * A Worker module function that un-initializes all of the data structures and
+ * FSMs associated with the BAL core. This function called from bal_core_init
+ * during BAL core cleanup on exit.
+ *
+ *****************************************************************************/
+void core_worker_thread_finish(void)
+{
+ /*
+ * Un-initialize the worker thread owned data structures. etc.
+ */
+ bcmos_msg_unregister(BCMBAL_MGMT_MSG, 0, BCMOS_MODULE_ID_WORKER_MGMT);
+
+ bcmos_msg_unregister(BCMBAL_MAC_UTIL_MSG, 0, BCMOS_MODULE_ID_WORKER_MGMT);
+
+ bcmos_task_destroy(&rx_mgmt_thread);
+
+ sub_term_fsm_finish();
+
+ flow_fsm_finish();
+
+ group_fsm_finish();
+
+ tm_sched_fsm_finish();
+
+ tm_queue_fsm_finish();
+
+ bcmos_msg_queue_destroy(&core_mgmt_queue);
+
+ if (p_bal_core_to_api_queue == &core_api_queue)
+ bcmos_msg_queue_destroy(p_bal_core_to_api_queue);
+
+ if (p_bal_core_to_api_ind_queue == &core_api_ind_queue)
+ bcmos_msg_queue_destroy(p_bal_core_to_api_ind_queue);
+
+ return;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core management message queue init
+ *
+ * A initialization function for the worker module.
+ * It creates message queues for communication with API layer and UTILS
+ *
+ * @param mgmt_queue_info A pointer to the ip:port addresses required for the msg queues.
+ * The ip:port addresses can be NULL in BAL_MONOLITHIC mode. In this case
+ * inter-thread queues will be used for communication.
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+bcmos_errno core_msg_queue_init(mgmt_queue_addr_ports *mgmt_queue_info)
+{
+ bcmos_msg_queue_parm msg_q_p = {};
+ bcmos_errno ret;
+
+ do
+ {
+ /* Create core queue. BAL core listens on this queue
+ * for public API calls and indications from the UTils
+ */
+ msg_q_p.name = "mgmt_rx_q";
+ if (NULL != mgmt_queue_info->core_mgmt_ip_port)
+ {
+ /* The queue allows sending from core_mgmt_ip_port and receiving at core_mgmt_ip_port */
+ msg_q_p.local_ep_address = mgmt_queue_info->core_mgmt_ip_port;
+ msg_q_p.remote_ep_address = mgmt_queue_info->core_mgmt_ip_port;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+ }
+ else
+ {
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_LOCAL;
+ }
+ ret = bcmos_msg_queue_create(&core_mgmt_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create rx mgmt queue\n");
+ break;
+ }
+ p_bal_core_queue = &core_mgmt_queue;
+#ifdef BAL_MONOLITHIC
+ if (NULL == mgmt_queue_info->core_mgmt_ip_port)
+ p_balapi_to_core_queue = p_bal_core_queue;
+#endif
+
+ /* Now create a TX queue for sending replies from the core to API.
+ * Only do it if using socket transport. In case of inter-thread queues
+ * it will be created by API layer
+ */
+ if (NULL != mgmt_queue_info->balapi_mgmt_ip_port)
+ {
+ uint16_t portnum;
+ char *p_portnum_str;
+ char balapi_ind_port_str[256];
+
+ msg_q_p.name = "mgmt_to_api_q";
+ msg_q_p.local_ep_address = NULL;
+ msg_q_p.remote_ep_address = mgmt_queue_info->balapi_mgmt_ip_port;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+ ret = bcmos_msg_queue_create(&core_api_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create tx mgmt queue\n");
+ break;
+ }
+ p_bal_core_to_api_queue = &core_api_queue;
+
+ /*
+ * make a copy of the user chosen bal api mgmt port
+ */
+ strcpy(balapi_ind_port_str, mgmt_queue_info->balapi_mgmt_ip_port);
+
+ /* Find the port number */
+ p_portnum_str = strchr(balapi_ind_port_str, ':') + 1;
+
+ /* convert to an integer and increment it by one */
+ portnum = atoi(p_portnum_str) + 1;
+
+ /* create the new string defining the BAL API indication port */
+ sprintf(p_portnum_str,"%d", portnum);
+
+ /* Create core->API indication queue
+ */
+ msg_q_p.name = "mgmt_ind_q";
+
+ /* Set up the management IP:port access parameters to allow the core to send indications to
+ * the BAL public API - this is a TX queue only!.
+ */
+ msg_q_p.local_ep_address = NULL;
+ msg_q_p.remote_ep_address = balapi_ind_port_str;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+
+ ret = bcmos_msg_queue_create(&core_api_ind_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create the core tx indication queue\n");
+ break;
+ }
+
+ BCM_LOG(DEBUG, log_id_core, "Created the core tx indication queue\n");
+
+ p_bal_core_to_api_ind_queue = &core_api_ind_queue;
+ }
+ } while (0);
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core management worker module init
+ *
+ * A initialization function for the worker module.
+ * It registers for messages that this module is expected to process.
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+bcmos_errno _bal_worker_mgmt_module_init(long data)
+{
+
+ bcmos_task_parm task_p = {};
+ bcmos_errno ret = BCM_ERR_OK;
+
+ do
+ {
+
+ /* Create Mgmt RX thread */
+ task_p.name = "mgmt_mgmt_rx";
+ task_p.priority = TASK_PRIORITY_IPC_RX;
+ task_p.handler = _bal_mgmt_rx_handler;
+ task_p.data = (long)p_bal_core_queue;
+
+ ret = bcmos_task_create(&rx_mgmt_thread, &task_p);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_core, "Couldn't create Mgmt RX thread\n");
+ break;
+ }
+
+ /* Register the message types to be handled by the mgmt module
+ */
+ bcmos_msg_register(BCMBAL_MGMT_MSG, 0, BCMOS_MODULE_ID_WORKER_MGMT, core_mgmt_msg_handler);
+ bcmos_msg_register(BCMBAL_MAC_UTIL_MSG, 0, BCMOS_MODULE_ID_WORKER_MGMT, core_util_msg_handler);
+ }
+ while(0);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Mgmt RX handler
+ *
+ * This handler is executed in the context of an RX thread. It's purpose
+ * is to dispatch the message received here to the module that has registered
+ * to process this message. The message is then processed in the context
+ * of the thread to which that module is attached.
+ *
+ * @param data A pointer to the received message
+ *
+ * @returns 0 on success, -EINVAL on failure
+ *
+ *****************************************************************************/
+static int _bal_mgmt_rx_handler(long data)
+{
+ bcmos_msg_queue *rxq = (bcmos_msg_queue *)data;
+ bcmos_task *my_task = bcmos_task_current();
+ void *payload;
+ bcmos_msg *msg;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ while (!my_task->destroy_request)
+ {
+ payload = NULL;
+ ret = bcmbal_msg_recv(rxq, BCMOS_WAIT_FOREVER, &payload);
+ if (ret)
+ {
+ /* Unexpected failure */
+ BCM_LOG(ERROR, log_id_core, "bcmbal_msg_recv() -> %s\n", bcmos_strerror(ret));
+ continue;
+ }
+
+ /* Message received */
+ BCM_LOG(DEBUG, log_id_core, "bcmbal_msg_recv(%p) -> %s\n", payload, bcmos_strerror(ret));
+
+ /*
+ * Got a message, so now dispatch it. This will result in one
+ * of the modules (registered for the message being processed)
+ * executing its message callback handler.
+ *
+ */
+ msg = bcmbal_bcmos_hdr_get(payload);
+ ret = bcmos_msg_dispatch(msg, BCMOS_MSG_SEND_AUTO_FREE);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_core,
+ "Couldn't dispatch message %d:%d\n",
+ (int)msg->type, (int)msg->instance);
+ }
+ }
+
+ my_task->destroyed = BCMOS_TRUE;
+
+ return (BCM_ERR_OK == ret) ? 0 : -EINVAL;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core management message handler
+ *
+ * A function that handlers messages received from the
+ * BAL public API via an RX thread.
+ *
+ * This function executes in the context of the worker thread.
+ *
+ * @param module_id The index of the module that this message handler
+ * is associated with.
+ *
+ * @param msg A pointer to the received message to be processed
+ *
+ *****************************************************************************/
+static void core_mgmt_msg_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+
+ void *msg_payload;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg);
+
+ /*
+ * @to-do
+ * validate the message major and minor version is correct
+ */
+
+ /*
+ * Point to the message payload for further processing
+ */
+ msg_payload = bcmbal_payload_ptr_get(bcmbal_bal_hdr_get_by_bcmos_hdr(msg));
+
+ /*
+ * These are messages from the BAL Public API or the UTILS
+ *
+ * - call into appropriate FSM
+ *
+ */
+ BCM_LOG(DEBUG, log_id_core, "Received a mgmt message (payload at %p)\n", msg_payload);
+
+
+ if(BCMBAL_MGMT_MSG == bcmbal_type_major_get(msg_payload) &&
+ BAL_SUBSYSTEM_PUBLIC_API == bcmbal_sender_get(msg_payload))
+ {
+ /* Process the message */
+ process_mgmt_msg(msg_payload);
+ }
+ else
+ {
+ BCM_LOG(FATAL, log_id_core, "message received with wrong major type/subsystem combination (%d/\%d)\n",
+ bcmbal_type_major_get(msg_payload),
+ bcmbal_sender_get(msg_payload));
+
+ BUG_ON(BCMOS_TRUE);
+ }
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core management message processing function
+ *
+ * A Worker module function that handles messages received from the
+ * BAL public API or UTILs via an RX thread.
+ *
+ * This function executes in the context of the worker thread
+ *
+ * @param msg_payload A pointer to the message to be processed
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+static bcmos_errno process_mgmt_msg(void *msg_payload)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_obj_id objtype;
+
+ BCM_LOG(DEBUG, log_id_core, "Processing a management message\n");
+
+ objtype = bcmbal_msg_id_obj_get(msg_payload);
+
+ /*
+ * Process the message based on the type of BAL object and sender
+ * in the message.
+ */
+ switch(objtype)
+ {
+ case BCMBAL_OBJ_ID_FLOW:
+ {
+ ret = process_flow_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ {
+ ret = process_group_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ {
+ ret = process_access_terminal_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ {
+ ret = process_interface_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ {
+ ret = process_subscriber_terminal_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_PACKET:
+ {
+
+ ret = process_packet_object(msg_payload);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, ((bcmbal_obj *)msg_payload)->type, log_id_core);
+
+ break;
+
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ {
+ ret = process_tm_sched_object(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_TM_QUEUE:
+ {
+ ret = process_tm_queue_object(msg_payload);
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_core,
+ "Unsupported object detected in management message\n");
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, ((bcmbal_obj *)msg_payload)->type, log_id_core);
+
+ break;
+ }
+ }
+ bcmbal_msg_free(msg_payload);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core util message handler
+ *
+ * A function that handlers messages received from the
+ * BAL utils via an RX thread.
+ *
+ * This function executes in the context of the worker thread.
+ *
+ * @param module_id The index of the module that this message handler
+ * is associated with.
+ *
+ * @param msg A pointer to the received message to be processed
+ *
+ *****************************************************************************/
+void core_util_msg_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+
+ void *msg_payload;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg);
+
+ /*
+ * @to-do
+ * validate the message major and minor version is correct
+ */
+
+ /*
+ * Point to the message payload for further processing
+ */
+ msg_payload = bcmbal_payload_ptr_get(bcmbal_bal_hdr_get_by_bcmos_hdr(msg));
+
+ /*
+ * These are messages from the BAL Utils
+ *
+ * - call into appropriate FSM
+ *
+ */
+ BCM_LOG(DEBUG, log_id_core, "Received a Util message (payload at %p)\n", msg_payload);
+
+ if(BCMBAL_MAC_UTIL_MSG == bcmbal_type_major_get(msg_payload) &&
+ BAL_SUBSYSTEM_MAC_UTIL == bcmbal_sender_get(msg_payload))
+ {
+ /* Process the message */
+ process_util_msg(msg_payload);
+
+ }
+ else
+ {
+ BCM_LOG(FATAL, log_id_core, "message received with wrong major type/subsystem combination (%d/\%d)\n",
+ bcmbal_type_major_get(msg_payload),
+ bcmbal_sender_get(msg_payload));
+
+ BUG_ON(BCMOS_TRUE);
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core util message processing function
+ *
+ * A Worker module function that handles messages received from the
+ * BAL utils via an RX thread.
+ *
+ * This function executes in the context of the worker thread
+ *
+ * @param msg_payload A pointer to the message to be processed
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+static bcmos_errno process_util_msg(void *msg_payload)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_obj_id objtype;
+
+ BCM_LOG(DEBUG, log_id_core, "Processing a util message\n");
+
+ objtype = bcmbal_msg_id_obj_get(msg_payload);
+
+ /*
+ * Process the util message based on the type of BAL object
+ * in the message.
+ */
+ switch(objtype)
+ {
+ case BCMBAL_OBJ_ID_FLOW:
+ {
+ ret = process_flow_util_msg(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ {
+ ret = process_group_util_msg(msg_payload);
+ break;
+ }
+
+
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ {
+ ret = process_access_terminal_util_msg(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ {
+ ret = process_interface_util_msg(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ {
+ ret = process_subscriber_terminal_util_msg(msg_payload);
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ {
+ ret = process_tm_sched_util_msg(msg_payload);
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_core,
+ "Unsupported object detected in message received from util\n");
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ break;
+ }
+ }
+ /*
+ * Free the message after processing
+ */
+ bcmbal_msg_free(msg_payload);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The BAL core "packet send" message processing function
+ *
+ * A Worker module function that handles packet send messages received from the
+ * BAL public API via an RX thread.
+ *
+ * This function executes in the context of the worker thread
+ *
+ * @param msg_payload A pointer to the message to be processed
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+static bcmos_errno process_packet_object(void *msg_payload)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ uint8_t *p_user_pkt;
+ uint16_t user_pkt_len;
+ uint8_t dst_port_id;
+ bcmos_bool b_port_id_is_nni;
+ bcmbal_packet_cfg *p_packet_obj;
+ uint16_t tunnel_tag_vlan_id = 0;
+
+ BCM_LOG(DEBUG, log_id_core, "Processing a \"Packet send\" message\n");
+
+ p_packet_obj = (bcmbal_packet_cfg *)msg_payload;
+
+ /* Extract the length of the user packet to be proxied */
+ user_pkt_len = p_packet_obj->data.pkt.len;
+
+ /* Derive a pointer to the user packet */
+ p_user_pkt = p_packet_obj->data.pkt.val;
+
+ BCM_LOG(DEBUG, log_id_core, "user packet first 12 bytes %02X%02X%02X%02X%02X%02X %02X%02X%02X%02X%02X%02X\n",
+ p_user_pkt[0], p_user_pkt[1], p_user_pkt[2], p_user_pkt[3], p_user_pkt[4], p_user_pkt[5],
+ p_user_pkt[6], p_user_pkt[7], p_user_pkt[8], p_user_pkt[9], p_user_pkt[10], p_user_pkt[11]);
+
+ /* Is this packet destined to an NNI or PON port? */
+ b_port_id_is_nni = (BCMBAL_DEST_TYPE_NNI == p_packet_obj->key.packet_send_dest.type) ?
+ BCMOS_TRUE : BCMOS_FALSE;
+
+ /*
+ * Process the message based on the type of BAL object
+ * in the message.
+ */
+ switch(p_packet_obj->hdr.hdr.obj_type)
+ {
+ case BCMBAL_OBJ_ID_PACKET:
+ {
+
+ dst_port_id = (BCMOS_TRUE == b_port_id_is_nni) ?
+ (p_packet_obj->key.packet_send_dest.u.nni.int_id) :
+ (p_packet_obj->key.packet_send_dest.u.sub_term.int_id);
+ if(BCMOS_FALSE == b_port_id_is_nni)
+ {
+ /*
+ * Packets destined to a PON interface require a tunnel tag
+ *
+ * Get the svc_port_id for the first flow on the subscriber terminal (if there is one)
+ */
+ if(BCM_ERR_OK != svc_port_id_for_sub_term_ds_flow_get(p_packet_obj->key.packet_send_dest.u.sub_term.int_id,
+ p_packet_obj->key.packet_send_dest.u.sub_term.sub_term_id,
+ p_packet_obj->key.packet_send_dest.u.sub_term.sub_term_uni,
+ &tunnel_tag_vlan_id))
+ {
+ BCM_LOG(ERROR,
+ log_id_core,
+ "Packet send could not find any downstream FLOW to send packet for sub_term_id %d (PON %d)\n",
+ p_packet_obj->key.packet_send_dest.u.sub_term.sub_term_id,
+ p_packet_obj->key.packet_send_dest.u.sub_term.int_id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ }
+
+ ret = sw_util_pkt_send(dst_port_id,
+ (b_port_id_is_nni ? REASON_SEND_TO_NNI : REASON_SEND_TO_PON),
+ p_user_pkt,
+ user_pkt_len,
+ (int)tunnel_tag_vlan_id);
+ }
+ break;
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_core,
+ "Unsupported object detected in \"packet send\" message\n");
+ ret = BCM_ERR_NOT_SUPPORTED;
+ }
+ break;
+
+ }
+ /*
+ * NOTE: DO NOT free the message after processing here. It is freed in the calling function
+ */
+
+ return ret;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/bal_worker.h b/bal_release/src/core/main/bal_worker.h
new file mode 100644
index 0000000..a0df6ae
--- /dev/null
+++ b/bal_release/src/core/main/bal_worker.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_worker.h
+ *
+ * @brief Bal worker thread include file
+ *
+ * Module contains the data structures and functions used to support the
+ * BAL core worker thread.
+ *
+ * @defgroup ctrlr Core Controller
+ * @ingroup core
+ *
+ */
+
+#ifndef BALWORKER_H
+#define BALWORKER_H
+
+/*@{*/
+
+#include <bcmos_errno.h>
+#include <bal_api.h>
+
+/* Transmit Queues to and from BAL core */
+extern bcmos_msg_queue *p_bal_core_to_api_queue;
+extern bcmos_msg_queue *p_bal_core_to_api_ind_queue;
+
+/*
+ * Function declarations
+ */
+extern bcmos_errno _bal_worker_mgmt_module_init(long data);
+extern bcmos_errno _bal_worker_util_module_init(long data);
+
+extern bcmos_errno core_msg_queue_init(mgmt_queue_addr_ports *msg_queue_info);
+extern void core_worker_thread_init(void);
+extern void core_worker_thread_finish(void);
+
+extern void core_util_msg_handler(bcmos_module_id module_id, bcmos_msg *msg);
+
+
+/*@}*/
+
+#endif /* BALWORKER_H */
diff --git a/bal_release/src/core/main/flow_fsm.c b/bal_release/src/core/main/flow_fsm.c
new file mode 100644
index 0000000..f7ee71a
--- /dev/null
+++ b/bal_release/src/core/main/flow_fsm.c
@@ -0,0 +1,2556 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file flow_fsm.c
+ * @brief Code to support the BAL flow FSM
+ *
+ * @addtogroup flow
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <flow_fsm.h>
+#include <tm_sched_fsm.h>
+#include <tm_queue_fsm.h>
+
+
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include "rsc_mgr.h"
+
+#include <bal_objs.h>
+#include <fsm_common.h>
+#include <bal_switch_flow.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+ /*
+ * @brief The logging device id for flow
+ */
+static dev_log_id log_id_flow;
+#endif
+
+/* local function declarations */
+static bcmos_errno flow_fsm_admin_up_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_admin_up_error(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_admin_dn_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_admin_dn_ok(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_admin_dn_error(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_ignore_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_removing_process_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_removing_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_null_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_process_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_clear_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+
+static bcmos_errno flow_fsm_state_err(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event);
+
+static bcmos_errno flow_fsm_exec(flow_inst *p_flow_inst, flow_fsm_event *p_event);
+
+static flow_inst *flow_inst_get(bcmbal_flow_key *key, flow_flag search_flag, bcmos_bool *is_new_flow);
+
+
+#ifdef FREE_FLOW_BY_KEY_SUPPORTED
+static bcmos_errno flow_free_by_key(bcmbal_flow_key *key);
+#endif
+static bcmos_errno flow_free_by_entry(flow_inst *p_entry);
+
+static bcmos_errno flow_tm_get(bcmbal_flow_cfg *p_flow_info, tm_sched_inst **p_tm_sched_inst);
+static bcmos_errno flow_queue_validate(bcmbal_flow_cfg *p_flow_cfg, tm_queue_inst **p_tm_queue_inst);
+
+
+/*
+ * @brief The Global flow fsm context data structure
+ */
+static flow_fsm_ctx g_flow_fsm_flow_list_ctx;
+
+/*
+ * Macros for flow ctx access
+ */
+#define FLOW_FSM_FLOW_LIST_CTX (g_flow_fsm_flow_list_ctx)
+#define FLOW_FSM_FLOW_LIST_CTX_PTR (&g_flow_fsm_flow_list_ctx)
+
+/*
+ * @brief The definition of a flow FSM state processing function
+ */
+typedef bcmos_errno (* flow_fsm_state_processor)(flow_inst *, void *, flow_fsm_event *);
+
+/*
+ * @brief The Flow FSM state processing array
+ */
+static flow_fsm_state_processor flow_states[FLOW_FSM_STATE__NUM_OF][FLOW_FSM_EVENT_TYPE__NUM_OF] =
+{
+
+ [FLOW_FSM_STATE_NULL] =
+ {
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_UP] = flow_fsm_admin_up_start,
+
+ /*
+ * Next state: NULL
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_DN] = flow_fsm_admin_dn_ok,
+
+ /*
+ * Next state: NULL
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_MSG] = flow_fsm_ignore_util_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = flow_fsm_null_process_util_auto_msg,
+ },
+ [FLOW_FSM_STATE_CONFIGURING] =
+ {
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_UP] = flow_fsm_admin_up_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_DN] = flow_fsm_admin_dn_start,
+
+ /*
+ * Next state: CONFIGURING | CONFIGURED
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_MSG] = flow_fsm_process_util_msg,
+
+ /*
+ * Next state: REMOVING
+ */
+ [FLOW_FSM_EVENT_TYPE_REMOVE] = flow_fsm_clear_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = flow_fsm_process_util_auto_msg,
+
+ },
+
+ [FLOW_FSM_STATE_CONFIGURED] =
+ {
+ /*
+ * Next state: CONFIGURED
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_UP] = flow_fsm_admin_up_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_DN] = flow_fsm_admin_dn_start,
+
+ /*
+ * Next state: REMOVING
+ */
+ [FLOW_FSM_EVENT_TYPE_REMOVE] = flow_fsm_clear_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_MSG] = flow_fsm_process_util_msg,
+
+ /*
+ * Next state: CONFIGURED
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = flow_fsm_process_util_auto_msg,
+
+ },
+
+ [FLOW_FSM_STATE_REMOVING] =
+ {
+ /*
+ * Next state: REMOVING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_UP] = flow_fsm_admin_up_error,
+
+ /*
+ * Next state: REMOVING
+ */
+ [FLOW_FSM_EVENT_TYPE_ADMIN_DN] = flow_fsm_admin_dn_error,
+
+ /*
+ * Next state: REMOVING | NULL
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_MSG] = flow_fsm_removing_process_util_msg,
+
+ /*
+ * Next state: REMOVING
+ */
+ [FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = flow_fsm_removing_process_util_auto_msg,
+ },
+
+};
+
+static char *state_name_str[] =
+{
+ "FLOW_FSM_STATE_NULL",
+ "FLOW_FSM_STATE_CONFIGURING",
+ "FLOW_FSM_STATE_CONFIGURED",
+ "FLOW_FSM_STATE_REMOVING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (FLOW_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), flow_fsm_state);
+
+static char *flow_state_name_get(flow_fsm_state state)
+{
+ if(state < FLOW_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "FLOW_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "FLOW_FSM_ADMIN_UP_EVENT",
+ "FLOW_FSM_ADMIN_DN_EVENT",
+ "FLOW_FSM_REMOVE_EVENT",
+ "FLOW_FSM_UTIL_MSG_EVENT",
+ "FLOW_FSM_UTIL_AUTO_MSG_EVENT",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (FLOW_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), flow_fsm_event_type);
+
+static char *flow_event_name_get(flow_fsm_event_type event)
+{
+ if(event < FLOW_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "FLOW_EVT_UNKNOWN";
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the current_flow_info object of the
+ * supplied entry.
+ *
+ * @param p_entry A pointer to the entry to be initialized
+ *
+ *
+ * @returns void
+ *****************************************************************************/
+static void flow_inst_entry_obj_init(flow_inst *p_entry)
+{
+ /* The actual key content is irrelevant for free flows */
+ bcmbal_flow_key key = { .flow_id = 0, .flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM };
+
+ BCMBAL_CFG_INIT(&p_entry->current_flow_info,
+ flow,
+ key);
+
+ BCMBAL_CFG_PROP_SET(&p_entry->current_flow_info,
+ flow,
+ admin_state,
+ BCMBAL_STATE_DOWN);
+
+ BCMBAL_CFG_PROP_SET(&p_entry->current_flow_info,
+ flow,
+ oper_status,
+ BCMBAL_STATUS_DOWN);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_flow_info), BCMOS_FALSE);
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the Flow FSM infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno flow_fsm_init(void)
+{
+ int ii;
+ flow_inst *new_entry;
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ log_id_flow = bcm_dev_log_id_register("FLOW", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_flow == DEV_LOG_INVALID_ID);
+#endif
+
+ /* Initialize all of the flow queues */
+ TAILQ_INIT(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list);
+ TAILQ_INIT(&FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list);
+
+ /* Populate the free list with it's initial set of flows
+ */
+ for(ii=0; ii<FLOW_ALLOCATION_BLOCK_SIZE; ii++)
+ {
+
+ new_entry = bcmos_calloc(sizeof(flow_inst));
+
+ if (NULL == new_entry)
+ {
+ BCM_LOG(FATAL, log_id_flow, "Failed to initialize the flow free list - FATAL\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ flow_free_by_entry(new_entry);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to un-initialize the Flow FSM infrastructure.
+ *
+ * NOTE: This is called once on shutdown and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno flow_fsm_finish(void)
+{
+
+ flow_inst *current_entry, *p_temp_entry;
+
+ /* Free all the entries on the active list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list, current_entry, flow_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ /* Free all the entries on the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list,
+ flow_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list, current_entry, flow_inst_next);
+
+ bcmos_free(current_entry);
+ }
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing executive function
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param p_event Pointer to a flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_exec(flow_inst *p_flow_inst, flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ flow_fsm_state pre_state;
+ flow_fsm_state_processor flow_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state for debug printing
+ */
+ pre_state = p_flow_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ flow_state_processor = flow_states[p_flow_inst->fsm_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if (flow_state_processor)
+ {
+ ret = flow_state_processor(p_flow_inst, p_event->msg, p_event);
+ } else
+ {
+ flow_fsm_state_err(p_flow_inst, p_event->msg, p_event);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow, "*** Error detected during state processing\n");
+ p_flow_inst->fsm_state = pre_state;
+ }
+
+ BCM_LOG(DEBUG, log_id_flow, "*** Event %s, State: %s --> %s\n\n",
+ flow_event_name_get(p_event->event_type),
+ flow_state_name_get(pre_state),
+ flow_state_name_get(p_flow_inst->fsm_state));
+
+ return ret;
+}
+
+
+
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow admin-up command received
+ * from the BAL Public API when the specified flow instance is in the
+ * admin-down state (i.e. when the flow instance FSM is in the NULL state).
+ *
+ * @param p_flow_inst Pointer to an flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_admin_up_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmos_bool is_ds_flow_to_host, is_ds_n_to_1;
+
+
+ BCM_LOG(INFO, log_id_flow, "Got admin UP request from BAL API - bringing up FLOW\n");
+
+ do
+ {
+ /* change Flow state to CONFIGURING */
+ p_flow_inst->fsm_state = FLOW_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_ADD)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by switch util while adding flow\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils add applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_ADD)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by mac util\n", bcmos_strerror(ret));
+
+ /* Remove the (just added) flow from the switch otherwise the switch utils
+ * will remember it and complain when this flow is added later. There's not
+ * much we can do about it if removing this flow fails.
+ */
+ if(BCM_ERR_OK != sw_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_CLEAR))
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "error detected by switch util while removing flow\n");
+ }
+
+ break;
+ }
+
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state.
+ */
+ bcmbal_flow_object_overlay_w_src_priority(&p_flow_inst->current_flow_info,
+ &p_flow_inst->api_req_flow_info);
+
+ is_ds_flow_to_host = (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type &&
+ (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_flow_inst->api_req_flow_info, flow, action) &&
+ (p_flow_inst->api_req_flow_info.data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)));
+
+ is_ds_n_to_1 = ((BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) &&
+ (BCMBAL_CFG_PROP_IS_SET(&p_flow_inst->api_req_flow_info, flow, group_id) ));
+
+
+ /* Add the svc_port_id record to the sub_term record for upstream flows,
+ * or for downstream flows that are not destined to the host
+ */
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type ||
+ (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type &&
+ !(is_ds_flow_to_host) && !(is_ds_n_to_1)))
+
+ {
+ bcmbal_sub_term_svc_port_id_list_entry_add(p_flow_inst->p_sub_term_inst,
+ p_flow_inst->api_req_flow_info.data.svc_port_id);
+ }
+
+ /* Add the agg_port_id to the sub_term record (only for upstream flows) */
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+ bcmbal_sub_term_agg_port_id_list_entry_add(p_flow_inst->p_sub_term_inst,
+ p_flow_inst->api_req_flow_info.data.agg_port_id);
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_flow_inst->current_flow_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API and free the flow */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_flow);
+
+ flow_free_by_entry(p_flow_inst);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow admin-up command received
+ * from the BAL Public API when the specified flow FSM is already
+ * in the REMOVING state.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_admin_up_error(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_STATE;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Received an admin UP request from BAL API"
+ " - returning ERROR to the API - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow admin-down command
+ * received from the BAL Public API when the specified flow is
+ * admin-up (i.e when the specified flow instance FSM is in the
+ * CONFIGURED state).
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_admin_dn_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_flow,
+ "Got admin DOWN request from BAL API - bringing down FLOW\n");
+
+ /* change Flow state to CONFIGURING */
+ p_flow_inst->fsm_state = FLOW_FSM_STATE_CONFIGURING;
+
+ do
+ {
+ /*– Core calls Switch Utils to remove applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_REMOVE)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by switch util\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils remove applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_REMOVE)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by mac util\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /* The hardware has properly accepted the object info but we do
+ * not overwrite the current flow data as there is nothing in the request
+ * that is relevant besides the admin_state
+ */
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_flow_inst->current_flow_info), BCMOS_TRUE);
+
+ }while(0);
+ /* Report any error found to the API immediately */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_flow);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow clear command
+ * received from the BAL Public API.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_clear_start(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst;
+ uint32_t alloc_ref_count;
+ bcmos_bool b_flow_is_destined_to_host;
+ tm_queue_inst *p_tm_queue_inst = NULL;
+
+ BCM_LOG(INFO, log_id_flow,
+ "Got CLEAR request from BAL API - removing FLOW\n");
+
+ /* change Flow state to REMOVING */
+ p_flow_inst->fsm_state = FLOW_FSM_STATE_REMOVING;
+
+
+ b_flow_is_destined_to_host = ((BCMBAL_CFG_PROP_IS_SET(&(p_flow_inst->api_req_flow_info), flow, action) &&
+ (p_flow_inst->api_req_flow_info.data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)) ? BCMOS_TRUE : BCMOS_FALSE);
+ do
+ {
+ /*Core calls Switch Utils to clear applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_CLEAR)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by switch util\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*Core calls Mac Utils clear applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_flow_set(p_flow_inst, BAL_UTIL_OPER_FLOW_CLEAR)))
+ {
+ /* if entry does not exist for a clear, that is fine, since anyway that would have been the end goal */
+ if (BCM_ERR_NOENT != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow, "error %s detected by mac util\n", bcmos_strerror(ret));
+ break;
+ }
+ }
+
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+ /*handle the alloc id and alloc - tm sched*/
+ if(BCM_ERR_OK != rsc_mgr_alloc_id_free(p_flow_inst->api_req_flow_info.data.access_int_id,
+ p_flow_inst->api_req_flow_info.data.agg_port_id, p_flow_inst))
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ " error encountered during release of flow resources (agg_port_id: %d, intf_id:%d\n",
+ p_flow_inst->api_req_flow_info.data.access_int_id,
+ p_flow_inst->api_req_flow_info.data.agg_port_id);
+ }
+ /*check if tm sched should be removed - ref count = 1 and tm sched is auto created*/
+ if(BCM_ERR_OK != (ret = flow_tm_get(&(p_flow_inst->api_req_flow_info), &p_tm_sched_inst)))
+ {
+
+ BCM_LOG(ERROR, log_id_flow,
+ " could not find tm sched for agg_port_id: %d, intf_id:%d\n",
+ p_flow_inst->api_req_flow_info.data.access_int_id,
+ p_flow_inst->api_req_flow_info.data.agg_port_id);
+ break;
+ }
+ ret = rsc_mgr_alloc_id_get_ref_count(p_flow_inst->api_req_flow_info.data.access_int_id,p_flow_inst->api_req_flow_info.data.agg_port_id, &alloc_ref_count);
+
+ if(BCM_ERR_OK == ret
+ && BCMBAL_TM_CREATION_MODE_AUTO == p_tm_sched_inst->req_tm_sched_info.data.creation_mode
+ && 1 == alloc_ref_count)
+ {
+ ret = bcmbal_tm_sched_fsm_active_destroy(p_tm_sched_inst);
+ }
+ }
+
+ /*if the flow is not a cpu flow (to host), should handle it sched/queue setting*/
+ if(!b_flow_is_destined_to_host)
+ {
+ /*remove the flow from the the tm queue list*/
+ /*find tm queue instance*/
+ ret = flow_queue_validate(&p_flow_inst->api_req_flow_info, &p_tm_queue_inst);
+
+ if (ret != BCM_ERR_OK)
+ {
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ ret = bcmbal_tm_queue_use_set(p_tm_queue_inst, BCMOS_FALSE);
+ if (ret != BCM_ERR_OK)
+ {
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state, except for the oper_status.
+ */
+ bcmbal_flow_object_overlay_w_src_priority(&p_flow_inst->current_flow_info,
+ &p_flow_inst->api_req_flow_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_flow_inst->current_flow_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* Report any error found to the API immediately */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_flow);
+ }
+
+ return ret;
+
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow admin-down command
+ * from the BAL Public API when the specified flow is already
+ * admin-down.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_admin_dn_ok(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Received an admin DOWN request from BAL API"
+ " - returning OK to the API - no further function\n");
+
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_flow);
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing for a flow admin-down command
+ * received from the BAL Public API when the specified flow FSM
+ * is in the CONFIGURING state.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_admin_dn_error(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_STATE;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Received an admin DOWN request from BAL API"
+ " - returning ERROR to the API - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to ignore a received message.
+ *
+ * @param p_flow_inst Pointer to an flow instance
+ * @param msg Pointer to a BAL message received from the BAL utils
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_ignore_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_flow, "Ignoring message from BAL utils\n");
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to process an AUTO IND
+ * message from one of the BAL apps.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_null_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_flow, "Received an AUTO IND in the NULL state\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to process a message from
+ * one of the BAL apps received when the specified flow instance FSM
+ * is in the CONFIGURING state.
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_process_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+
+ BCM_LOG(DEBUG, log_id_flow,
+ " Received an IND message from BAL UTIL (%s) during %s state\n",
+ subsystem_str[bcmbal_sender_get(msg)],flow_state_name_get(p_flow_inst->fsm_state));
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "%s, thread %s, module %d\n", __FUNCTION__, bcmos_task_current()->name, bcmos_module_current());
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ /* Reflect the execution status in the object being returned in the indication
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ p_flow_inst->current_flow_info.data.oper_status =
+ p_flow_inst->api_req_flow_info.data.oper_status;
+
+ /*
+ * The flow has been successfully configured
+ */
+ p_flow_inst->fsm_state = FLOW_FSM_STATE_CONFIGURED;
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_flow, "Flow %d: Failed in state %s. Error %s\n",
+ p_flow_inst->api_req_flow_info.key.flow_id,
+ flow_state_name_get(p_flow_inst->fsm_state),
+ bcmos_strerror(ret));
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_flow_inst->current_flow_info), BCMOS_FALSE);
+ p_flow_inst->current_flow_info.hdr.hdr.status = ret;
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_flow_inst->current_flow_info.hdr,
+ log_id_flow);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to process a message from
+ * one of the BAL apps received
+ *
+ * @param p_flow_inst Pointer to a flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an access terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bal_util_msg_auto_ind *ind_msg;
+
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Received an AUTO IND message in the %s state\n",
+ flow_state_name_get(p_flow_inst->fsm_state));
+
+ ind_msg = (bal_util_msg_auto_ind *)msg;
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* data reflects the new oper_status in the object being indicated */
+ memcpy(&p_flow_inst->current_flow_info.data.oper_status, ind_msg->data, sizeof(bcmbal_status));
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_flow_inst->current_flow_info.hdr,
+ log_id_flow);
+
+
+ p_flow_inst->fsm_state = FLOW_FSM_STATE_CONFIGURED;
+
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to process a
+ * message from one of the BAL apps received when the specified
+ * flow instance FSM is in the REMOVING state.
+ *
+ * @param p_flow_inst Pointer to an flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_removing_process_util_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bal_util_msg_ind *ind_msg;
+ bcmos_bool is_ds_flow_to_host;
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+
+ BCM_LOG(DEBUG, log_id_flow,
+ " Received an IND message from BAL UTIL (%s) during REMOVING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ do{
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ /* Reflect the execution status in the object being returned in the indication
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type ||
+ BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+ is_ds_flow_to_host = (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type &&
+ (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_flow_inst->api_req_flow_info, flow, action) &&
+ (p_flow_inst->api_req_flow_info.data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)));
+
+ if (bcm_topo_pon_get_pon_family(p_flow_inst->api_req_flow_info.data.access_int_id) == BCM_TOPO_PON_FAMILY_GPON)
+ {
+
+ /* Don't attempt to release a GEM for a downstream flow that is TRAP_TO_HOST, because there
+ * is no subscriber terminal involved in this flow (there was no GEM allocated for this flow).
+ */
+ if(BCMOS_FALSE == is_ds_flow_to_host)
+ {
+ if(BCM_ERR_OK != rsc_mgr_gem_free(p_flow_inst->api_req_flow_info.data.access_int_id,
+ p_flow_inst->api_req_flow_info.data.svc_port_id, p_flow_inst))
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ " error encountered during release of flow resources (svc_port_id: %d, intf_id:%d\n",
+ p_flow_inst->api_req_flow_info.data.svc_port_id,
+ p_flow_inst->api_req_flow_info.data.access_int_id);
+ }
+ }
+
+
+ }
+
+ /* Remove the svc_port_id record from the sub_term record for upstream flows,
+ * or for downstream flows that are not destined to the host
+ */
+ if((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) ||
+ ((BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) &&
+ !(is_ds_flow_to_host)))
+ {
+ bcmbal_sub_term_svc_port_id_list_entry_remove(p_flow_inst->p_sub_term_inst,
+ p_flow_inst->current_flow_info.data.svc_port_id);
+ }
+
+ /* Remove the agg_port_id from the sub_term record (only for upstream flows) */
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+
+ bcmbal_sub_term_agg_port_id_list_entry_remove(p_flow_inst->p_sub_term_inst,
+ p_flow_inst->current_flow_info.data.agg_port_id);
+ }
+ }
+
+ p_flow_inst->current_flow_info.hdr.hdr.status = ret;
+
+ /* This is the proper state and status for the indication about to be sent */
+ p_flow_inst->current_flow_info.data.admin_state = BCMBAL_STATE_DOWN;
+ p_flow_inst->current_flow_info.data.oper_status = BCMBAL_STATUS_DOWN;
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_flow_inst->current_flow_info), BCMOS_FALSE);
+
+ /*
+ * Send the success indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_flow_inst->current_flow_info.hdr,
+ log_id_flow);
+
+ /* Return the flow to the free pool regardless of the errors encountered above */
+ flow_free_by_entry(p_flow_inst);
+ }
+ else
+ {
+ /*
+ * Send the failure indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_flow_inst->current_flow_info.hdr,
+ log_id_flow);
+ }
+ }while(0);
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM state processing function to process a
+ * AUTO IND message from one of the BAL apps received when the specified
+ * flow instance FSM is in the REMOVING state.
+ *
+ * @param p_flow_inst Pointer to an flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_removing_process_util_auto_msg(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_flow_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Received an AUTO IND in the removing state"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Flow FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_flow_inst Pointer to an flow instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an flow event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_fsm_state_err(flow_inst *p_flow_inst,
+ void *msg,
+ flow_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Error encountered processing FLOW FSM"
+ " - BAD EVENT ()\n");
+
+ return ret;
+}
+static bcmos_errno flow_queue_validate(bcmbal_flow_cfg *p_flow_cfg, tm_queue_inst **p_tm_queue_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_interface_key intf_key;
+ bcmbal_tm_sched_key tm_key;
+ tm_sched_inst *p_tm_sched;
+ bcmbal_tm_queue_key queue_key;
+ bcmbal_tm_queue_ref queue_ref;
+ bcmos_bool is_auto_set = BCMOS_TRUE;
+
+ do
+ {
+ if (BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_cfg->key.flow_type)
+ {
+ intf_key.intf_type = BCMBAL_INTF_TYPE_NNI;
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
+ intf_key.intf_id = p_flow_cfg->data.network_int_id;
+ }
+ else /*BCMBAL_FLOW_TYPE_DOWNSTREM or BCMBAL_FLOW_TYPE_MULTICAST */
+ {
+ intf_key.intf_type = BCMBAL_INTF_TYPE_PON;
+ tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
+ intf_key.intf_id = p_flow_cfg->data.access_int_id;
+ }
+
+ if (BCMBAL_CFG_PROP_IS_SET(p_flow_cfg, flow, queue))
+ {
+ queue_ref = p_flow_cfg->data.queue;
+ is_auto_set = BCMOS_FALSE;
+ }
+ else
+ {
+ /*look for the auto created tm sched and queue*/
+ ret = bcmbal_interface_tm_get(intf_key, &tm_key.id);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "could not get interface instance"
+ " to set flow queue reference intf_key.intf_type = %d,"
+ " intf_key.intf_id = %d\n",
+ intf_key.intf_type, intf_key.intf_id);
+ break;
+ }
+ p_tm_sched = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "could not get tm sched instance to "
+ "set flow queue reference intf_key.intf_type = %d,"
+ " intf_key.intf_id = %d tm_key.dir = %s\n"
+ ,intf_key.intf_type, intf_key.intf_id, TM_SCHED_DIR_TO_STR(tm_key.dir));
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ if(BCMBAL_TM_CREATION_MODE_AUTO != p_tm_sched->current_tm_sched_info.data.creation_mode)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "can not set flow queue reference if the "
+ "interface tm sched is not auto created. "
+ "intf_key.intf_type = %d, intf_key.intf_id = %d tm_key.dir = %s\n",
+ intf_key.intf_type, intf_key.intf_id, TM_SCHED_DIR_TO_STR(tm_key.dir));
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*if the tm sched exist and it is auto created, queue 0 should be there as well*/
+ queue_ref.sched_id = tm_key.id;
+ queue_ref.queue_id = 0;
+ BCM_LOG(INFO, log_id_flow,
+ "flow will be assign to queue: node id=%d "
+ "node dir=%s queue id = %d\n",
+ tm_key.id, TM_SCHED_DIR_TO_STR(tm_key.dir), queue_ref.queue_id);
+
+ BCMBAL_CFG_PROP_SET(p_flow_cfg, flow, queue, queue_ref);
+ }
+
+ queue_key.id = queue_ref.queue_id;
+ queue_key.sched_id = queue_ref.sched_id;
+ queue_key.sched_dir = tm_key.dir;
+
+ /*validate a given tm queue exist and match flow type*/
+ *p_tm_queue_inst = tm_queue_inst_get(queue_key, TM_QUEUE_FLAG_ACTIVE);
+ if (NULL == *p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "could not find the queue to assign the flow to "
+ ":tm sched dir = %s tm sched id = %d queue id = %d\n",
+ TM_SCHED_DIR_TO_STR(queue_key.sched_dir), queue_key.sched_id,queue_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ if (BCMOS_FALSE == is_auto_set)
+ {
+ /*should validate queue is related to the flow intf/sub_term/sub_term_uni*/
+ tm_key.dir = queue_key.sched_dir;
+ tm_key.id = queue_key.sched_id;
+
+ p_tm_sched = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "could not get tm sched instance to set flow queue "
+ "reference intf_key.intf_type = %d, intf_key.intf_id = %d tm_key.dir = %s\n",
+ intf_key.intf_type, intf_key.intf_id, TM_SCHED_DIR_TO_STR(tm_key.dir));
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched->req_tm_sched_info,tm_sched,owner))
+ {
+ switch(p_tm_sched->req_tm_sched_info.data.owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ if (p_tm_sched->req_tm_sched_info.data.owner.u.sub_term.intf_id != p_flow_cfg->data.access_int_id
+ || p_tm_sched->req_tm_sched_info.data.owner.u.sub_term.sub_term_id!= p_flow_cfg->data.sub_term_id)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "queue referenced by flow, attached to tm sched instance that is owned by "
+ "sub term intf_id = %d sub_term_id = %d while flow is related to sub term"
+ " intf_id = %d sub_term_id = %d therefor cannot be set as flow queue\n",
+ p_tm_sched->req_tm_sched_info.data.owner.u.sub_term.intf_id,
+ p_tm_sched->req_tm_sched_info.data.owner.u.sub_term.sub_term_id,
+ p_flow_cfg->data.access_int_id,
+ p_flow_cfg->data.sub_term_uni_idx);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ if (p_tm_sched->req_tm_sched_info.data.owner.u.uni.intf_id != p_flow_cfg->data.access_int_id
+ || p_tm_sched->req_tm_sched_info.data.owner.u.uni.sub_term_id!= p_flow_cfg->data.sub_term_id
+ || p_tm_sched->req_tm_sched_info.data.owner.u.uni.idx != p_flow_cfg->data.sub_term_uni_idx)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "queue referenced by flow , attached to tm sched "
+ "instance that is owned by sub term uni intf_id = %d "
+ "sub_term_id = %d uni = %d while flow is related to uni sub "
+ "term intf_id = %d sub_term_id = %d uni = %d therefor cannot be "
+ "set as flow queue\n",
+ p_tm_sched->req_tm_sched_info.data.owner.u.uni.intf_id,
+ p_tm_sched->req_tm_sched_info.data.owner.u.uni.sub_term_id,
+ p_tm_sched->req_tm_sched_info.data.owner.u.uni.idx,
+ p_flow_cfg->data.access_int_id,
+ p_flow_cfg->data.sub_term_id,
+ p_flow_cfg->data.sub_term_uni_idx);
+ ret = BCM_ERR_PARM;
+ }
+ }
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_flow,
+ "tm sched instance is owned by %d therefor "
+ "cannot be set as flow queue\n",
+ p_tm_sched->req_tm_sched_info.data.owner.type);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "tm sched instance is not set with an owner therefor "
+ "cannot be set as flow queue intf_key.intf_type = %d, "
+ "intf_key.intf_id = %d tm_key.dir = %s\n",
+ intf_key.intf_type, intf_key.intf_id, TM_SCHED_DIR_TO_STR(tm_key.dir));
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }while (0);
+ return ret;
+
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * flow object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_flow_object(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
+ bcmbal_flow_cfg *p_flow_cfg = (bcmbal_flow_cfg *)msg_payload;
+ flow_inst *p_flow_inst = NULL;
+ flow_fsm_event fsm_event;
+ bcmbal_flow_key *p_flow_key;
+ bcmbal_state admin_state_req;
+ bcmos_bool b_flow_is_destined_to_host;
+ bcmbal_obj_msg_type oper_type;
+ bcmbal_subscriber_terminal_key sub_term_key;
+ sub_term_inst *p_sub_term_inst = NULL;
+ bcmos_bool is_multicast = BCMOS_FALSE;
+ bcmos_bool is_unicast = BCMOS_FALSE;
+
+ bcmos_bool is_us_n_to_1 = BCMOS_FALSE;
+ bcmos_bool is_ds_n_to_1 = BCMOS_FALSE;
+
+ tm_queue_inst *p_tm_queue_inst = NULL;
+
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_flow, "Processing a flow object\n");
+
+ p_flow_key = &p_flow_cfg->key;
+
+ oper_type = p_flow_cfg->hdr.hdr.type;
+
+ is_multicast = (BCMBAL_FLOW_TYPE_MULTICAST == p_flow_key->flow_type);
+
+ is_unicast = ((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_key->flow_type) ||
+ (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_key->flow_type));
+
+ is_us_n_to_1 = ((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_key->flow_type) &&
+ (BCMBAL_CFG_PROP_IS_SET(p_flow_cfg, flow, group_id)));
+
+ is_ds_n_to_1 = ((BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_key->flow_type) &&
+ (BCMBAL_CFG_PROP_IS_SET(p_flow_cfg, flow, group_id) ));
+
+
+ /*
+ * A message pointer may be passed inside the event structure.
+ */
+ fsm_event.msg = msg_payload;
+
+ /* SET or GET or CLEAR...? */
+ switch (oper_type)
+ {
+ case (BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ bcmos_bool b_generate_event = BCMOS_FALSE;
+ bcmos_bool found_new_flow = BCMOS_FALSE;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Processing a flow SET REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ b_flow_is_destined_to_host = ((BCMBAL_CFG_PROP_IS_SET(p_flow_cfg, flow, action) &&
+ (p_flow_cfg->data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)) ? BCMOS_TRUE : BCMOS_FALSE);
+
+ admin_state_req = p_flow_cfg->data.admin_state;
+
+ BCM_LOG(INFO, log_id_flow,
+ "flow %d:%s request - admin state requested is %s\n",
+ p_flow_key->flow_id,
+ CORE_FSM_FLOW_TYPE_GET_STR(p_flow_key->flow_type),
+ (BCMBAL_STATE_UP == admin_state_req) ? "UP" : "DOWN");
+
+ /*
+ * Find or create the specified flow instance
+ */
+ p_flow_inst = flow_inst_get(p_flow_key, FLOW_FLAG_ANY, &found_new_flow);
+ if(NULL == p_flow_inst)
+ {
+ /* This is a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_flow,
+ "ERROR - Flow not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ /*
+ * Fill in the local flow info data structure
+ */
+ p_flow_inst->api_req_flow_info = *p_flow_cfg;
+
+ /* For flows that have already been configured, merge the
+ * requested flow data with the current flow data, and this results in the new request.
+ */
+ if((BCMOS_FALSE == found_new_flow) &&
+ (p_flow_inst->api_req_flow_info.data.oper_status != p_flow_inst->current_flow_info.data.oper_status))
+ {
+ bcmbal_flow_object_overlay_w_dst_priority(&p_flow_inst->api_req_flow_info,
+ &p_flow_inst->current_flow_info);
+ }
+
+ BCM_LOG(INFO, log_id_flow,
+ "flow access_int_id: %d, sub_term_id: %d\n",
+ p_flow_inst->api_req_flow_info.data.access_int_id,
+ p_flow_inst->api_req_flow_info.data.sub_term_id);
+
+ /* Next, find sub term instance, if is flow UP */
+ if (BCMBAL_STATE_UP == admin_state_req)
+ {
+ sub_term_key.intf_id = p_flow_inst->api_req_flow_info.data.access_int_id;
+ sub_term_key.sub_term_id = p_flow_inst->api_req_flow_info.data.sub_term_id;
+
+ p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if (!p_sub_term_inst && !is_multicast && !is_ds_n_to_1 && !b_flow_is_destined_to_host)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "No active subscriber terminal with id=%u, and for flow type %s \n",
+ sub_term_key.sub_term_id,
+ CORE_FSM_FLOW_TYPE_GET_STR(p_flow_key->flow_type));
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /*if the flow is not a cpu flow (to host), then we should validate/use the sched/queue setting*/
+ if(!b_flow_is_destined_to_host)
+ {
+ /*find tm queue instance*/
+ ret = flow_queue_validate(&(p_flow_inst->api_req_flow_info), &p_tm_queue_inst);
+ if (ret != BCM_ERR_OK)
+ {
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_queue_use_set(p_tm_queue_inst, BCMOS_TRUE);
+ if (ret != BCM_ERR_OK)
+ {
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }
+
+ p_flow_inst->p_sub_term_inst = p_sub_term_inst;
+
+ /*
+ * Process the request
+ */
+ if(((BCMBAL_STATE_UP == admin_state_req) || found_new_flow)
+ && (BCMBAL_STATE_UP != p_flow_inst->current_flow_info.data.admin_state))
+ {
+ bcmbal_service_port_id svc_port_id = 0;
+ flow_inst *p_peer_flow;
+ uint8_t svc_port_id_range;
+
+ do
+ {
+ if (bcm_topo_pon_get_pon_family(p_flow_inst->api_req_flow_info.data.access_int_id) == BCM_TOPO_PON_FAMILY_GPON)
+ {
+ /* There's no need to do anything with the MAC in downstream flows that
+ * that are destined to the host CPU (i.e. NNI->CPU)
+ */
+ if((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) ||
+ !(b_flow_is_destined_to_host))
+ {
+
+ /*
+ * GEM resolution does not rely on the pbits in a packet, however,
+ * we currently only support allocate a svc_port_id range of 1.
+ */
+ svc_port_id_range = 1;
+
+ /* Is there a peer flow configured already? (only upstream and downstream flows
+ * can have a peer flow)
+ * If not, look in the active list for a match. NOTE: It might not be there.
+ */
+ if( is_unicast && NULL == p_flow_inst->p_peer_flow_inst)
+ {
+ /*
+ * See if we can find a peer flow (a peer flow is a flow that has
+ * the same flow ID as this flow does, but has the opposite direction
+ * in the key).
+ */
+
+ /* Look for an active flow, but ignore the direction (BEWARE: we might
+ * find ourself!!)
+ */
+ p_peer_flow = flow_inst_get(p_flow_key,
+ FLOW_FLAG_ACTIVE | FLOW_FLAG_IGNORE_DIR,
+ NULL);
+
+ /* If the flow that we found isn't us, then link it to our flow
+ */
+ if(p_peer_flow->api_req_flow_info.key.flow_type !=
+ p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+ p_flow_inst->p_peer_flow_inst = p_peer_flow;
+ }
+ }
+
+ /* If a peer flow exists, copy the GEM ID from the peer flow into this flow
+ */
+ if(NULL != p_flow_inst->p_peer_flow_inst)
+ {
+ svc_port_id =
+ p_flow_inst->p_peer_flow_inst->current_flow_info.data.svc_port_id;
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Using GEM ID from peer flow (%d) on access_id %d\n",
+ svc_port_id,
+ p_flow_inst->api_req_flow_info.data.access_int_id);
+
+ /* even though we have gem Id, get it allocated by rsrc mgr so that it can
+ * manage ref counts.
+ */
+ ret = rsc_mgr_gem_alloc_unicast(
+ p_flow_inst->api_req_flow_info.data.access_int_id,
+ &svc_port_id,
+ svc_port_id_range,
+ p_flow_inst); /* A multicast flow cannot have a peer flow. So this means this is definitely not a multicast. */
+ if (BCM_ERR_OK != ret)
+ {
+ /*
+ * An error has occurred trying to get mandatory data
+ */
+
+ BCM_LOG(ERROR, log_id_flow, "Failed to get base GEM from resource manager\n");
+
+ /*
+ * @todo If the flow instance (that we got) is not active, then return it to the
+ * free pool.
+ */
+
+ break;
+ }
+ }
+ else /* A peer flow does not exist */
+ {
+ /* needs single GEM for flows which is not multicast and not downstream N:1 service.
+ In another words, all upstream flows and downstream flows which is not N:1 service needs one GEM */
+ if(!is_multicast && !is_ds_n_to_1)
+ {
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_flow_inst->api_req_flow_info,
+ flow,
+ svc_port_id))
+ {
+ svc_port_id = p_flow_inst->api_req_flow_info.data.svc_port_id;
+
+
+ BCM_LOG(DEBUG, log_id_flow,
+ "Using the base GEM ID supplied by the user (%d) on access_id %d\n",
+ svc_port_id,
+ p_flow_inst->api_req_flow_info.data.access_int_id);
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_flow,
+ "Getting a new base GEM ID on access_id %d from resource manager\n",
+ p_flow_inst->api_req_flow_info.data.access_int_id);
+ svc_port_id = 0; /* 0 is a magic number telling the resource manager that it should provide
+ * the initial allocation of the base GEM */
+ }
+
+ ret = rsc_mgr_gem_alloc_unicast(p_flow_inst->api_req_flow_info.data.access_int_id,
+ &svc_port_id,
+ svc_port_id_range,
+ p_flow_inst);
+
+ if (BCM_ERR_OK != ret)
+ {
+ /*
+ * An error has occurred trying to get mandatory data
+ */
+
+ BCM_LOG(ERROR, log_id_flow, "Failed to get base GEM from resource manager\n");
+
+ /*
+ * @todo If the flow instance (that we got) is not active, then return it to the
+ * free pool.
+ */
+
+ break;
+ }
+ }
+ /* make sure the all members in the group assoficated with the flow has a GEM */
+ if(BCMBAL_CFG_PROP_IS_SET(&p_flow_inst->api_req_flow_info, flow, group_id))
+ {
+ bcmbal_group_key group_key;
+ bcmbal_group_owner group_owner;
+
+ group_key.group_id = p_flow_inst->api_req_flow_info.data.group_id;
+ if(is_ds_n_to_1 || is_us_n_to_1 )
+ {
+ group_owner = BCMBAL_GROUP_OWNER_UNICAST;
+ }
+ else
+ {
+ group_owner = BCMBAL_GROUP_OWNER_MULTICAST;
+ }
+
+ ret = group_owner_set(group_key, group_owner);
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "error %s while updating group owner\n", bcmos_strerror(ret));
+ break;
+ }
+ }
+ }
+ /*
+ * Set the GEM ID into the object being processed
+ */
+ if(svc_port_id)
+ {
+ BCMBAL_CFG_PROP_SET(&p_flow_inst->api_req_flow_info, flow, svc_port_id,svc_port_id);
+ BCM_LOG(DEBUG, log_id_flow, "GEM %d being used\n", svc_port_id);
+ }
+ /*
+ * alloc ID is only required on an UPSTREAM FLOW
+ */
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type)
+ {
+ tm_sched_inst * dummy_p_tm_sched_inst;
+ ret = flow_tm_get(&p_flow_inst->api_req_flow_info, &dummy_p_tm_sched_inst);
+
+ if (BCM_ERR_OK != ret)
+ {
+ /* An error has occurred trying to get mandatory data */
+ BCM_LOG(ERROR, log_id_flow, "Failed to get required tm sched for agg port id\n");
+ break;
+ }
+ ret = rsc_mgr_alloc_id_alloc( p_flow_inst->api_req_flow_info.data.access_int_id,
+ &p_flow_inst->api_req_flow_info.data.agg_port_id, 1, p_flow_inst);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow, "Failed to get ALLOC ID from resource manager\n");
+ break;
+ }
+
+ BCM_LOG(DEBUG, log_id_flow, "ALLOC ID %d being used\n", p_flow_inst->api_req_flow_info.data.agg_port_id);
+ }
+
+ /*
+ * Perform the validation check(s) that the utils require
+ */
+ if(BCM_ERR_OK != (ret = mac_util_flow_info_validate(&p_flow_inst->api_req_flow_info)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "Failed mac validation\n");
+ break;
+ }
+ }
+ }
+ else if (bcm_topo_pon_get_pon_family(p_flow_inst->api_req_flow_info.data.access_int_id) == BCM_TOPO_PON_FAMILY_EPON)
+ {
+ /* There's no need to do anything with the MAC in downstream flows that
+ * that are destined to the host CPU (i.e. NNI->CPU)
+ */
+ if((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) ||
+ !(b_flow_is_destined_to_host))
+ {
+
+ sub_term_key.intf_id = p_flow_inst->api_req_flow_info.data.access_int_id;
+ sub_term_key.sub_term_id = p_flow_inst->api_req_flow_info.data.sub_term_id;
+
+ p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if (!p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "Failed to get subscriber terminal with id=%u\n",
+ sub_term_key.sub_term_id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ /*
+ * set svc_port to the subtunnel id.
+ */
+ BCMBAL_CFG_PROP_SET(&p_flow_inst->api_req_flow_info, flow,
+ svc_port_id,p_sub_term_inst->current_sub_term_info.data.svc_port_id);
+
+ /*
+ * Perform the validation check(s) that the utils require
+ */
+ if(BCM_ERR_OK != (ret = mac_util_flow_info_validate(&p_flow_inst->api_req_flow_info)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "Failed mac validation\n");
+ break;
+ }
+ }
+ }
+
+ /* No need to do anything in the switch for upstream flows that
+ * that are destined to the host CPU (i.e. PON->CPU), so no switch
+ * validation is necessary.
+ */
+ if(!((BCMBAL_FLOW_TYPE_UPSTREAM == p_flow_inst->api_req_flow_info.key.flow_type) &&
+ b_flow_is_destined_to_host))
+ {
+ if(BCM_ERR_OK != (ret = sw_util_flow_info_validate(&p_flow_inst->api_req_flow_info)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "Failed switch validation\n");
+ break;
+ }
+ }
+
+ p_flow_inst->current_flow_info.data.admin_state = BCMBAL_STATE_UP;
+
+ /* Set the expected state of the oper_status upon success */
+ p_flow_inst->api_req_flow_info.data.oper_status = BCMBAL_STATUS_UP;
+
+ fsm_event.event_type = FLOW_FSM_EVENT_TYPE_ADMIN_UP;
+ b_generate_event = BCMOS_TRUE;
+
+ } while(0);
+
+ if(BCM_ERR_OK != ret)
+ {
+ flow_free_by_entry(p_flow_inst);
+ break;
+ }
+ }
+ /*
+ * NOTE: This is not a complete implementation of the admin down processing.
+ *
+ * @todo - complete admin down processing
+ */
+ else if(((BCMBAL_STATE_DOWN == admin_state_req) || found_new_flow)
+ && (BCMBAL_STATE_DOWN != p_flow_inst->current_flow_info.data.admin_state))
+ {
+ p_flow_inst->current_flow_info.data.admin_state = BCMBAL_STATE_DOWN;
+
+ /* Set the expected state of the oper_status upon success */
+ p_flow_inst->api_req_flow_info.data.oper_status = BCMBAL_STATUS_DOWN;
+
+ fsm_event.event_type = FLOW_FSM_EVENT_TYPE_ADMIN_DN;
+ b_generate_event = BCMOS_TRUE;
+ }
+ else
+ {
+ /* @todo implement a MODIFY here */
+
+ break; /* no state change detected - do nothing for now */
+ }
+
+ }while(0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_flow);
+
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
+ ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
+ break;
+ }
+
+ /* If there was an event generated, call the state machine exec */
+ if(BCMOS_TRUE == b_generate_event)
+ {
+ /*
+ * Run the flow FSM to process this event
+ */
+ ret = flow_fsm_exec(p_flow_inst, &fsm_event);
+ }
+ break;
+ }
+
+ case (BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+
+ BCM_LOG(DEBUG, log_id_flow, "Processing a flow GET REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ }
+ else
+ {
+ /*
+ * Find the specified flow instance
+ */
+ p_flow_inst = flow_inst_get(p_flow_key, FLOW_FLAG_ACTIVE, NULL);
+ }
+
+ if(NULL == p_flow_inst)
+ {
+ if(BCM_ERR_STATE != ret)
+ {
+ /* This is not a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_flow, "ERROR - Specified flow (%d:%s) not found\n",
+ p_flow_key->flow_id,
+ CORE_FSM_FLOW_TYPE_GET_STR(p_flow_key->flow_type));
+ ret = BCM_ERR_NOENT;
+ }
+
+ break;
+ }
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ p_flow_inst->current_flow_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_flow_cfg *)msg_payload) = p_flow_inst->current_flow_info;
+
+ } while (0);
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_flow);
+
+ }
+ break;
+
+ case (BCMBAL_OBJ_MSG_TYPE_CLEAR):
+ {
+ BCM_LOG(DEBUG, log_id_flow, "Processing a flow CLEAR REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ /*
+ * Find the specified flow instance
+ */
+ p_flow_inst = flow_inst_get(p_flow_key, FLOW_FLAG_ACTIVE, NULL);
+
+ if(NULL == p_flow_inst)
+ {
+ /* This is a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_flow, "ERROR - Specified flow (%d:%s) not found\n",
+ p_flow_key->flow_id,
+ CORE_FSM_FLOW_TYPE_GET_STR(p_flow_key->flow_type));
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ } while(0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_flow);
+
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
+ ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
+ break;
+ }
+
+ /* Merge the requested flow data with the current flow data,
+ * and this is the new request.
+ */
+ bcmbal_flow_object_overlay_w_dst_priority(&p_flow_inst->api_req_flow_info,
+ &p_flow_inst->current_flow_info);
+ /*
+ * Run the flow FSM to process this event
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ fsm_event.event_type = FLOW_FSM_EVENT_TYPE_REMOVE;
+
+ ret = flow_fsm_exec(p_flow_inst, &fsm_event);
+ }
+
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_flow, "Unsupported operation on flow object (%d)\n",
+ oper_type );
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_flow);
+
+ break;
+ }
+ }
+
+ BCM_LOG(DEBUG, log_id_flow, "%s returns : %s\n", __FUNCTION__, bcmos_strerror(ret));
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to process a flow object event received
+ * from one of the BAL apps.
+ *
+ * @param msg_payload A pointer to the util message
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_flow_util_msg(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ flow_inst *p_flow_inst;
+ flow_fsm_event fsm_event;
+ bcmbal_msg_type type;
+ bcmbal_flow_key key;
+
+ type = bcmbal_type_minor_get(msg_payload);
+
+ BCM_LOG(DEBUG, log_id_flow, "processing a flow %s util message from %s\n",
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ /* recover the key from the message */
+ key = ((bal_util_msg_ind *)msg_payload)->obj_key.flow_key;
+
+ do
+ {
+ BCM_LOG(DEBUG, log_id_flow, "Got flow key id from util message (%d)\n", key.flow_id);
+
+ /*
+ * Get the flow instance that's being referenced
+ */
+ if(NULL == (p_flow_inst = flow_inst_get(&key, FLOW_FLAG_ACTIVE, NULL)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "invalid flow (%d, %s) found while processing a util message from %s\n",
+ key.flow_id,
+ CORE_FSM_FLOW_TYPE_GET_STR(key.flow_type),
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ ret = BCM_ERR_INTERNAL;
+
+ break;
+ }
+
+ /*
+ * Record the msg for further processing access
+ */
+ fsm_event.msg = msg_payload;
+
+ if (BAL_MSG_TYPE_IND == type)
+ {
+ fsm_event.event_type = FLOW_FSM_EVENT_TYPE_UTIL_MSG;
+ }
+ else if (BAL_MSG_TYPE_AUTO_IND == type)
+ {
+ fsm_event.event_type = FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG;
+ }
+ else
+ {
+ ret = BCM_ERR_NOT_SUPPORTED;
+ BCM_LOG(ERROR, log_id_flow,
+ "Unknown message type received from the UTIL"
+ " (not one of IND:AUTO_IND) (type:%d)\n",
+ type);
+ break;
+ }
+
+ /*
+ * Run the Flow FSM to process this event
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ ret = flow_fsm_exec(p_flow_inst, &fsm_event);
+ }
+ }
+ while(0);
+
+ return ret;
+}
+
+/*
+ * Helper functions
+ */
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a flow instance of the specified
+ * class.
+ *
+ * @param key A pointer to the key of the flow being
+ * referenced
+ * @param search_flag A flag specifying the type of flow
+ * instance to be retrieved
+ *
+ * @param is_new_flow A returned value signifying whether a found flow was on the free list
+ *
+ * @returns flow_inst_t* A pointer to the found flow instance,
+ * or NULL if one is not found
+ *
+ *****************************************************************************/
+static flow_inst *flow_inst_get(bcmbal_flow_key *key, flow_flag search_flag, bcmos_bool *is_new_flow)
+{
+ flow_inst *current_entry = NULL;
+
+ if(NULL != is_new_flow)
+ {
+ *is_new_flow = BCMOS_FALSE;
+ }
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ if(FLOW_FLAG_ACTIVE & search_flag)
+ {
+ TAILQ_FOREACH(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next)
+ {
+
+ if((current_entry->api_req_flow_info.key.flow_id == key->flow_id)
+ &&
+ ((FLOW_FLAG_IGNORE_DIR & search_flag) ?
+ 1:(current_entry->api_req_flow_info.key.flow_type == key->flow_type)))
+ {
+ BCM_LOG(DEBUG, log_id_flow, "Found active flow\n");
+ /* The flow instance pointer is in current_entry */
+ break;
+ }
+ }
+ }
+
+ /*
+ * Next, check the free list if the caller has chosen to do so
+ */
+ if((FLOW_FLAG_FREE & search_flag) && (NULL == current_entry))
+ {
+ /* Now check the free list */
+ if(!TAILQ_EMPTY(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list))
+ {
+ /* Just grab the first entry */
+ current_entry = TAILQ_FIRST(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list);
+
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list, current_entry, flow_inst_next);
+
+ /* And add it to the active list */
+ TAILQ_INSERT_TAIL(&FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list, current_entry, flow_inst_next);
+
+ /*
+ * Initialize the fsm state and some of the fields
+ */
+ current_entry->fsm_state = FLOW_FSM_STATE_NULL;
+ current_entry->p_peer_flow_inst = NULL;
+
+ if(NULL != is_new_flow)
+ {
+ *is_new_flow = BCMOS_TRUE;
+ }
+
+ BCM_LOG(DEBUG, log_id_flow, "Using new flow\n");
+
+ }
+ }
+
+ if((FLOW_FLAG_ANY & search_flag) && (NULL == current_entry))
+ {
+ /*A flow was not found on either list */
+ BCM_LOG(DEBUG, log_id_flow, "************** ERROR: no flow found\n");
+ }
+
+ return current_entry;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a flow instance by access_if_id and svc_port_id
+ *
+ * @param access_if_id access interface id of the flow being searched
+ * @param type flow type (direction)
+ * @param svc_port_id svc_port_id of the flow being searched
+ *
+ * @returns flow_inst_t* A pointer to the found flow instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+flow_inst *flow_get_by_svc_id(uint16_t access_if_id, bcmbal_flow_type type, bcmbal_service_port_id svc_port_id)
+{
+ flow_inst *current_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ TAILQ_FOREACH(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next)
+ {
+
+ if((current_entry->api_req_flow_info.data.access_int_id == access_if_id)
+ &&
+ (current_entry->api_req_flow_info.key.flow_type == type)
+ &&
+ (current_entry->api_req_flow_info.data.svc_port_id == svc_port_id))
+ {
+ /* The flow instance pointer is in current_entry */
+ break;
+ }
+ }
+
+ return current_entry;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve the current flow info for the specified
+ * flow instance.
+ *
+ * @param key A flow key
+ *
+ * @returns bcmbal_flow_cfg* A pointer to the current flow info for the
+ * specified flow, or NULL if the flow is not found
+ *****************************************************************************/
+bcmbal_flow_cfg *flow_get_current_info_by_key(bcmbal_flow_key key)
+{
+ flow_inst *current_entry = NULL;
+
+ /*
+ * Check the active list
+ */
+ TAILQ_FOREACH(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next)
+ {
+
+ if((current_entry->current_flow_info.key.flow_id == key.flow_id)
+ &&
+ (current_entry->current_flow_info.key.flow_type == key.flow_type))
+ {
+ /* The flow instance pointer is in current_entry */
+ break;
+ }
+ }
+
+ if(current_entry)
+ {
+ return &(current_entry->current_flow_info);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a flow instance by access_if_id and agg_port_id
+ *
+ * @param access_if_id access interface id of the flow being searched
+ * @param agg_port_id svc_port_id of the flow being searched
+ *
+ * @returns flow_inst_t* A pointer to the found flow instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+flow_inst *flow_get_by_agg_id(uint16_t access_if_id, bcmbal_aggregation_port_id agg_port_id)
+{
+ flow_inst *current_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ TAILQ_FOREACH(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next)
+ {
+
+ if((current_entry->current_flow_info.data.access_int_id == access_if_id)
+ &&
+ (current_entry->current_flow_info.key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ &&
+ (current_entry->current_flow_info.data.agg_port_id == agg_port_id))
+ {
+ /* The flow instance pointer is in current_entry */
+ break;
+ }
+ }
+
+ return current_entry;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve the first flow instance associated with
+ * a subscriber terminal
+ *
+ * @param access_if_id access interface id of the flow being searched
+ * @param type flow type (direction)
+ * @param sub_term_id the subscriber terminal associated with the flow being
+ * searched
+ * @param sub_term_uni uni port on ONU
+ *
+ * @returns flow_inst_t* A pointer to the found flow instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+static flow_inst *flow_get_first_by_sub_term(uint16_t access_if_id,
+ bcmbal_flow_type type,
+ uint16_t sub_term_id,
+ uint16_t sub_term_uni)
+{
+ flow_inst *current_entry = NULL;
+ flow_inst *matched_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ TAILQ_FOREACH(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next)
+ {
+
+ if((current_entry->current_flow_info.data.access_int_id == access_if_id)
+ &&
+ (current_entry->current_flow_info.key.flow_type == type)
+ &&
+ (current_entry->current_flow_info.data.sub_term_id == sub_term_id)
+ &&
+ (current_entry->current_flow_info.data.sub_term_uni_idx == sub_term_uni))
+ {
+ /* The flow instance pointer is in current_entry */
+ matched_entry = current_entry;
+ break;
+ }
+ else if((current_entry->current_flow_info.data.access_int_id == access_if_id)
+ &&
+ (current_entry->current_flow_info.key.flow_type == type)
+ &&
+ (current_entry->current_flow_info.data.sub_term_id == sub_term_id))
+ {
+ if(NULL == matched_entry)
+ matched_entry = current_entry; /* store the first matched entry irrespective of uni port match */
+ }
+ }
+
+ return matched_entry;
+}
+
+
+bcmos_errno svc_port_id_for_sub_term_ds_flow_get(uint16_t access_if_id,
+ uint16_t sub_term_id,
+ uint16_t sub_term_uni,
+ uint16_t *svc_port_id)
+{
+ flow_inst *p_flow_inst;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ if(NULL == (p_flow_inst = flow_get_first_by_sub_term(access_if_id,
+ BCMBAL_FLOW_TYPE_DOWNSTREAM,
+ sub_term_id,
+ sub_term_uni)))
+ {
+ ret = BCM_ERR_NOENT;
+ }
+ else
+ {
+ *svc_port_id = p_flow_inst->current_flow_info.data.svc_port_id;
+ }
+
+ return ret;
+
+}
+
+#ifdef FREE_FLOW_BY_KEY_SUPPORTED
+/*****************************************************************************/
+/**
+ * @brief A function to free a flow instance specified by a supplied key.
+ *
+ *
+ * @param key A pointer to the key of the subscriber terminal instance to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_free_by_key(bcmbal_flow_key *key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ flow_inst *current_entry;
+ flow_inst *p_temp_entry;
+
+ BUG_ON(NULL == key);
+
+ /*
+ * First, check the active list (an active flow can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next,
+ p_temp_entry)
+ {
+ if((current_entry->api_req_flow_info.key.flow_id == key->flow_id) &&
+ (current_entry->api_req_flow_info.key.flow_type == key->flow_type))
+ {
+
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list, current_entry, flow_inst_next);
+
+ /* And add it to the free list */
+ current_entry->fsm_state = FLOW_FSM_STATE_NULL;
+ current_entry->p_sub_term_fsm = NULL;
+ TAILQ_INSERT_TAIL(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list, current_entry, flow_inst_next);
+ break;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+/*****************************************************************************/
+/**
+ * @brief A function to free a flow instance specified by a the supplied
+ * entry pointer.
+ *
+ * @param p_entry A pointer to the entry to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno flow_free_by_entry(flow_inst *p_entry)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ flow_inst *current_entry;
+ flow_inst *p_temp_entry;
+
+ /*
+ * First, check the active list (an active flow can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
+ flow_inst_next,
+ p_temp_entry)
+ {
+ if(current_entry == p_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list, current_entry, flow_inst_next);
+ break;
+ }
+ }
+
+ /* And add it to the free list */
+ p_entry->fsm_state = FLOW_FSM_STATE_NULL;
+
+ /* And initialize the current object in the flow instance */
+ flow_inst_entry_obj_init(p_entry);
+
+ TAILQ_INSERT_TAIL(&FLOW_FSM_FLOW_LIST_CTX_PTR->free_flow_list, p_entry, flow_inst_next);
+
+ return ret;
+}
+
+static bcmos_errno flow_tm_auto_create(bcmbal_flow_cfg *p_flow_info, tm_sched_inst **p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_cfg tm_sched_default_cfg;
+ bcmbal_tm_sched_owner owner;
+ bcmbal_tm_sched_key tm_sched_key;
+ do
+ {
+ tm_sched_key.dir = BCMBAL_TM_SCHED_DIR_US;
+ BCMBAL_CFG_INIT(&tm_sched_default_cfg, tm_sched, tm_sched_key);
+ owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
+ owner.u.agg_port.intf_id = p_flow_info->data.access_int_id;
+ owner.u.agg_port.sub_term_id = p_flow_info->data.sub_term_id;
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, owner, owner);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, creation_mode, BCMBAL_TM_CREATION_MODE_AUTO);
+ if(BCMBAL_CFG_PROP_IS_SET(p_flow_info,flow,sla))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&(tm_sched_default_cfg.data.rate),tm_shaping, sbr, p_flow_info->data.sla.min_rate);
+ BCMBAL_ATTRIBUTE_PROP_SET(&(tm_sched_default_cfg.data.rate),tm_shaping, pbr, p_flow_info->data.sla.max_rate);
+ }
+ if (BCM_ERR_OK != (ret = bcmbal_tm_sched_auto_create(tm_sched_default_cfg, p_tm_sched_inst)))
+ {
+ BCM_LOG(ERROR, log_id_flow, "Could not create the auto tm sched\n");
+ break;
+ }
+ }while(0);
+ return ret;
+}
+
+static bcmos_errno flow_tm_get(bcmbal_flow_cfg *p_flow_info, tm_sched_inst **p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow_info,
+ flow,
+ agg_port_id))
+ {
+ BCM_LOG(DEBUG, log_id_flow,
+ "Using ALLOC ID supplied by the user (%d)\n",
+ p_flow_info->data.agg_port_id );
+
+ *p_tm_sched_inst = tm_sched_find_agg_port_node(p_flow_info->data.access_int_id, p_flow_info->data.agg_port_id);
+ if(NULL == *p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "agg port %d (intf id %d sub term id %d ) has no tm sched\n",
+ p_flow_info->data.agg_port_id, p_flow_info->data.access_int_id, p_flow_info->data.sub_term_id);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(p_flow_info->data.sub_term_id != (*p_tm_sched_inst)->req_tm_sched_info.data.owner.u.agg_port.sub_term_id)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "agg port %d (intf id %d) is already assign to sub term %d (not %d) \n",
+ p_flow_info->data.agg_port_id, p_flow_info->data.access_int_id,
+ (*p_tm_sched_inst)->req_tm_sched_info.data.owner.u.agg_port.sub_term_id,
+ p_flow_info->data.sub_term_id);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_flow, "Getting a new ALLOC ID from resource manager\n");
+ /*create a new agg port tm and allocate a new agg port id */
+ ret = flow_tm_auto_create(p_flow_info, p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_flow,
+ "could not create the auto tm sched for agg port %d (intf id %d)\n",
+ p_flow_info->data.agg_port_id, p_flow_info->data.access_int_id);
+ break;
+ }
+ BCMBAL_CFG_PROP_SET(p_flow_info, flow, agg_port_id,
+ (*p_tm_sched_inst)->req_tm_sched_info.data.owner.u.agg_port.agg_port_id);
+ }
+ }while(0);
+ return ret;
+}
+/*@}*/
diff --git a/bal_release/src/core/main/flow_fsm.h b/bal_release/src/core/main/flow_fsm.h
new file mode 100755
index 0000000..c6bb3a0
--- /dev/null
+++ b/bal_release/src/core/main/flow_fsm.h
@@ -0,0 +1,170 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file flow_fsm.h
+ * @brief Code to support the BAL Flow FSM
+ *
+ * @defgroup flow Flow
+ * @ingroup core
+ */
+
+#ifndef FLOW_FSM_H
+#define FLOW_FSM_H
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_api.h>
+
+#define FLOW_ALLOCATION_BLOCK_SIZE (16384)
+
+#define CORE_FSM_FLOW_TYPE_GET_STR(_fsm_flow_type) (BCMBAL_FLOW_TYPE_MULTICAST == (_fsm_flow_type) ? "Multicast":\
+ BCMBAL_FLOW_TYPE_BROADCAST == (_fsm_flow_type) ? "Broadcast":\
+ BCMBAL_FLOW_TYPE_DOWNSTREAM == (_fsm_flow_type) ? "Downstream":\
+ BCMBAL_FLOW_TYPE_UPSTREAM == (_fsm_flow_type) ? "Upstream":"Invalid")
+
+
+typedef enum
+{
+ FLOW_FSM_EVENT_TYPE_NONE = -1,
+ FLOW_FSM_EVENT_TYPE_ADMIN_UP ,
+ FLOW_FSM_EVENT_TYPE_ADMIN_DN ,
+ FLOW_FSM_EVENT_TYPE_REMOVE ,
+ FLOW_FSM_EVENT_TYPE_UTIL_MSG ,
+ FLOW_FSM_EVENT_TYPE_UTIL_AUTO_MSG ,
+
+
+ FLOW_FSM_EVENT_TYPE__LAST,
+ FLOW_FSM_EVENT_TYPE__NUM_OF
+} flow_fsm_event_type;
+
+
+
+typedef enum
+{
+ FLOW_FSM_STATE_NONE = -1,
+ FLOW_FSM_STATE_NULL ,
+ FLOW_FSM_STATE_CONFIGURING ,
+ FLOW_FSM_STATE_CONFIGURED ,
+ FLOW_FSM_STATE_REMOVING ,
+
+
+ FLOW_FSM_STATE__LAST,
+ FLOW_FSM_STATE__NUM_OF
+} flow_fsm_state;
+
+
+typedef enum
+{
+ FLOW_FLAG_ACTIVE = 1<<0, /**< A flow is on the active list */
+ FLOW_FLAG_FREE = 1<<1, /**< A flow is on the free list */
+ FLOW_FLAG_ANY = (FLOW_FLAG_ACTIVE | FLOW_FLAG_FREE), /**< A flow is on either the active or free list */
+ FLOW_FLAG_IGNORE_DIR = 1<<2 /**< Ignore direction during operation */
+} flow_flag;
+
+
+typedef struct flow_fsm_event_t
+{
+ flow_fsm_event_type event_type; /**< The flow fsm events */
+ void *msg;
+
+ /* other necessary information */
+} flow_fsm_event;
+
+
+/* Flow state in MAC plugin */
+typedef enum
+{
+ FLOW_MAC_STATE_NONE = 0x00, /**< Neither svc_id nor agg_id configured */
+ FLOW_MAC_STATE_SVC = 1<<0, /**< SVC is configured */
+ FLOW_MAC_STATE_AGG = 1<<1, /**< AGG is configured */
+ FLOW_MAC_STATE_READY = (FLOW_MAC_STATE_SVC | FLOW_MAC_STATE_AGG)
+} flow_mac_state;
+
+typedef struct flow_inst flow_inst;
+struct flow_inst
+{
+ bcmbal_flow_cfg current_flow_info; /**< The current information for this flow (used for GET) */
+ bcmbal_flow_cfg api_req_flow_info; /**< The last flow object info received from the Public API */
+ flow_fsm_state fsm_state; /**< The Flow FSM state */
+ flow_mac_state mac_state; /**< Flow state from MAC point of view */
+ struct flow_inst *p_peer_flow_inst; /**< Pointer to the linked flow in the opposite direction (if any) */
+ struct sub_term_inst *p_sub_term_inst; /**< Pointer to subscriber terminal instance associated with this flow */
+ bcmos_timer timer_info; /**< A structure used for the state machine timeout timer */
+ TAILQ_ENTRY(flow_inst) flow_inst_next ; /**< TAILQ link */
+ TAILQ_ENTRY(flow_inst) rsc_mgr_list_next ; /**< TAILQ link used for storing in Resource mgr list */
+};
+
+
+/*
+ * Flow FSM data structures
+ */
+typedef struct flow_fsm_ctx
+{
+ /* Lists of free flow entries and active flow entries
+ */
+ TAILQ_HEAD(free_flow_list_head, flow_inst) free_flow_list;
+
+ TAILQ_HEAD(active_flow_list_head, flow_inst) active_flow_list;
+
+} flow_fsm_ctx;
+
+
+/*
+ * Function declarations
+ */
+extern bcmos_errno flow_fsm_init(void);
+extern bcmos_errno flow_fsm_finish(void);
+
+extern bcmos_errno process_flow_object(void *msg_payload);
+
+extern bcmos_errno process_flow_util_msg(void *msg_payload);
+
+extern flow_inst *flow_get_by_svc_id(uint16_t access_if_id,
+ bcmbal_flow_type type,
+ bcmbal_service_port_id svc_port_id);
+
+extern flow_inst *flow_get_by_agg_id(uint16_t access_if_id,
+ bcmbal_aggregation_port_id agg_port_id);
+
+extern bcmos_errno svc_port_id_for_sub_term_ds_flow_get(uint16_t access_if_id,
+ uint16_t sub_term_id,
+ uint16_t sub_term_uni,
+ uint16_t *svc_port_id);
+
+extern bcmbal_flow_cfg *flow_get_current_info_by_key(bcmbal_flow_key key);
+
+
+/*@}*/
+
+#endif /*FLOW_FSM_H */
+
diff --git a/bal_release/src/core/main/fsm_common.c b/bal_release/src/core/main/fsm_common.c
new file mode 100644
index 0000000..0e1a8e5
--- /dev/null
+++ b/bal_release/src/core/main/fsm_common.c
@@ -0,0 +1,358 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file fsm_common.c
+ * @brief Common code to support the BAL access terminal FSMs
+ *
+ * @addtogroup core
+ */
+
+/*@{*/
+
+/*--- project includes ---*/
+#include <bcmos_system.h>
+#include <acc_term_fsm.h>
+#include <bal_msg.h>
+#include <bal_api.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include <bal_osmsg.h>
+#include <fsm_common.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+#endif
+
+
+/*****************************************************************************/
+/**
+ * @brief Send a management message response
+ *
+ * A Worker module function that sends the specified message to the
+ * BAL Public API.
+ *
+ * @param cmd_status The results of the command associated with the message
+ *
+ * @param msg_payload A pointer to the message to be sent
+ *
+ * @param oper_type The operation type of the object in this response
+ *
+ * @param log_id The log id of the calling component
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+bcmos_errno mgmt_msg_send_balapi_rsp(bcmos_errno cmd_status,
+ void *msg_payload,
+ bcmbal_obj_msg_type oper_type,
+ dev_log_id log_id)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id, "sending rsp message to the public api (payload at %p)\n",
+ msg_payload);
+
+ /*
+ * Send the response back to the BAL Public API backend
+ */
+ bcmbal_msg_hdr_set(msg_payload,
+ bcmbal_type_major_get(msg_payload),
+ BAL_MSG_TYPE_RSP,
+ BAL_SUBSYSTEM_CORE,
+ bcmbal_msg_id_obj_get(msg_payload),
+ bcmbal_msg_id_oper_get(msg_payload),
+ bcmbal_ex_id_get(msg_payload));
+
+ /* Return the command status to the Public API backend */
+ ((bcmbal_obj *)(msg_payload))->status = cmd_status;
+
+ ((bcmbal_obj *)(msg_payload))->dir = BCMBAL_OBJ_MSG_DIR_RESPONSE;
+
+ ((bcmbal_obj *)(msg_payload))->type = oper_type;
+
+ if(BCM_ERR_OK != cmd_status)
+ {
+ ((bcmbal_obj *)(msg_payload))->presence_mask = 0;
+ }
+
+ /* Send message, but don't free it. It is still being used by FSM */
+ if(BCM_ERR_OK != (ret = bcmbal_msg_send(p_bal_core_to_api_queue, msg_payload, BCMOS_MSG_SEND_NO_FREE_ON_ERROR)))
+ {
+ BCM_LOG(ERROR, log_id, "msg_send failed to send rsp to core (error:%s)\n",
+ bcmos_strerror(ret));
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id, "RSP message sent to the public api with status=%s\n",
+ bcmos_strerror(cmd_status));
+ }
+
+ return ret;
+
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief Send a management message indication
+ *
+ * A Worker module function that sends the specified message to the
+ * BAL Public API.
+ *
+ * @param cmd_status The results of the command associated with the message
+ *
+ * @param is_auto_ind Set to BCMOS_TRUE if the indication to be sent is an AUTO IND
+ *
+ * @param msg_payload A pointer to the message to be sent (a BAL object!) (may be NULL)
+ *
+ * @param log_id The log id of the calling component
+ *
+ * @returns bcmos_errno
+ *
+ *****************************************************************************/
+static bcmos_errno _mgmt_msg_send_balapi_ind(bcmos_errno cmd_status,
+ bcmos_bool is_auto_ind,
+ void *msg_payload, /* If this is NULL, there is no message body */
+ dev_log_id log_id)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ uint16_t payload_size;
+ void *p_ind_msg;
+ bcmbal_obj_id obj_type;
+
+ if(NULL == msg_payload)
+ {
+ obj_type = BCMBAL_OBJ_ID_ANY;
+ payload_size = sizeof(bcmbal_obj);
+ }
+ else
+ {
+ switch(((bcmbal_obj *)msg_payload)->obj_type)
+ {
+ case (BCMBAL_OBJ_ID_FLOW):
+ {
+ payload_size = sizeof(bcmbal_flow_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_ACCESS_TERMINAL):
+ {
+ payload_size = sizeof(bcmbal_access_terminal_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_INTERFACE):
+ {
+ payload_size = sizeof(bcmbal_interface_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL):
+ {
+ payload_size = sizeof(bcmbal_subscriber_terminal_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_GROUP):
+ {
+ payload_size = sizeof(bcmbal_group_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_TM_SCHED):
+ {
+ payload_size = sizeof(bcmbal_tm_sched_cfg);
+ break;
+ }
+
+ case (BCMBAL_OBJ_ID_TM_QUEUE):
+ {
+ payload_size = sizeof(bcmbal_tm_queue_cfg);
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id, "indication for object (%d) not supported\n",
+ ((bcmbal_obj *)msg_payload)->obj_type);
+ ret = BCM_ERR_PARM;
+ goto out;
+ }
+ }
+
+ }
+
+ p_ind_msg = bcmbal_msg_calloc(payload_size);
+
+ if(NULL == msg_payload)
+ {
+ ((bcmbal_obj *)p_ind_msg)->obj_type = obj_type;
+ }
+ else
+ {
+ memcpy(p_ind_msg, msg_payload, payload_size);
+ }
+
+ /*
+ * Send the indication back to the BAL Public API backend
+ */
+ bcmbal_msg_hdr_set(p_ind_msg,
+ BCMBAL_MGMT_API_IND_MSG,
+ (BCMOS_TRUE == is_auto_ind) ? BAL_MSG_TYPE_AUTO_IND : BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_CORE,
+ ((bcmbal_obj *)p_ind_msg)->obj_type,
+ 0,
+ 0);
+
+ /* Return the command status to the Public API backend */
+ ((bcmbal_obj *)(p_ind_msg))->status = cmd_status;
+
+ ((bcmbal_obj *)(p_ind_msg))->type = BCMBAL_OBJ_MSG_TYPE_GET;
+ ((bcmbal_obj *)(p_ind_msg))->dir = BCMBAL_OBJ_MSG_DIR_RESPONSE;
+
+ BCM_LOG(DEBUG, log_id, "sending IND message to the public api (payload at %p)\n", p_ind_msg);
+
+ if(BCM_ERR_OK != (ret = bcmbal_msg_send(p_bal_core_to_api_ind_queue, p_ind_msg, BCMOS_MSG_SEND_AUTO_FREE)))
+ {
+ BCM_LOG(ERROR, log_id, "msg_send failed to send IND to public API (%s)\n", bcmos_strerror(ret));
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id, "IND message sent to the public api with status=%s\n",
+ bcmos_strerror(cmd_status));
+ }
+
+ out:
+ return ret;
+
+}
+
+bcmos_errno mgmt_msg_send_balapi_ind(bcmos_errno cmd_status,
+ void *msg_payload, /* If this is NULL, there is no message body */
+ dev_log_id log_id)
+{
+
+ return _mgmt_msg_send_balapi_ind(cmd_status,
+ BCMOS_FALSE,
+ msg_payload,
+ log_id);
+}
+
+bcmos_errno mgmt_msg_send_balapi_auto_ind(bcmos_errno cmd_status,
+ void *msg_payload, /* If this is NULL, there is no message body */
+ dev_log_id log_id)
+{
+
+ return _mgmt_msg_send_balapi_ind(cmd_status,
+ BCMOS_TRUE,
+ msg_payload,
+ log_id);
+}
+
+/*****************************************************************************/
+/**
+ * @brief Create and Start the FSM timer
+ *
+ * @param p_timer_inst A pointer to an instance of a timer data structure
+ *
+ * @param p_inst An opaque pointer to an FSM instance to be passed to the timer
+ * expiry handler
+ *
+ * @param p_timer_expiry_handler A timer expiry handler function
+ *
+ * @param delay The delay interval (in mS) for this timer to run before the
+ * expiry handler is called
+ *
+ * @param log_id The log_id to use when logging errors encountered in this
+ * function
+ *
+ * @returns bcmos_errno
+ */
+bcmos_errno fsm_timer_start(bcmos_timer *p_timer_inst,
+ void *p_inst,
+ F_bcmos_timer_handler p_timer_expiry_handler,
+ uint32_t delay, /* delay is in mS */
+ dev_log_id log_id)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmos_timer_parm timer_spec;
+
+ /* Parameter checks */
+ BUG_ON(p_inst == NULL);
+ BUG_ON(p_timer_expiry_handler == NULL);
+ BUG_ON(p_timer_inst == NULL);
+
+
+ /* Create bcm_os timer */
+ timer_spec.owner = BCMOS_MODULE_ID_WORKER_MGMT;
+ timer_spec.handler = p_timer_expiry_handler;
+ timer_spec.data = (long) p_inst;
+ timer_spec.periodic = BCMOS_FALSE;
+
+ if (BCM_ERR_OK != bcmos_timer_create(p_timer_inst, &timer_spec))
+ {
+ BCM_LOG(ERROR, log_id, "Can't create timer for FSM\n");
+ ret = BCM_ERR_NORES;
+ }
+ else
+ {
+ /* Start the timer. Timer resolution is in uS*/
+ bcmos_timer_start(p_timer_inst, delay*1000);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief Stop and delete the specified FSM timer
+ *
+ * @param p_timer_inst A pointer to an instance of a timer data structure
+ *
+ */
+void fsm_timer_stop(bcmos_timer *p_timer_inst)
+{
+ /* Parameter checks */
+ BUG_ON(p_timer_inst == NULL);
+
+ bcmos_timer_destroy(p_timer_inst);
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/fsm_common.h b/bal_release/src/core/main/fsm_common.h
new file mode 100644
index 0000000..0e5b803
--- /dev/null
+++ b/bal_release/src/core/main/fsm_common.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file fsm_common.h
+ * @brief Common code to support the BAL Access Terminal FSMs
+ *
+ * @ingroup core
+ */
+#ifndef FSM_COMMON_H
+#define FSM_COMMON_H
+
+/*@{*/
+
+#include <bal_common.h>
+#include <bal_obj.h>
+
+#define TIMER_DURATION_1_SEC (1000)
+#define TIMER_DURATION_IN_SEC(time_in_seconds) (TIMER_DURATION_1_SEC*time_in_seconds)
+
+
+extern bcmos_errno mgmt_msg_send_balapi_rsp(bcmos_errno cmd_status,
+ void *msg_payload,
+ bcmbal_obj_msg_type oper_type,
+ dev_log_id log_id);
+
+extern bcmos_errno mgmt_msg_send_balapi_ind(bcmos_errno cmd_status,
+ void *msg_payload, /* If this is NULL, there is no message body */
+ dev_log_id log_id);
+
+extern bcmos_errno mgmt_msg_send_balapi_auto_ind(bcmos_errno cmd_status,
+ void *msg_payload, /* If this is NULL, there is no message body */
+ dev_log_id log_id);
+
+extern bcmos_errno fsm_timer_start(bcmos_timer *p_timer_inst,
+ void *p_inst,
+ F_bcmos_timer_handler p_timer_expiry_handler,
+ uint32_t delay, /* delay is in mS */
+ dev_log_id log_id);
+
+extern void fsm_timer_stop(bcmos_timer *p_timer_inst);
+
+/*@}*/
+
+#endif /*FSM_COMMON_H */
diff --git a/bal_release/src/core/main/group_fsm.c b/bal_release/src/core/main/group_fsm.c
new file mode 100644
index 0000000..97b0a45
--- /dev/null
+++ b/bal_release/src/core/main/group_fsm.c
@@ -0,0 +1,2162 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file group_fsm.c
+ * @brief Code to support the BAL group FSM
+ *
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <group_fsm.h>
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include "rsc_mgr.h"
+
+#include <bal_objs.h>
+#include <fsm_common.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+ /*
+ * @brief The logging device id for group
+ */
+static dev_log_id log_id_group;
+#endif
+
+/* local function declarations */
+static bcmos_errno group_fsm_create(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_destroy(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_add(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_remove(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_set(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_configuring_util_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_deleting_util_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_ignore_api_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_state_err(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event);
+
+static bcmos_errno group_fsm_exec(group_inst *p_group_inst, group_fsm_event *p_event);
+
+static group_inst *group_inst_get(bcmbal_group_key *key, group_flag search_flag);
+
+static bcmos_errno group_free_by_entry(group_inst *p_entry);
+
+static bcmos_errno bcmbal_group_object_member_remove(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group);
+
+static bcmos_errno bcmbal_group_object_member_add(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group);
+
+static bcmos_errno bcmbal_group_object_member_replace(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group);
+
+static bcmos_errno bcmbal_group_object_overlay(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group);
+ /*
+ * @brief The Global group fsm context data structure
+ */
+static group_fsm_ctx g_group_fsm_group_list_ctx;
+
+/*
+ * Macros for group ctx access
+ */
+#define GROUP_FSM_GROUP_LIST_CTX (g_group_fsm_group_list_ctx)
+#define GROUP_FSM_GROUP_LIST_CTX_PTR (&g_group_fsm_group_list_ctx)
+
+/*
+ * @brief The definition of a group FSM state processing function
+ */
+typedef bcmos_errno (* group_fsm_state_processor)(group_inst *, void *, group_fsm_event *);
+
+/*
+ * @brief The Group FSM state processing array
+ */
+static group_fsm_state_processor group_states[GROUP_FSM_STATE__NUM_OF][GROUP_FSM_EVENT_TYPE__NUM_OF] =
+{
+
+ [GROUP_FSM_STATE_NULL] =
+ {
+ /*
+ * Next state: COMFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_CREATE] = group_fsm_create,
+
+ /*
+ * Next state: NULL
+ */
+ [GROUP_FSM_EVENT_TYPE_DESTROY] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_ADD] = group_fsm_add,
+
+ /*
+ * Next state: NULL
+ */
+ [GROUP_FSM_EVENT_TYPE_REMOVE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_SET] = group_fsm_set,
+
+ },
+ [GROUP_FSM_STATE_CONFIGURING] =
+ {
+ /*
+ * Next state: COMFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_CREATE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: COMFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_DESTROY] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_ADD] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_REMOVE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_SET] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: CONFIGURED
+ */
+ [GROUP_FSM_EVENT_TYPE_UTIL_MSG] = group_fsm_configuring_util_msg,
+
+ },
+
+ [GROUP_FSM_STATE_CONFIGURED] =
+ {
+ /*
+ * Next state: COMFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_CREATE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_DESTROY] = group_fsm_destroy,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_ADD] = group_fsm_add,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_REMOVE] = group_fsm_remove,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [GROUP_FSM_EVENT_TYPE_SET] = group_fsm_set,
+
+ },
+
+ [GROUP_FSM_STATE_DELETING] =
+ {
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_CREATE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_DESTROY] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_ADD] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_REMOVE] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: DELETING
+ */
+ [GROUP_FSM_EVENT_TYPE_SET] = group_fsm_ignore_api_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [GROUP_FSM_EVENT_TYPE_UTIL_MSG] = group_fsm_deleting_util_msg,
+
+ },
+
+};
+
+static char *state_name_str[] =
+{
+ "GROUP_FSM_STATE_NULL",
+ "GROUP_FSM_STATE_CONFIGURING",
+ "GROUP_FSM_STATE_CONFIGURED",
+ "GROUP_FSM_STATE_DELETING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (GROUP_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), group_fsm_state);
+
+static char *group_state_name_get(group_fsm_state state)
+{
+ if(state < GROUP_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "GROUP_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "GROUP_FSM_CREATE_EVENT",
+ "GROUP_FSM_DESTROY_EVENT",
+ "GROUP_FSM_ADD_EVENT",
+ "GROUP_FSM_REMOVE_EVENT",
+ "GROUP_FSM_SET_EVENT",
+ "GROUP_FSM_UTIL_MSG_EVENT",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (GROUP_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), group_fsm_event_type);
+
+static char *group_event_name_get(group_fsm_event_type event)
+{
+ if(event < GROUP_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "GROUP_EVT_UNKNOWN";
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the current_group_info object of the
+ * supplied entry.
+ *
+ * @param p_entry A pointer to the entry to be initialized
+ *
+ *
+ * @returns void
+ *****************************************************************************/
+static void group_inst_entry_obj_init(group_inst *p_entry)
+{
+ /* The actual key content is irrelevant for free groups */
+ bcmbal_group_key key = { .group_id = 0 };
+
+ BCMBAL_CFG_INIT(&p_entry->current_group_info,
+ group,
+ key);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_group_info), BCMOS_FALSE);
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the Group FSM infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno group_fsm_init(void)
+{
+ int ii;
+ group_inst *new_entry;
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ log_id_group = bcm_dev_log_id_register("GROUP", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_group == DEV_LOG_INVALID_ID);
+#endif
+
+ /* Initialize all of the group queues */
+ TAILQ_INIT(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list);
+ TAILQ_INIT(&GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list);
+
+ /* Populate the free list with it's initial set of groups
+ */
+ for(ii=0; ii<GROUP_ALLOCATION_BLOCK_SIZE; ii++)
+ {
+
+ new_entry = bcmos_calloc(sizeof(group_inst));
+
+ if (NULL == new_entry)
+ {
+ BCM_LOG(FATAL, log_id_group, "Failed to initialize the group free list - FATAL\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ group_free_by_entry(new_entry);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to un-initialize the Group FSM infrastructure.
+ *
+ * NOTE: This is called once on shutdown and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno group_fsm_finish(void)
+{
+
+ group_inst *current_entry, *p_temp_entry;
+
+ /* Free all the entries on the active list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list,
+ group_inst_next,
+ p_temp_entry)
+ {
+ /* free up the internal allocated member info */
+ if(current_entry->current_group_info.data.members.val)
+ {
+ bcmos_free(current_entry->current_group_info.data.members.val);
+ }
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list, current_entry, group_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ /* Free all the entries on the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list,
+ group_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list, current_entry, group_inst_next);
+
+ bcmos_free(current_entry);
+ }
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing executive function
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_exec(group_inst *p_group_inst, group_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ group_fsm_state pre_state;
+ group_fsm_state_processor group_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_group_inst);
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state for debug printing
+ */
+ pre_state = p_group_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ group_state_processor = group_states[p_group_inst->fsm_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if (group_state_processor)
+ {
+ ret = group_state_processor(p_group_inst, p_event->msg, p_event);
+ } else
+ {
+ group_fsm_state_err(p_group_inst, p_event->msg, p_event);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_group, "*** Error detected during state processing\n");
+ p_group_inst->fsm_state = pre_state;
+ }
+
+ BCM_LOG(DEBUG, log_id_group, "*** Event %s, State: %s --> %s\n\n",
+ group_event_name_get(p_event->event_type),
+ group_state_name_get(pre_state),
+ group_state_name_get(p_group_inst->fsm_state));
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing for a group create command received
+ * from the BAL Public API.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_create(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ group_fsm_state pre_fsm_state;
+
+ BCM_LOG(INFO, log_id_group, "Got SET request from BAL API - create group \n");
+
+ do
+ {
+ /* save the current state */
+ pre_fsm_state = p_group_inst->fsm_state;
+ /* change Group state to CONFIGURING */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_CREATE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by switch util while create group\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils create applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_CREATE, BCMOS_TRUE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by mac util\n", bcmos_strerror(ret));
+
+ /* Reverse the (just create) group in the switch, otherwise the switch utils
+ * will be out of sync with Core and Mac. There's not
+ * much we can do about it if reversing this group fails.
+ */
+ if(BCM_ERR_OK != sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_DESTROY))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error detected by switch util while reversing create group\n");
+ }
+ else
+ {
+ /* restore the original state */
+ p_group_inst->fsm_state = pre_fsm_state;
+ }
+
+ break;
+ }
+
+ /* The hardware has properly accepted the object info, so copy object to
+ * the current state.
+ */
+ bcmbal_group_object_overlay(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_group);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing for a group destroy command received
+ * from the BAL Public API.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_destroy(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ group_fsm_state sav_state = p_group_inst->fsm_state;
+ bcmbal_group_cfg *p_group_cfg;
+ int i;
+
+ BCM_LOG(INFO, log_id_group, "Got CLEAR request from BAL API - destroy group \n");
+
+ do
+ {
+ /* change Group state to CONFIGURING */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_DELETING;
+
+ /* Destroy operation is best effort, as it is unlikely to fail */
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_DESTROY)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by switch util while destroy group\n", bcmos_strerror(ret));
+ /* if the group is busy, some flow still reference this group, skip the MAC and return error
+ no member has been clean up */
+ if(ret == BCM_ERR_INVALID_OP)
+ {
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+ p_group_inst->fsm_state = sav_state;
+ mgmt_msg_send_balapi_ind(ret, msg, log_id_group);
+ return ret;
+ }
+ break;
+ }
+
+ /*– Core calls Mac Utils create applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_DESTROY, BCMOS_TRUE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by mac util\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /* The hardware has properly accepted the object info, so copy object to
+ * the current state.
+ */
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_group);
+ /* TBD, need logic to perform error recovery if SwitchUtil success and MacUtil failed */
+ }
+ else
+ {
+ /* update resource manager on svc_port_id usage - keep going as the Mac and Switch already clean up */
+ p_group_cfg = &p_group_inst->current_group_info;
+ for(i=0; i<p_group_cfg->data.members.len; i++)
+ {
+ if(BCM_ERR_OK != rsc_mgr_gem_free(p_group_cfg->data.members.val[i].intf_id,
+ p_group_cfg->data.members.val[i].svc_port_id,
+ NULL) )
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " error encountered during destroy of group resources (gem_id: %d, intf_id:%d\n",
+ p_group_cfg->data.members.val[i].svc_port_id,
+ p_group_cfg->data.members.val[i].intf_id);
+ }
+ }
+ }
+
+ return ret;
+
+}
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing for a group set command received
+ * from the BAL Public API.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_set(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ group_inst group_inst_rvt;
+ bcmbal_group_cfg *p_group_cfg;
+ int i;
+
+ BCM_LOG(INFO, log_id_group, "Got SET request from BAL API - replace group members\n");
+
+ do
+ {
+ /* save the current state */
+ group_inst_rvt.fsm_state = p_group_inst->fsm_state;
+ /* change Group state to CONFIGURING */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_SET)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by switch util while set group members\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils add applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_SET, BCMOS_TRUE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by mac util\n", bcmos_strerror(ret));
+
+ group_inst_rvt.current_group_info = p_group_inst->api_req_group_info;
+ group_inst_rvt.api_req_group_info = p_group_inst->current_group_info;
+ /* Reverse the (just set) group from the switch otherwise the switch utils
+ * will be out of sync with Core and Mac. There's not
+ * much we can do about it if reversing this group fails.
+ */
+ if(BCM_ERR_OK != sw_util_group_set(&group_inst_rvt, BAL_UTIL_OPER_GROUP_SET))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error detected by switch util while reversing group\n");
+ }
+ else
+ {
+ /* restore the original state */
+ p_group_inst->fsm_state = group_inst_rvt.fsm_state;
+ }
+
+ break;
+ }
+ /* update resource manager on svc_port_id usage - free the gem on old members */
+ p_group_cfg = &p_group_inst->current_group_info;
+ for(i=0; i<p_group_cfg->data.members.len; i++)
+ {
+ if(BCM_ERR_OK != rsc_mgr_gem_free(p_group_cfg->data.members.val[i].intf_id,
+ p_group_cfg->data.members.val[i].svc_port_id,
+ NULL) )
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " error encountered during release of group resources (gem_id: %d, intf_id:%d\n",
+ p_group_cfg->data.members.val[i].svc_port_id,
+ p_group_cfg->data.members.val[i].intf_id);
+ }
+ }
+
+ /* set operation can be made without CREATE, so fill in the non-member info */
+ bcmbal_group_object_overlay(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state.
+ */
+ bcmbal_group_object_member_replace(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_group);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing for a group add command received
+ * from the BAL Public API.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_add(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ group_fsm_state pre_fsm_state;
+
+ BCM_LOG(INFO, log_id_group, "Got SET request from BAL API - add group members\n");
+
+ do
+ {
+ /* save the current state */
+ pre_fsm_state = p_group_inst->fsm_state;
+ /* change Group state to CONFIGURING */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_ADD)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by switch util while add group members\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils add applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_ADD, BCMOS_TRUE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by mac util\n", bcmos_strerror(ret));
+
+ /* Reverse the (just add) group member from the switch, otherwise the switch utils
+ * will be out of sync with Core and Mac. There's not
+ * much we can do about it if reversing this group fails.
+ */
+ if(BCM_ERR_OK != sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_REMOVE))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error detected by switch util while reversing add group\n");
+ }
+ else
+ {
+ /* restore the original state */
+ p_group_inst->fsm_state = pre_fsm_state;
+ }
+
+ break;
+ }
+
+ /* add operation can be made without CREATE, so fill in the non-member info */
+ bcmbal_group_object_overlay(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ /* The hardware has properly accepted the object info, so add object members to
+ * the current state.
+ */
+ bcmbal_group_object_member_add(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_group);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing for a group remove command received
+ * from the BAL Public API.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_remove(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ group_fsm_state pre_fsm_state;
+ bcmbal_group_cfg *p_group_cfg;
+ int i;
+
+ BCM_LOG(INFO, log_id_group, "Got SET request from BAL API - remove group members\n");
+
+ do
+ {
+ /* save the current state */
+ pre_fsm_state = p_group_inst->fsm_state;
+ /* change Group state to CONFIGURING */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Switch Utils to add applicable CMDs */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_REMOVE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by switch util while remove group members\n", bcmos_strerror(ret));
+ break;
+ }
+
+ /*– Core calls Mac Utils add applicable CMDs */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_REMOVE, BCMOS_TRUE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "error %s detected by mac util\n", bcmos_strerror(ret));
+
+ /* Reverse the (just remove) group member from the switch, otherwise the switch utils
+ * will be out of sync with Core and Mac. There's not
+ * much we can do about it if reversing this group fails.
+ */
+ if(BCM_ERR_OK != sw_util_group_set(p_group_inst, BAL_UTIL_OPER_GROUP_ADD))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error detected by switch util while reversing remove group\n");
+ }
+ else
+ {
+ /* restore the original state */
+ p_group_inst->fsm_state = pre_fsm_state;
+ }
+
+ break;
+ }
+
+ /* update resource manager on svc_port_id usage */
+ p_group_cfg = &p_group_inst->api_req_group_info;
+ for(i=0; i<p_group_cfg->data.members.len; i++)
+ {
+ /* if interface is not a member (e.g. already removed), skip it */
+ if(p_group_cfg->data.members.val[i].svc_port_id == 0)
+ {
+ continue;
+ }
+ if(BCM_ERR_OK != rsc_mgr_gem_free(p_group_cfg->data.members.val[i].intf_id,
+ p_group_cfg->data.members.val[i].svc_port_id,
+ NULL) )
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " error encountered during release of group resources (gem_id: %d, intf_id:%d\n",
+ p_group_cfg->data.members.val[i].svc_port_id,
+ p_group_cfg->data.members.val[i].intf_id);
+ }
+ }
+
+ /* The hardware has properly accepted the object info, so remove object members from
+ * the current state.
+ */
+ bcmbal_group_object_member_remove(&p_group_inst->api_req_group_info,
+ &p_group_inst->current_group_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_TRUE);
+
+ }while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_group);
+
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing function to ignore a received message.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_ignore_api_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(WARNING, log_id_group, "Ignoring message from BAL API when in %s state \n", group_state_name_get(p_group_inst->fsm_state));
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing function to process a message from
+ * one of the BAL apps received when the specified group instance FSM
+ * is in the CONFIGURING state.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_configuring_util_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_group_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ BCM_LOG(DEBUG, log_id_group,
+ " Received an IND message from BAL UTIL (%s) during CONFIGURING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ BCM_LOG(DEBUG, log_id_group,
+ "%s, thread %s, module %d\n", __FUNCTION__, bcmos_task_current()->name, bcmos_module_current());
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ /* Reflect the execution status in the object being returned in the indication
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ /*
+ * The group has been successfully configured
+ */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURED;
+
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_group, "Group %d: Failed in state %s. Error %s\n\n",
+ p_group_inst->api_req_group_info.key.group_id,
+ group_state_name_get(p_group_inst->fsm_state),
+ bcmos_strerror(ret));
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_FALSE);
+ p_group_inst->current_group_info.hdr.hdr.status = ret;
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_group_inst->current_group_info.hdr,
+ log_id_group);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM state processing function to process a
+ * message from one of the BAL apps received when the specified
+ * group instance FSM is in the DELETING state.
+ *
+ * @param p_group_inst Pointer to an group instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_deleting_util_msg(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_group_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ BCM_LOG(DEBUG, log_id_group,
+ " Received an IND message from BAL UTIL (%s) during DELETING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ /* Reflect the execution status in the object being returned in the indication
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ p_group_inst->current_group_info.hdr.hdr.status = ret;
+
+ /*
+ * The group has been successfully destroy
+ */
+ p_group_inst->fsm_state = GROUP_FSM_STATE_NULL;
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_group_inst->current_group_info), BCMOS_FALSE);
+ /*
+ * Send the indication back to the BAL public API
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_group_inst->current_group_info.hdr,
+ log_id_group);
+
+ /* free up the member memory */
+ if( p_group_inst->current_group_info.data.members.val)
+ {
+ bcmos_free(p_group_inst->current_group_info.data.members.val);
+ p_group_inst->current_group_info.data.members.val = NULL;
+ p_group_inst->current_group_info.data.members.len = 0;
+ }
+
+ /* Return the group to the free pool */
+ group_free_by_entry(p_group_inst);
+
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_group, "Group %d: Failed in state %s. Error %s\n\n",
+ p_group_inst->current_group_info.key.group_id,
+ group_state_name_get(p_group_inst->fsm_state),
+ bcmos_strerror(ret));
+ p_group_inst->fsm_state = GROUP_FSM_STATE_CONFIGURED;
+
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Group FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_group_inst Pointer to a group instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a group event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_fsm_state_err(group_inst *p_group_inst,
+ void *msg,
+ group_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(DEBUG, log_id_group,
+ "Error encountered processing GROUP FSM"
+ " - BAD EVENT ()\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * group object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_group_object(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
+ bcmbal_group_cfg *p_group_cfg = (bcmbal_group_cfg *)msg_payload;
+ group_inst *p_group_inst = NULL;
+ group_fsm_event fsm_event;
+ bcmbal_group_key *p_group_key;
+ bcmbal_obj_msg_type oper_type;
+ int i, j, num_svc_port_allocated = 0;
+
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_group, "Processing a group object\n");
+
+ p_group_key = &p_group_cfg->key;
+
+ oper_type = p_group_cfg->hdr.hdr.type;
+
+ /*
+ * A message pointer may be passed inside the event structure.
+ */
+ fsm_event.msg = msg_payload;
+
+ /* SET or GET or CLEAR...? */
+ switch (oper_type)
+ {
+ case (BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ bcmos_bool b_generate_event = BCMOS_FALSE;
+
+ BCM_LOG(DEBUG, log_id_group,
+ "Processing a group SET REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+ /*
+ * Find or create the specified group instance
+ */
+ p_group_inst = group_inst_get(p_group_key, GROUP_FLAG_ANY);
+ if(NULL == p_group_inst)
+ {
+ /* This is a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_group,
+ "ERROR - Group not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ /* If the state of this group is in flux, then reject the SET request */
+ if(BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_group_inst->current_group_info)))
+ {
+ ret = BCM_ERR_IN_PROGRESS;
+ break;
+ }
+
+ /* if needed, request/validate svc_port_id from resource manager - before validation */
+ if (BCMBAL_CFG_PROP_IS_SET(p_group_cfg, group, members_cmd) )
+ {
+ if(p_group_cfg->data.members_cmd == BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS)
+ {
+ /* if service id is not specified, filled in with current config info */
+ for(i=0; i<p_group_cfg->data.members.len; i++)
+ {
+ int req_intf = p_group_cfg->data.members.val[i].intf_id;
+ if(p_group_cfg->data.members.val[i].svc_port_id == 0)
+ {
+ for(j=0; j<p_group_inst->current_group_info.data.members.len; j++)
+ {
+ int cur_intf = p_group_inst->current_group_info.data.members.val[j].intf_id;
+ if( cur_intf == req_intf)
+ {
+ p_group_cfg->data.members.val[i].svc_port_id = p_group_inst->current_group_info.data.members.val[j].svc_port_id;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* if the group already has owner, alloc the svc_port for addition or replacement members */
+ if(BCMBAL_GROUP_OWNER_NONE != p_group_inst->current_group_info.data.owner )
+ {
+ /* copy the owner to the request */
+ BCMBAL_CFG_PROP_SET(p_group_cfg, group, owner, p_group_inst->current_group_info.data.owner);
+ /* allocate GEM */
+ for(i=0; i<p_group_cfg->data.members.len; i++)
+ {
+ if (BCMBAL_GROUP_OWNER_MULTICAST != p_group_inst->current_group_info.data.owner)
+ {
+ ret = rsc_mgr_gem_alloc_multicast(p_group_cfg->data.members.val[i].intf_id,
+ &p_group_cfg->data.members.val[i].svc_port_id,
+ 1, /* request gem range */
+ NULL);
+ }
+ else if (BCMBAL_GROUP_OWNER_UNICAST != p_group_inst->current_group_info.data.owner)
+ {
+ ret = rsc_mgr_gem_alloc_broadcast(p_group_cfg->data.members.val[i].intf_id,
+ &p_group_cfg->data.members.val[i].svc_port_id,
+ 1, /* request gem range */
+ NULL);
+ }
+ else
+ {
+ ret = BCM_ERR_PARM;
+ }
+ if(BCM_ERR_OK != ret)
+ {
+ break;
+ }
+ }
+ /* remember how many service port request been made to resource manager */
+ num_svc_port_allocated = i;
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " error encountered during allocate of group resources (intf_id:%d)\n",
+ p_group_cfg->data.members.val[i].intf_id);
+ break;
+ }
+ }
+
+ }
+ }
+
+ /*
+ * Fill in the local group info data structure
+ * Notice that any memory allocated in the request message will be free in
+ * process_mgmt_msg() of worker thread. If needed, GROUP FSM need to clone any
+ * request info into p_group_inst->current_group_info before return
+ */
+ p_group_inst->api_req_group_info = *p_group_cfg;
+
+ /*
+ * Process the request
+ */
+
+ /*
+ * Perform the validation check(s) that the utils require
+ */
+ if(BCM_ERR_OK != (ret = mac_util_group_info_validate(&p_group_inst->api_req_group_info)))
+ {
+ BCM_LOG(ERROR, log_id_group, "Failed GROUP mac validation\n");
+ break;
+ }
+
+ if(BCM_ERR_OK != (ret = sw_util_group_info_validate(&p_group_inst->api_req_group_info)))
+ {
+ BCM_LOG(ERROR, log_id_group, "Failed switch group validation\n");
+ break;
+ }
+
+ /* set the event based on request command */
+ b_generate_event = BCMOS_TRUE;
+ if ( BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_group_inst->api_req_group_info, group, members_cmd) )
+ {
+ switch(p_group_inst->api_req_group_info.data.members_cmd)
+ {
+ case BCMBAL_GROUP_MEMBER_CMD_ADD_MEMBERS:
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_ADD;
+ break;
+ case BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS:
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_REMOVE;
+ break;
+ case BCMBAL_GROUP_MEMBER_CMD_SET_MEMBERS:
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_SET;
+ break;
+ default:
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_NONE;
+ b_generate_event = BCMOS_FALSE;
+ break;
+ }
+ }
+ else
+ {
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_CREATE;
+ }
+
+ }while(0);
+
+ /* if anything go wrong, inform resource manager to free up the service port */
+ if (BCM_ERR_OK != ret &&
+ BCMBAL_CFG_PROP_IS_SET(p_group_cfg, group, members_cmd) &&
+ p_group_cfg->data.members_cmd != BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS)
+ {
+ for(i=0; i<num_svc_port_allocated; i++)
+ {
+ rsp_ret = rsc_mgr_gem_free(p_group_cfg->data.members.val[i].intf_id,
+ p_group_cfg->data.members.val[i].svc_port_id,
+ NULL);
+
+ /* best effort to free up */
+ if(BCM_ERR_OK != rsp_ret)
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " error encountered during allocate of group resources (intf_id:%d)\n",
+ p_group_cfg->data.members.val[i].intf_id);
+ }
+ }
+ }
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_group);
+
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
+ ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
+ break;
+ }
+
+ /* If there was an event generated, call the state machine exec */
+ if(BCMOS_TRUE == b_generate_event)
+ {
+ /*
+ * Run the group FSM to process this event
+ */
+ ret = group_fsm_exec(p_group_inst, &fsm_event);
+ }
+ break;
+ }
+
+ case (BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+
+ BCM_LOG(DEBUG, log_id_group, "Processing a group GET REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ }
+ else
+ {
+ /*
+ * Find the specified group instance
+ */
+ p_group_inst = group_inst_get(p_group_key, GROUP_FLAG_ACTIVE);
+ }
+
+ if(NULL == p_group_inst)
+ {
+ if(BCM_ERR_STATE != ret)
+ {
+ /* This is not a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_group, "ERROR - Specified group (%d) not found\n",
+ p_group_key->group_id);
+
+ ret = BCM_ERR_NOENT;
+ }
+
+ break;
+ }
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ p_group_inst->current_group_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_group_cfg *)msg_payload) = p_group_inst->current_group_info;
+
+ } while (0);
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_group);
+
+ }
+ break;
+
+ case (BCMBAL_OBJ_MSG_TYPE_CLEAR):
+ {
+ BCM_LOG(DEBUG, log_id_group, "Processing a group CLEAR REQ mgmt message\n");
+
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ /*
+ * Find the specified group instance
+ */
+ p_group_inst = group_inst_get(p_group_key, GROUP_FLAG_ACTIVE);
+
+ if(NULL == p_group_inst)
+ {
+ /* This is a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_group, "ERROR - Specified group (%d: not found\n",
+ p_group_key->group_id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ } while(0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_group);
+
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
+ ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
+ break;
+ }
+
+ /*
+ * Run the group FSM to process this event
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_DESTROY;
+
+ ret = group_fsm_exec(p_group_inst, &fsm_event);
+ }
+
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_group, "Unsupported operation on group object (%d)\n",
+ oper_type );
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_group);
+
+ break;
+ }
+ }
+
+ BCM_LOG(DEBUG, log_id_group, "%s returns\n", __FUNCTION__);
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to process a group object event received
+ * from one of the BAL apps.
+ *
+ * @param msg_payload A pointer to the util message
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_group_util_msg(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ group_inst *p_group_inst;
+ group_fsm_event fsm_event;
+ bcmbal_msg_type type;
+ bcmbal_group_key key;
+
+ type = bcmbal_type_minor_get(msg_payload);
+
+ BCM_LOG(DEBUG, log_id_group, "processing a group %s util message from %s\n",
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ /* recover the key from the message */
+ key = ((bal_util_msg_ind *)msg_payload)->obj_key.group_key;
+
+ do
+ {
+ BCM_LOG(DEBUG, log_id_group, "Got group key id (%d) from util message\n", key.group_id);
+
+ /*
+ * Get the group instance that's being referenced
+ */
+ if(NULL == (p_group_inst = group_inst_get(&key, GROUP_FLAG_ACTIVE)))
+ {
+ BCM_LOG(ERROR, log_id_group, "invalid group (%d) found while processing a util message from %s\n",
+ key.group_id,
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ ret = BCM_ERR_INTERNAL;
+
+ break;
+ }
+
+ /*
+ * Record the msg for further processing access
+ */
+ fsm_event.msg = msg_payload;
+
+ if (BAL_MSG_TYPE_IND == type)
+ {
+ fsm_event.event_type = GROUP_FSM_EVENT_TYPE_UTIL_MSG;
+ }
+ else
+ {
+ ret = BCM_ERR_NOT_SUPPORTED;
+ BCM_LOG(ERROR, log_id_group,
+ "Unknown message type received from the UTIL"
+ " (not IND) (type:%d)\n",
+ type);
+ break;
+ }
+
+ /*
+ * Run the Group FSM to process this event
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ ret = group_fsm_exec(p_group_inst, &fsm_event);
+ }
+ }
+ while(0);
+
+ return ret;
+}
+
+/*
+ * Helper functions
+ */
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a group instance of the specified
+ * class.
+ *
+ * @param key A pointer to the key of the group being
+ * referenced
+ * @param search_flag A flag specifying the type of group
+ * instance to be retrieved
+ *
+ * @returns group_inst_t* A pointer to the found group instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+static group_inst *group_inst_get(bcmbal_group_key *key, group_flag search_flag)
+{
+ group_inst *current_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ if(GROUP_FLAG_ACTIVE & search_flag)
+ {
+ TAILQ_FOREACH(current_entry,
+ &GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list,
+ group_inst_next)
+ {
+
+ if(current_entry->api_req_group_info.key.group_id == key->group_id)
+ {
+ BCM_LOG(DEBUG, log_id_group, "Found active group\n");
+ /* The group instance pointer is in current_entry */
+ break;
+ }
+ }
+ }
+
+ /*
+ * Next, check the free list if the caller has chosen to do so
+ */
+ if((GROUP_FLAG_FREE & search_flag) && (NULL == current_entry))
+ {
+ /* Now check the free list */
+ if(!TAILQ_EMPTY(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list))
+ {
+ /* Just grab the first entry */
+ current_entry = TAILQ_FIRST(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list);
+
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list, current_entry, group_inst_next);
+
+ /* And add it to the active list */
+ TAILQ_INSERT_TAIL(&GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list, current_entry, group_inst_next);
+
+ /*
+ * Initialize the fsm state
+ */
+ current_entry->fsm_state = GROUP_FSM_STATE_NULL;
+
+ BCM_LOG(DEBUG, log_id_group, "Using new group\n");
+
+ }
+ }
+
+ if((GROUP_FLAG_ANY & search_flag) && (NULL == current_entry))
+ {
+ /*A group was not found on either list*/
+
+ BCM_LOG(DEBUG, log_id_group, "************** ERROR: no group found\n");
+ }
+
+ return current_entry;
+}
+
+
+#ifdef GET_GROUP_CFG_BY_KEY_SUPPORTED
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve the current group info for the specified
+ * group instance.
+ *
+ * @param key A group key
+ *
+ * @returns bcmbal_group_cfg* A pointer to the current group info for the
+ * specified group, or NULL if the group is not found
+ *****************************************************************************/
+static bcmbal_group_cfg *group_get_current_info_by_key(bcmbal_group_key key)
+{
+ group_inst *current_entry = NULL;
+
+ /*
+ * Check the active list
+ */
+ TAILQ_FOREACH(current_entry,
+ &GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list,
+ group_inst_next)
+ {
+
+ if(current_entry->current_group_info.key.group_id == key.group_id)
+ {
+ /* The group instance pointer is in current_entry */
+ break;
+ }
+ }
+
+ if(current_entry)
+ {
+ return &(current_entry->current_group_info);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+#endif
+
+/*****************************************************************************/
+/**
+ * @brief A function to free a group instance specified by a the supplied
+ * entry pointer.
+ *
+ * @param p_entry A pointer to the entry to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno group_free_by_entry(group_inst *p_entry)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ group_inst *current_entry;
+ group_inst *p_temp_entry;
+
+ /*
+ * First, check the active list (an active group can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list,
+ group_inst_next,
+ p_temp_entry)
+ {
+ if(current_entry == p_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&GROUP_FSM_GROUP_LIST_CTX_PTR->active_group_list, current_entry, group_inst_next);
+ break;
+ }
+ }
+
+ /* And add it to the free list */
+ p_entry->fsm_state = GROUP_FSM_STATE_NULL;
+
+ /* And initialize the current object in the group instance */
+ group_inst_entry_obj_init(p_entry);
+
+ TAILQ_INSERT_TAIL(&GROUP_FSM_GROUP_LIST_CTX_PTR->free_group_list, p_entry, group_inst_next);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to remove group members specified in a requested group
+ * from a target group
+ *
+ * @param p_req_group A pointer to the group config that holds the members to be removed
+ * @param p_cur_group A pointer to the group config that holds the current members
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno bcmbal_group_object_member_remove(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group)
+{
+ int i, j, k, num_members, member_match;
+ bcmbal_group_member_info *p_new_member_info;
+ bcmbal_group_member_info_list_u16 new_members;
+
+ num_members = 0;
+ /* first calculate the final number of members */
+ for(i = 0; i < p_cur_group->data.members.len; i++)
+ {
+ member_match = 0;
+ /* check if it is in the remove list */
+ for(j = 0; j < p_req_group->data.members.len; j++)
+ {
+ if( p_cur_group->data.members.val[i].intf_id == p_req_group->data.members.val[j].intf_id)
+ {
+ member_match = 1;
+ break;
+ }
+ }
+ /* no match, we need to keep it */
+ if(!member_match)
+ {
+ num_members++;
+ }
+ }
+ /* if all requested members already been removed, no change, just return */
+ if( num_members == p_cur_group->data.members.len)
+ {
+ return BCM_ERR_OK;
+ }
+ /* if no member left, just clean up and leave */
+ if(num_members == 0)
+ {
+ bcmos_free(p_cur_group->data.members.val);
+ BCMBAL_CFG_PROP_CLEAR(p_cur_group, group, members);
+ return BCM_ERR_OK;
+ }
+
+ /* alloc memory for new list */
+ p_new_member_info = bcmos_calloc( num_members * sizeof(bcmbal_group_member_info));
+ if(p_new_member_info == NULL)
+ {
+ BCM_LOG(ERROR, log_id_group, "calloc failed when remove members from group object\n");
+ return BCM_ERR_NORES;
+ }
+
+ /* fill in the new list */
+ k=0;
+ for(i = 0; i < p_cur_group->data.members.len; i++)
+ {
+ member_match = 0;
+ /* check if it is in the remove list */
+ for(j = 0; j < p_req_group->data.members.len; j++)
+ {
+ if( p_cur_group->data.members.val[i].intf_id == p_req_group->data.members.val[j].intf_id)
+ {
+ member_match = 1;
+ break;
+ }
+ }
+ /* no match, we need to keep it */
+ if(!member_match)
+ {
+ p_new_member_info[k++] = p_cur_group->data.members.val[i];
+ }
+ }
+
+ /* free up the old list */
+ bcmos_free(p_cur_group->data.members.val);
+
+ /* assign new list */
+ new_members.val = p_new_member_info;
+ new_members.len = num_members;
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, members, new_members);
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to add group members specified in a requested group
+ * to a target group
+ *
+ * @param p_req_group A pointer to the group config that holds the members to be added
+ * @param p_cur_group A pointer to the group config that holds the current members
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno bcmbal_group_object_member_add(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group)
+{
+ int i, j, k, num_members, member_match;
+ bcmbal_group_member_info *p_new_member_info;
+ bcmbal_group_member_info_list_u16 new_members;
+
+ num_members = 0;
+ /* first calculate the final number of members */
+ for(i = 0; i < p_req_group->data.members.len; i++)
+ {
+ member_match = 0;
+ /* check if it is in the current list */
+ for(j = 0; j < p_cur_group->data.members.len; j++)
+ {
+ if( p_req_group->data.members.val[i].intf_id == p_cur_group->data.members.val[j].intf_id)
+ {
+ member_match = 1;
+ break;
+ }
+ }
+ /* no match, we need to add it */
+ if(!member_match)
+ {
+ num_members++;
+ }
+ }
+ /* if all requested members already in the list, no change, just return */
+ if( num_members == 0)
+ {
+ return BCM_ERR_OK;
+ }
+ /* alloc memory for new list */
+ p_new_member_info = bcmos_calloc( (num_members + p_cur_group->data.members.len) * sizeof(bcmbal_group_member_info) );
+ if(p_new_member_info == NULL)
+ {
+ BCM_LOG(ERROR, log_id_group, "calloc failed when add members to group object\n");
+ return BCM_ERR_NORES;
+ }
+
+ /* fill in the new list */
+ k=0;
+ for(j = 0; j < p_cur_group->data.members.len; j++)
+ {
+ p_new_member_info[k++] = p_cur_group->data.members.val[j];
+ }
+
+ for(i = 0; i < p_req_group->data.members.len; i++)
+ {
+ member_match = 0;
+ /* check if it is in the current list */
+ for(j = 0; j < p_cur_group->data.members.len; j++)
+ {
+ if( p_req_group->data.members.val[i].intf_id == p_cur_group->data.members.val[j].intf_id)
+ {
+ member_match = 1;
+ break;
+ }
+ }
+ /* no match, we need to add it */
+ if(!member_match)
+ {
+ p_new_member_info[k++] = p_req_group->data.members.val[i];
+ }
+ }
+
+ /* free up the old list */
+ bcmos_free(p_cur_group->data.members.val);
+
+ /* assign new list */
+ new_members.val = p_new_member_info;
+ new_members.len = k;
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, members, new_members);
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to replace group members specified in a targeted group
+ * with a requested group
+ *
+ * @param p_req_group A pointer to the group config that holds the members to be replaced
+ * @param p_cur_group A pointer to the group config that holds the current members
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno bcmbal_group_object_member_replace(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group)
+{
+ int j, k;
+ bcmbal_group_member_info *p_new_member_info;
+ bcmbal_group_member_info_list_u16 new_members;
+
+ /* alloc memory for new list */
+ p_new_member_info = bcmos_calloc( p_req_group->data.members.len * sizeof(bcmbal_group_member_info) );
+ if(p_new_member_info == NULL)
+ {
+ BCM_LOG(ERROR, log_id_group, "calloc failed when replace members to group object\n");
+ return BCM_ERR_NORES;
+ }
+
+ /* fill in the new list */
+ k=0;
+ for(j = 0; j < p_req_group->data.members.len; j++)
+ {
+ p_new_member_info[k++] = p_req_group->data.members.val[j];
+ }
+
+ /* free up the old list */
+ bcmos_free(p_cur_group->data.members.val);
+
+ /* assign new list */
+ new_members.val = p_new_member_info;
+ new_members.len = k;
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, members, new_members);
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to overlay group info specified in a requested group
+ * to a target group ( exclude the member info as it will be managed by
+ bcmbal_group_object_member_xxx functions)
+ *
+ * @param p_req_group A pointer to the requested group config
+ * @param p_cur_group A pointer to the group config that to be overlay
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno bcmbal_group_object_overlay(bcmbal_group_cfg *p_req_group,
+ bcmbal_group_cfg *p_cur_group)
+{
+ BUG_ON(NULL == p_cur_group);
+ BUG_ON(NULL == p_req_group);
+
+ bcmbal_presence_mask cur_presence_mask;
+
+ /* First, copy the common object and keys in their entirety, except for preserving the presence_mask */
+ cur_presence_mask = p_cur_group->hdr.hdr.presence_mask;
+ p_cur_group->hdr = p_req_group->hdr;
+ p_cur_group->key = p_req_group->key;
+ p_cur_group->hdr.hdr.presence_mask = cur_presence_mask;
+
+ /* Now copy only the fields that have been specified in the request object */
+ if(BCMBAL_CFG_PROP_IS_SET(p_req_group, group, members_cmd))
+ {
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, members_cmd, p_req_group->data.members_cmd);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(p_req_group, group, cookie))
+ {
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, cookie, p_req_group->data.cookie);
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(p_req_group, group, owner))
+ {
+ BCMBAL_CFG_PROP_SET(p_cur_group, group, owner, p_req_group->data.owner);
+ }
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to test if the specified group is active
+ *
+ * @param p_group_key A pointer to the group key to be tested
+ *
+ * @returns bcmos_bool BCMOS_TRUE if specified group is active
+ *****************************************************************************/
+bcmos_bool group_is_active(bcmbal_group_key *p_group_key)
+{
+ return (NULL == group_inst_get(p_group_key, GROUP_FLAG_ACTIVE)) ? BCMOS_FALSE : BCMOS_TRUE;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrive the group owner
+ *
+ * @param group_key the group key
+ * @param p_group_owner A pointer to store the retrieve owner
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno group_owner_get(bcmbal_group_key group_key, bcmbal_group_owner *p_group_owner)
+{
+ group_inst *p_group;
+
+ p_group = group_inst_get(&group_key, GROUP_FLAG_ACTIVE);
+ if (p_group)
+ {
+ *p_group_owner = p_group->current_group_info.data.owner;
+ return BCM_ERR_OK;
+ }
+ else
+ {
+ return BCM_ERR_NOENT;
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to set the group owner
+ * When the owner is set, the service port of the member is also allocated
+ *
+ * @param group_key group key
+ * @param grp_owner owner
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno group_owner_set(bcmbal_group_key group_key, bcmbal_group_owner grp_owner)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* if group has no owner, set the GROUP owner and allocate the GEM for each GROUP member
+
+ 1. flip the current info with request info
+ 2. allocate GEM for each group member
+ 3. Call switch_util to update the group (SET with new GEM info)
+ 4. Call mac_util to update the group (SET with new GEM info)
+ 5. flip back the current info
+ else
+ do nothing and let util validate the group owner
+ end-if
+ later, follow the regular FLOW fsm to SET FLOW in switch_util and Mac_util
+ */
+
+ group_inst *p_group;
+
+ p_group = group_inst_get(&group_key, GROUP_FLAG_ACTIVE);
+
+ if (p_group == NULL)
+ {
+ BCM_LOG(ERROR, log_id_group, "Failed to get group instance, group_id %d\n", group_key.group_id);
+ return BCM_ERR_INTERNAL;
+ }
+ if ( BCMBAL_GROUP_OWNER_NONE == p_group->current_group_info.data.owner)
+ {
+ int i;
+ bcmbal_group_cfg *p_group_req = &(p_group->api_req_group_info);
+ bcmbal_group_cfg *p_group_cur = &(p_group->current_group_info);
+
+ do
+ {
+ /* step 1 */
+ BCMBAL_CFG_PROP_SET(p_group_req, group, owner, grp_owner);
+ BCMBAL_CFG_PROP_SET(p_group_req, group, members_cmd, BAL_UTIL_OPER_GROUP_SET);
+ p_group_req->data.members.len = p_group_cur->data.members.len;
+ p_group_req->data.members.val = p_group_cur->data.members.val;
+
+ p_group_cur->data.members.len = 0;
+ p_group_cur->data.members.val = NULL;
+
+ /* step 2 */
+ for(i=0; i<p_group_req->data.members.len; i++)
+ {
+ if(grp_owner == BCMBAL_GROUP_OWNER_UNICAST )
+ {
+ ret = rsc_mgr_gem_alloc_broadcast(p_group_req->data.members.val[i].intf_id,
+ &p_group_req->data.members.val[i].svc_port_id,
+ 1, /* request gem range */
+ NULL);
+ }
+ else if (grp_owner == BCMBAL_GROUP_OWNER_MULTICAST)
+ {
+ ret = rsc_mgr_gem_alloc_multicast(p_group_req->data.members.val[i].intf_id,
+ &p_group_req->data.members.val[i].svc_port_id,
+ 1, /* request gem range */
+ NULL);
+ }
+ else
+ {
+ ret = BCM_ERR_PARM;
+ }
+ if(BCM_ERR_OK != ret)
+ {
+ break;
+ }
+ }
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_group, "Failed to alloc group GEM, interface=%d\n", p_group_req->data.members.val[i].intf_id);
+ break;
+ }
+ /* step 3 */
+ if(BCM_ERR_OK != (ret = sw_util_group_set(p_group, BAL_UTIL_OPER_GROUP_SET)))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error %s while updating group GEM in switch\n", bcmos_strerror(ret));
+ break;
+ }
+ /* step 4 - request no indicaiton send back */
+ if(BCM_ERR_OK != (ret = mac_util_group_set(p_group, BAL_UTIL_OPER_GROUP_SET, BCMOS_FALSE)))
+ {
+ BCM_LOG(ERROR, log_id_group,
+ "error %s while updating group GEM in mac \n", bcmos_strerror(ret));
+ break;
+ }
+ /* step 5 - flip back */
+ BCMBAL_CFG_PROP_SET(p_group_cur, group, owner, grp_owner);
+ BCMBAL_CFG_PROP_SET(p_group_cur, group, members_cmd, BAL_UTIL_OPER_GROUP_SET);
+ p_group_cur->data.members.len = p_group_req->data.members.len;
+ p_group_cur->data.members.val = p_group_req->data.members.val;
+
+ p_group_req->data.members.len = 0;
+ p_group_req->data.members.val = NULL;
+
+ }while(0);
+ }
+ else
+ {
+ /* if GROUP already has owner , make sure it is the same type */
+ if ( grp_owner != p_group->current_group_info.data.owner)
+ {
+ BCM_LOG(ERROR, log_id_group,
+ " group already has owner %d, can not reassign to %d \n", p_group->current_group_info.data.owner, grp_owner);
+ ret = BCM_ERR_INTERNAL;
+ }
+ }
+
+ return ret;
+}
+/*@}*/
diff --git a/bal_release/src/core/main/group_fsm.h b/bal_release/src/core/main/group_fsm.h
new file mode 100644
index 0000000..f7ebe57
--- /dev/null
+++ b/bal_release/src/core/main/group_fsm.h
@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file group_fsm.h
+ * @brief Code to support the BAL Group FSM
+ *
+ */
+
+#ifndef GROUP_FSM_H
+#define GROUP_FSM_H
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_api.h>
+
+/* set the total number of available group to 4k */
+#define GROUP_ALLOCATION_BLOCK_SIZE (4095)
+
+typedef enum
+{
+ GROUP_FSM_EVENT_TYPE_NONE = -1,
+ GROUP_FSM_EVENT_TYPE_CREATE ,
+ GROUP_FSM_EVENT_TYPE_DESTROY ,
+ GROUP_FSM_EVENT_TYPE_ADD ,
+ GROUP_FSM_EVENT_TYPE_REMOVE ,
+ GROUP_FSM_EVENT_TYPE_SET ,
+ GROUP_FSM_EVENT_TYPE_UTIL_MSG ,
+
+ GROUP_FSM_EVENT_TYPE__LAST,
+ GROUP_FSM_EVENT_TYPE__NUM_OF
+} group_fsm_event_type;
+
+
+
+typedef enum
+{
+ GROUP_FSM_STATE_NONE = -1,
+ GROUP_FSM_STATE_NULL ,
+ GROUP_FSM_STATE_CONFIGURING ,
+ GROUP_FSM_STATE_CONFIGURED ,
+ GROUP_FSM_STATE_DELETING ,
+
+ GROUP_FSM_STATE__LAST,
+ GROUP_FSM_STATE__NUM_OF
+} group_fsm_state;
+
+
+typedef enum
+{
+ GROUP_FLAG_ACTIVE = 1<<0, /**< A group is on the active list */
+ GROUP_FLAG_FREE = 1<<1, /**< A group is on the free list */
+ GROUP_FLAG_ANY = (GROUP_FLAG_ACTIVE | GROUP_FLAG_FREE), /**< A group is on either the active or free list */
+} group_flag;
+
+
+typedef struct group_fsm_event_t
+{
+ group_fsm_event_type event_type; /**< The group fsm events */
+ void *msg;
+
+ /* other necessary information */
+} group_fsm_event;
+
+
+typedef struct group_inst group_inst;
+struct group_inst
+{
+ bcmbal_group_cfg current_group_info; /**< The current information for this group (used for GET) */
+ bcmbal_group_cfg api_req_group_info; /**< The last group object info received from the Public API */
+ group_fsm_state fsm_state; /**< The group FSM state */
+ bcmos_timer timer_info; /**< A structure used for the state machine timeout timer */
+ TAILQ_ENTRY(group_inst) group_inst_next ; /**< TAILQ link */
+};
+
+
+/*
+ * Group FSM data structures
+ */
+typedef struct group_fsm_ctx
+{
+ /* Lists of free group entries and active group entries
+ */
+ TAILQ_HEAD(free_group_list_head, group_inst) free_group_list;
+
+ TAILQ_HEAD(active_group_list_head, group_inst) active_group_list;
+
+} group_fsm_ctx;
+
+
+/* Function declarations */
+
+extern bcmos_errno group_fsm_init(void);
+extern bcmos_errno group_fsm_finish(void);
+extern bcmos_errno process_group_util_msg(void *msg_payload);
+extern bcmos_errno process_group_object(void *msg_payload);
+extern bcmos_bool group_is_active(bcmbal_group_key *p_group_key);
+extern bcmos_errno group_owner_set(bcmbal_group_key group_key, bcmbal_group_owner group_owner);
+extern bcmos_errno group_owner_get(bcmbal_group_key group_key, bcmbal_group_owner *p_group_owner);
+
+/*@}*/
+
+#endif /*GROUP_FSM_H */
+
diff --git a/bal_release/src/core/main/sub_term_fsm.c b/bal_release/src/core/main/sub_term_fsm.c
new file mode 100644
index 0000000..c632a28
--- /dev/null
+++ b/bal_release/src/core/main/sub_term_fsm.c
@@ -0,0 +1,2182 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file sub_term_fsm.c
+ * @brief Code to support the BAL subscriber-terminal FSM
+ *
+ * @addtogroup sub_terminal
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include "sub_term_fsm.h"
+#include "tm_sched_fsm.h"
+
+#include <bal_objs.h>
+#include <fsm_common.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+/*
+ * @brief Logging device id for the subscriber-terminal
+ */
+static dev_log_id log_id_sub_term;
+#endif
+
+/* local function declarations */
+
+static bcmos_errno sub_term_fsm_admin_up_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_admin_up_error(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_admin_dn_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_admin_dn_ok(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_admin_dn_error(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_removing_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_ignore_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+
+static bcmos_errno sub_term_fsm_removing_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_removing_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_configuring_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_null_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_configured_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_configuring_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_state_err(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_fsm_exec(sub_term_inst *p_sub_term_inst, sub_term_fsm_event *p_event);
+
+static bcmos_errno sub_term_free_by_entry(sub_term_inst *p_entry);
+
+
+static bcmos_errno agg_port_id_list_fill(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id_list_u8 *agg_port_id_list);
+
+static bcmos_errno svc_port_id_list_fill(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id_list_u8 *svc_port_id_list);
+
+static bcmos_errno bcmbal_sub_term_tm_scheds_set(const bcmbal_subscriber_terminal_cfg *p_sub_term_cfg);
+
+/*
+ *@brief Global sub_term fsm context data structure
+ */
+static sub_term_fsm_ctx g_sub_term_fsm_sub_term_list_ctx;
+
+/*
+ * Macros for sub_term ctx access
+ */
+#define SUB_TERM_FSM_SUB_TERM_LIST_CTX (g_sub_term_fsm_sub_term_list_ctx)
+#define SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR (&g_sub_term_fsm_sub_term_list_ctx)
+
+/*
+ * @brief The definition of a sub_term state processing function
+ */
+typedef bcmos_errno (* sub_term_fsm_state_processor)(sub_term_inst *, void *, sub_term_fsm_event *);
+
+/*
+ * @brief The Subscriber Terminal FSM state processing array
+ */
+static sub_term_fsm_state_processor sub_term_states[SUB_TERM_FSM_STATE__NUM_OF][SUB_TERM_FSM_EVENT_TYPE__NUM_OF] =
+{
+
+ [SUB_TERM_FSM_STATE_NULL] =
+ {
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP] = sub_term_fsm_admin_up_start,
+
+ /*
+ * Next state: NULL
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN] = sub_term_fsm_admin_dn_ok,
+
+ /*
+ * Next state: NULL
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG] = sub_term_fsm_ignore_util_msg,
+
+ /*
+ * Next state: NULL
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = sub_term_fsm_null_process_util_auto_msg,
+ },
+
+ [SUB_TERM_FSM_STATE_CONFIGURING] =
+ {
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP] = sub_term_fsm_admin_up_error,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN] = sub_term_fsm_admin_dn_error,
+
+ /*
+ * Next state: REMOVING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_REMOVE] = sub_term_fsm_removing_start,
+
+ /*
+ * Next state: CONFIGURING | CONFIGURED
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG] = sub_term_fsm_configuring_process_util_msg,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = sub_term_fsm_configuring_process_util_auto_msg,
+
+ },
+
+ [SUB_TERM_FSM_STATE_CONFIGURED] =
+ {
+ /*
+ * Next state: CONFIGURED
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP] = sub_term_fsm_admin_up_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN] = sub_term_fsm_admin_dn_start,
+
+ /*
+ * Next state: REMOVING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_REMOVE] = sub_term_fsm_removing_start,
+
+ /*
+ * Next state: CONFIGURING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG] = sub_term_fsm_configured_process_util_msg,
+
+ /*
+ * Next state: CONFIGURED
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = sub_term_fsm_ignore_util_msg,
+
+ },
+
+ [SUB_TERM_FSM_STATE_REMOVING] =
+ {
+ /*
+ * Next state: REMOVING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP] = sub_term_fsm_admin_up_error,
+
+ /*
+ * Next state: REMOVING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN] = sub_term_fsm_admin_dn_error,
+
+ /*
+ * Next state: REMOVING | NULL
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG] = sub_term_fsm_removing_process_util_msg,
+
+ /*
+ * Next state: REMOVING
+ */
+ [SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = sub_term_fsm_removing_process_util_auto_msg,
+ },
+};
+
+static char *state_name_str[] =
+{
+ "SUB_TERM_FSM_STATE_NULL",
+ "SUB_TERM_FSM_STATE_CONFIGURING",
+ "SUB_TERM_FSM_STATE_CONFIGURED",
+ "SUB_TERM_FSM_STATE_REMOVING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (SUB_TERM_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), sub_term_fsm_state);
+
+static char *sub_term_state_name_get(sub_term_fsm_state state)
+{
+ if(state < SUB_TERM_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "SUB_TERM_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "SUB_TERM_FSM_ADMIN_UP_EVENT",
+ "SUB_TERM_FSM_ADMIN_DN_EVENT",
+ "SUB_TERM_FSM_REMOVE_EVENT",
+ "SUB_TERM_FSM_UTIL_MSG_EVENT",
+ "SUB_TERM_FSM_UTIL_AUTO_IND_EVENT",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT (SUB_TERM_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), sub_term_fsm_event_type);
+
+static char *sub_term_event_name_get(sub_term_fsm_event_type event)
+{
+ if(event < SUB_TERM_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "SUB_TERM_EVT_UNKNOWN";
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the current sub_term_info object of the
+ * supplied entry.
+ *
+ * @param p_entry A pointer to the entry to be initialized
+ *
+ *
+ * @returns void
+ *****************************************************************************/
+static void sub_term_inst_entry_obj_init(sub_term_inst *p_entry)
+{
+ bcmbal_subscriber_terminal_key key = { .sub_term_id = 0, .intf_id = 0 };
+ BCMBAL_CFG_INIT(&p_entry->current_sub_term_info,
+ subscriber_terminal,
+ key);
+
+ BCMBAL_CFG_PROP_SET(&p_entry->current_sub_term_info,
+ subscriber_terminal, admin_state, BCMBAL_STATE_DOWN);
+
+ BCMBAL_CFG_PROP_SET(&p_entry->current_sub_term_info,
+ subscriber_terminal, oper_status, BCMBAL_STATUS_NOT_PRESENT);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_sub_term_info), BCMOS_FALSE);
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function called to initialize the subscriber-terminal FSM
+ * infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns void
+ *****************************************************************************/
+bcmos_errno sub_term_fsm_init(void)
+{
+ int ii;
+ sub_term_inst *new_entry;
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ log_id_sub_term = bcm_dev_log_id_register("SUB_TERM", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_sub_term == DEV_LOG_INVALID_ID);
+#endif
+
+ /* Initialize all of the sub_term queues */
+ TAILQ_INIT(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list);
+ TAILQ_INIT(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list);
+
+ /* Populate the free list with it's set of sub_term instance entries */
+ for(ii=0; ii<NUM_SUPPORTED_SUB_TERMS; ii++)
+ {
+
+ new_entry = bcmos_calloc(sizeof(sub_term_inst));
+
+ if (NULL == new_entry)
+ {
+ BCM_LOG(FATAL, log_id_sub_term,
+ "Failed to initialize the sub_term free list - FATAL\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ /* And add it to the free list */
+ sub_term_free_by_entry(new_entry);
+
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to un-initialize the subscriber-terminal FSM infrastructure.
+ *
+ * NOTE: This is called once on shutdown and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno sub_term_fsm_finish(void)
+{
+
+ sub_term_inst *current_entry, *p_temp_entry;
+ agg_port_id_entry *agg_port_entry;
+ svc_port_id_entry *svc_port_entry;
+
+ /* Free all the entries on the active list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ sub_term_inst_next,
+ p_temp_entry)
+ {
+ /* free the aggregation port list */
+ TAILQ_FOREACH(agg_port_entry,
+ ¤t_entry->agg_port_id_list,
+ next)
+ {
+
+ bcmos_free(agg_port_entry);
+ }
+
+ /* free the service port list */
+ TAILQ_FOREACH(svc_port_entry,
+ ¤t_entry->svc_port_id_list,
+ next)
+ {
+ bcmos_free(svc_port_entry);
+ }
+
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ current_entry, sub_term_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ /* Free all the entries on the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list,
+ sub_term_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list,
+ current_entry, sub_term_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing executive function
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_exec(sub_term_inst *p_sub_term_inst, sub_term_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ sub_term_fsm_state pre_state;
+ sub_term_fsm_state fsm_state;
+ sub_term_fsm_state_processor sub_term_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state for debug printing
+ */
+ pre_state = (NULL == p_sub_term_inst) ? SUB_TERM_FSM_STATE_NULL : p_sub_term_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ sub_term_state_processor = sub_term_states[pre_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if (sub_term_state_processor)
+ {
+ ret = sub_term_state_processor(p_sub_term_inst, p_event->msg, p_event);
+ } else
+ {
+ sub_term_fsm_state_err(p_sub_term_inst, p_event->msg, p_event);
+ }
+
+ /* And get the new state for debug printing */
+ fsm_state = (NULL == p_sub_term_inst) ? SUB_TERM_FSM_STATE_NULL : p_sub_term_inst->fsm_state;
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "*** Event %s, State: %s --> %s\n",
+ sub_term_event_name_get(p_event->event_type),
+ sub_term_state_name_get(pre_state), sub_term_state_name_get(fsm_state));
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * subscriber-terminal object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_subscriber_terminal_object(void *msg_payload)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ bcmbal_subscriber_terminal_cfg *p_sub_term_cfg = (bcmbal_subscriber_terminal_cfg *)msg_payload;
+ sub_term_inst *p_sub_term_inst;
+ sub_term_fsm_event fsm_event;
+ bcmbal_subscriber_terminal_key *sub_term_key;
+ bcmbal_obj_msg_type oper_type;
+
+ /* Parameter checks */
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_sub_term, "Processing a sub_term object\n");
+
+ sub_term_key = &p_sub_term_cfg->key;
+
+ oper_type = p_sub_term_cfg->hdr.hdr.type;
+
+ /*
+ * A message pointer may be passed inside the event structure.
+ */
+ fsm_event.msg = msg_payload;
+
+ /* SET or GET or CLEAR ? */
+ switch (oper_type)
+ {
+ case (BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ bcmos_bool b_generate_event = BCMOS_FALSE;
+
+ BCM_LOG(DEBUG, log_id_sub_term, "Processing a sub_term SET REQ mgmt message\n");
+
+ /*
+ * Find or create the specified sub_term instance
+ */
+ p_sub_term_inst = sub_term_inst_get(sub_term_key, SUB_TERM_FLAG_ANY);
+
+ do
+ {
+
+ if(NULL == p_sub_term_inst)
+ {
+ /* This is a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Specified sub_term not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ /* If the state of this sub_term is in flux, then reject the SET request */
+ if(BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_sub_term_inst->current_sub_term_info)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "The subscriber_terminal is in-progress, SETs are not allowed\n");
+ ret = BCM_ERR_IN_PROGRESS;
+ break;
+ }
+
+ if(BCM_ERR_OK != (ret = bcmbal_sub_term_tm_scheds_set(p_sub_term_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "could not set subscriber terminal as owner of specified tm scheds\n");
+ ret = BCM_ERR_PARM;
+
+ }
+
+ /*
+ * Fill in the local sub_term instance API request data structure
+ */
+ p_sub_term_inst->api_req_sub_term_info = *p_sub_term_cfg;
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "sub_term admin state is: %s\n",
+ (BCMBAL_STATE_UP == p_sub_term_inst->api_req_sub_term_info.data.admin_state) ? "UP" : "DOWN");
+
+
+ /* If there's no state change, then we're done */
+ if(p_sub_term_inst->current_sub_term_info.data.admin_state ==
+ p_sub_term_inst->api_req_sub_term_info.data.admin_state)
+ {
+ break;
+ }
+
+ /* For subscriber terminals that have already been configured and then made dormant, merge the
+ * requested data with the current data, and this is the new request.
+ */
+ if(BCMBAL_STATUS_DOWN == p_sub_term_inst->current_sub_term_info.data.oper_status)
+ {
+
+ bcmbal_sub_term_object_overlay_w_dst_priority(&p_sub_term_inst->api_req_sub_term_info,
+ &p_sub_term_inst->current_sub_term_info);
+ }
+
+ /*
+ * Check if the mandatory subscriber terminal attributes have been set, and range check where
+ * applicable.
+ */
+
+
+ /* The admin state attribute is mandatory */
+ if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(&p_sub_term_inst->api_req_sub_term_info,
+ subscriber_terminal,
+ admin_state))
+ {
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+
+ /*
+ * Perform the validation check(s) that the utils require
+ */
+ if(BCM_ERR_OK !=
+ (ret = mac_util_subscriber_terminal_info_validate(&p_sub_term_inst->api_req_sub_term_info)))
+ {
+ break;
+ }
+
+ }
+ while(0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_sub_term);
+
+ if(BCM_ERR_OK != ret)
+ {
+ break;
+ }
+
+ /*
+ * Initial checks complete. Process the request
+ */
+
+ if((BCMBAL_STATE_UP == p_sub_term_inst->api_req_sub_term_info.data.admin_state)
+ && (BCMBAL_STATE_UP != p_sub_term_inst->current_sub_term_info.data.admin_state))
+ {
+ BCMBAL_CFG_PROP_SET(&p_sub_term_inst->api_req_sub_term_info,
+ subscriber_terminal,
+ svc_port_id,
+ sub_term_key->sub_term_id);
+
+ p_sub_term_inst->api_req_sub_term_info.data.admin_state = BCMBAL_STATE_UP;
+
+ /* Set the expected state of the oper_status upon success */
+ p_sub_term_inst->api_req_sub_term_info.data.oper_status = BCMBAL_STATUS_UP;
+
+ fsm_event.event_type = SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP;
+ b_generate_event = BCMOS_TRUE;
+
+ BCM_LOG(INFO, log_id_sub_term,
+ "***Using GEM %d for subscriber terminal OMCI channel\n",
+ p_sub_term_inst->api_req_sub_term_info.data.svc_port_id);
+
+ }
+ else if((BCMBAL_STATE_DOWN == p_sub_term_inst->api_req_sub_term_info.data.admin_state)
+ && (BCMBAL_STATE_DOWN != p_sub_term_inst->current_sub_term_info.data.admin_state))
+ {
+ p_sub_term_inst->current_sub_term_info.data.admin_state = BCMBAL_STATE_DOWN;
+
+ /* Set the expected state of the oper_status upon success */
+ p_sub_term_inst->api_req_sub_term_info.data.oper_status = BCMBAL_STATUS_DOWN;
+
+ fsm_event.event_type = SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN;
+ b_generate_event = BCMOS_TRUE;
+ }
+ else
+ {
+ /* @todo implement a MODIFY here */
+ BCM_LOG(INFO, log_id_sub_term, "no state change...done\n");
+ break; /* no state change detected - do nothing for now */
+ }
+
+ /* If there was an event generated, call the state machine exec */
+ if(BCMOS_TRUE == b_generate_event)
+ {
+ /*
+ * Run the sub_term FSM to process this event
+ */
+ ret = sub_term_fsm_exec(p_sub_term_inst, &fsm_event);
+ }
+ break;
+ }
+
+ case (BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+
+ bcmbal_aggregation_port_id_list_u8 agg_port_id_list = {};
+ bcmbal_service_port_id_list_u8 svc_port_id_list = {};
+
+ BCM_LOG(DEBUG, log_id_sub_term, "Processing a sub_term GET REQ mgmt message\n");
+
+ /*
+ * Just return the sub_term data info that we have on record for
+ * this sub_term instance
+ */
+
+ /*
+ * Find the specified sub_term instance
+ */
+ p_sub_term_inst = sub_term_inst_get(sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if(NULL == p_sub_term_inst)
+ {
+ /* This is not a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_sub_term, "Specified sub_term not found on GET\n");
+ ret = BCM_ERR_NOENT;
+ }
+ else
+ {
+ do
+ {
+ /* Return the agg_port_id list if requested */
+ BCMBAL_CFG_PROP_CLEAR(&p_sub_term_inst->current_sub_term_info,
+ subscriber_terminal,
+ agg_port_id_list);
+
+
+ /* If the user requested the list of agg_port_ids for this subscriber terminal
+ * then return the list.
+ */
+ if(BCMBAL_CFG_PROP_IS_SET(p_sub_term_cfg,
+ subscriber_terminal,
+ agg_port_id_list))
+ {
+
+ if(BCM_ERR_OK == agg_port_id_list_fill(p_sub_term_inst, &agg_port_id_list))
+ {
+ /* NOTE: The returned list may be empty */
+ BCMBAL_CFG_PROP_SET(&p_sub_term_inst->current_sub_term_info,
+ subscriber_terminal,
+ agg_port_id_list,
+ agg_port_id_list);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sub_term, "Error trying to fill agg_port list to return\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+
+ }
+ }
+
+ /* Return the svc_port_id list if requested */
+ BCMBAL_CFG_PROP_CLEAR(&p_sub_term_inst->current_sub_term_info,
+ subscriber_terminal,
+ svc_port_id_list);
+
+ /* If the user requested the list of sub_term_ids for this subscriber terminal,
+ * then return the list.
+ */
+ if(BCMBAL_CFG_PROP_IS_SET(p_sub_term_cfg,
+ subscriber_terminal,
+ svc_port_id_list))
+ {
+
+ if(BCM_ERR_OK == svc_port_id_list_fill(p_sub_term_inst, &svc_port_id_list))
+ {
+ /* NOTE: The returned list may be empty */
+ BCMBAL_CFG_PROP_SET(&p_sub_term_inst->current_sub_term_info,
+ subscriber_terminal,
+ svc_port_id_list,
+ svc_port_id_list);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sub_term, "Error trying to fill svc_port list to return\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+
+ }
+ }
+ }while (0);
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+
+ p_sub_term_inst->current_sub_term_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_subscriber_terminal_cfg *)msg_payload) = p_sub_term_inst->current_sub_term_info;
+ }
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_sub_term);
+
+ /* Free the temporary lists if they were used */
+ if(svc_port_id_list.val)
+ {
+ bcmos_free(svc_port_id_list.val);
+ }
+
+ if(agg_port_id_list.val)
+ {
+ bcmos_free(agg_port_id_list.val);
+ }
+
+ break;
+ }
+
+ case (BCMBAL_OBJ_MSG_TYPE_CLEAR):
+ {
+ /*
+ * Find the specified sub_term instance
+ */
+ p_sub_term_inst = sub_term_inst_get(sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if(NULL == p_sub_term_inst)
+ {
+ /* This is not a fatal error condition
+ */
+ BCM_LOG(ERROR, log_id_sub_term, "Specified sub_term not found on CLEAR\n");
+ ret = BCM_ERR_NOENT;
+ }
+ else
+ {
+ /*
+ * Fill in the local sub_term instance API request data structure
+ */
+ p_sub_term_inst->api_req_sub_term_info = *p_sub_term_cfg;
+ }
+
+ /* We respond to the BAL public API backend with a result.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_sub_term);
+
+ if(BCM_ERR_OK == ret)
+ {
+ fsm_event.event_type = SUB_TERM_FSM_EVENT_TYPE_REMOVE;
+
+ /* Run the sub_term FSM to process this event */
+ ret = sub_term_fsm_exec(p_sub_term_inst, &fsm_event);
+ }
+
+ break;
+ }
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Unsupported operation on sub_term object (%d)\n",
+ bcmbal_msg_id_oper_get(msg_payload) );
+
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_sub_term);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+bcmos_errno process_subscriber_terminal_util_msg(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ sub_term_inst *p_sub_term_inst = NULL;
+ bcmbal_msg_type type;
+ sub_term_fsm_event sub_term_event;
+ bcmbal_subscriber_terminal_key key;
+
+ BUG_ON(NULL == msg_payload);
+
+ type = bcmbal_type_minor_get(msg_payload);
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "Processing a sub_term %s util message from %s\n",
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ /* recover the key from the message */
+ key = ((bal_util_msg_ind *)msg_payload)->obj_key.sub_term_key;
+
+ do
+ {
+ BCM_LOG(DEBUG, log_id_sub_term, "Got sub_term key id from util (ID%d, PON %d)\n",
+ key.sub_term_id, key.intf_id);
+
+ /* Don't bother to look up the sub_term instance for DISCOVERY messages from the
+ * mac util where the sub_term_id is unknown. This is a new ONU, so it will not
+ * be found in the ACTIVE table.
+ */
+ if((BAL_MSG_TYPE_AUTO_IND != (bcmbal_msg_type)type) ||
+ (BAL_MSG_TYPE_AUTO_IND == (bcmbal_msg_type)type && BCMBAL_SUB_ID_UNKNOWN != key.sub_term_id))
+ {
+ /*
+ * Get the sub_term instance that's being referenced
+ */
+ p_sub_term_inst = sub_term_inst_get(&key, SUB_TERM_FLAG_ACTIVE);
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "invalid sub_term (ID%d, PON%d) found while processing a util message type %s from %s\n",
+ key.sub_term_id,
+ key.intf_id,
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ ret = BCM_ERR_INTERNAL;
+
+ break;
+ }
+ }
+
+ /*
+ * Record the msg for further processing access
+ */
+ sub_term_event.msg = msg_payload;
+
+ if (BAL_MSG_TYPE_IND == type)
+ {
+ sub_term_event.event_type = SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG;
+ }
+ else if (BAL_MSG_TYPE_AUTO_IND == type)
+ {
+ sub_term_event.event_type = SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG;
+ }
+ else
+ {
+ ret = BCM_ERR_NOT_SUPPORTED;
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Unknown message type received from the APP (not one of RSP:ACK:IND:AUTO_IND) (type:%d)\n",
+ type);
+ }
+
+ if (p_sub_term_inst)
+ {
+ BCM_LOG(DEBUG, log_id_sub_term, "p_sub_term_inst->fsm_state=%d , sub_term_event.event_type = %d\n",
+ p_sub_term_inst->fsm_state, sub_term_event.event_type);
+ }
+ else
+ {
+ if (BAL_MSG_TYPE_IND == type)
+ {
+ BCM_LOG(WARNING, log_id_sub_term, "p_sub_term_inst is NULL\n");
+ }
+ }
+ /*
+ * Run the Sub_Term FSM to process this event
+ */
+ if(BCM_ERR_OK == ret)
+ {
+ ret = sub_term_fsm_exec(p_sub_term_inst, &sub_term_event);
+ }
+ }
+ while(0);
+
+ return ret;
+}
+
+/************************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing for a subscriber-terminal
+ * admin-up command received from the BAL Public API when the specified
+ * subscriber-terminal instance is in the admin-down state (i.e. when
+ * the subscriber-terminal instance FSM is in the NULL or REMOVED state).
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ ***********************************************************************************/
+static bcmos_errno sub_term_fsm_admin_up_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_sub_term,
+ "Received a admin UP request from BAL API - bringing up SUB_TERM\n");
+
+ /* change subscriber terminal state to CONFIGURING */
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Mac Utils to set the subscriber-terminal parameters using the applicable SDK calls */
+ ret = mac_util_subscriber_terminal_set(p_sub_term_inst, BAL_UTIL_OPER_SUB_TERM_ADD, BCMOS_FALSE);
+
+ do
+ {
+
+ /* check for object in wrong state, this is not an actual error */
+ if(BCM_ERR_STATE == ret)
+ {
+ BCM_LOG(INFO, log_id_sub_term,
+ "mac_util_subscriber_terminal_set() subscriber_terminal could not be activated at this time\n");
+
+ }
+ /* check for errors */
+ else if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Error detected in mac_util_subscriber_terminal_set(): %s\n",
+ bcmos_strerror(ret));
+ break;
+
+ }
+
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state, except for the oper_status.
+ */
+ bcmbal_sub_term_object_overlay_w_src_priority(&p_sub_term_inst->current_sub_term_info,
+ &p_sub_term_inst->api_req_sub_term_info);
+
+ /* Add this subscriber_terminal to the list of subscriber_terminals associated with it's interface */
+ bcmbal_interface_sub_term_list_entry_add(p_sub_term_inst->current_sub_term_info.key);
+
+ /* Record that this object is in progress */
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_sub_term_inst->current_sub_term_info), BCMOS_TRUE);
+
+ } while(0);
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_sub_term);
+ }
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The subscriber terminal FSM state processing for a subscriber terminal
+ * admin-up command received from the BAL Public API when the specified
+ * subscriber terminal FSM is already in the REMOVING state.
+ *
+ * @param p_sub_term_inst Pointer to a subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_admin_up_error(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_STATE;
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "Received a admin UP request from BAL API - returning ERROR to the API"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing for an subscriber-terminal
+ * admin-down command received from the BAL Public API when the specified
+ * subscriber-terminal is admin-up (i.e when the specified subscriber-terminal
+ * instance FSM is in the CONFIGURED state).
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_admin_dn_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_sub_term,
+ "Received a admin DOWN request from BAL API - bringing down SUB_TERM\n");
+
+ /* change subscriber terminal state to CONFIGURING */
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_CONFIGURING;
+
+ /*– Core calls Mac Utils to set the subscriber-terminal parameters using the applicable SDK calls */
+ ret = mac_util_subscriber_terminal_set(p_sub_term_inst, BAL_UTIL_OPER_SUB_TERM_REMOVE, BCMOS_FALSE);
+
+ /* check for errors */
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Error detected in mac_util_subscriber_terminal_set(): %s\n",
+ bcmos_strerror(ret));
+
+ /* report the status to the API */
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_sub_term);
+
+
+ }
+ else
+ {
+ /* NOTE: The hardware has properly accepted the object info but we do
+ * not overwrite the current subscriber terminal data as there is nothing in the request
+ * that is relevant besides the admin_state. We merely set the object to in_progress.
+ */
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_sub_term_inst->current_sub_term_info), BCMOS_TRUE);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing for an subscriber-terminal
+ * clear command received from the BAL Public API
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_removing_start(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_sub_term,
+ "Received a REMOVE request from BAL API - removing SUB_TERM\n");
+
+ /* change subscriber terminal state to REMOVING */
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_REMOVING;
+
+ /*– Core calls Mac Utils to set the subscriber-terminal parameters using the applicable SDK calls */
+ ret = mac_util_subscriber_terminal_set(p_sub_term_inst, BAL_UTIL_OPER_SUB_TERM_CLEAR, BCMOS_FALSE);
+
+ /* check for errors */
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Error detected in mac_util_subscriber_terminal_set(): %s\n",
+ bcmos_strerror(ret));
+
+ /* report the error to the API */
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_sub_term);
+ }
+ else
+ {
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state, except for the oper_status.
+ */
+ bcmbal_sub_term_object_overlay_w_src_priority(&p_sub_term_inst->current_sub_term_info,
+ &p_sub_term_inst->api_req_sub_term_info);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_sub_term_inst->current_sub_term_info), BCMOS_TRUE);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing for subscriber-terminal
+ * admin-down command from the BAL Public API when the specified
+ * subscriber-terminal is already admin-down.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_admin_dn_ok(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "Received a admin DOWN request from BAL API - returning OK to the API"
+ " - no further function\n");
+
+ mgmt_msg_send_balapi_ind(ret,
+ msg,
+ log_id_sub_term);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The subscriber terminal FSM state processing for a subscriber terminal
+ * admin-down command received from the BAL Public API when the specified
+ * subscriber terminal FSM is already in the REMOVING state.
+ *
+ * @param p_sub_term_inst Pointer to a subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_admin_dn_error(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_STATE;
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "Received a admin DOWN request from BAL API - returning ERROR to the API"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to ignore a
+ * received message.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_ignore_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_sub_term, "Ignoring message from BAL utils\n");
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process an
+ * AUTO IND message from one of the BAL apps while in the NULL state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_null_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_subscriber_terminal_cfg subscriber_terminal_obj;
+ bcmbal_serial_number serial = {};
+ bal_util_msg_ind *ind_msg;
+
+ /* Process checks */
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ BCM_LOG(DEBUG, log_id_sub_term, "Received a AUTO IND in the null state\n");
+
+ /*
+ * Set the key in the subscriber_terminal object
+ */
+ BCMBAL_CFG_INIT(&subscriber_terminal_obj, subscriber_terminal, ind_msg->obj_key.sub_term_key);
+
+ /*
+ * Set the serial number in the subscriber_terminal object
+ */
+ memcpy(&serial, ind_msg->data, sizeof(bcmbal_serial_number));
+ BCMBAL_CFG_PROP_SET(&subscriber_terminal_obj, subscriber_terminal, serial_number, serial);
+
+ /* And mark it's status as DOWN */
+ BCMBAL_CFG_PROP_SET(&subscriber_terminal_obj, subscriber_terminal, oper_status, BCMBAL_STATUS_DOWN);
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&subscriber_terminal_obj.hdr,
+ log_id_sub_term);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process an
+ * AUTO IND message from one of the BAL apps while in the CONFIGURING state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_configuring_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_sub_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ " Received a IND message from BAL UTIL (%s) during CONFIGURING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ /* Handle response */
+ ret = ind_msg->status;
+
+ if(BCM_ERR_OK == ret)
+ {
+
+ /* If this indication is for a subscriber terminal that has been ADDED and is ADMIN_UP,
+ * OR for a subscriber terminal that has been REMOVED and is ADMIN_DOWN
+ * then complete the state transition.
+ */
+
+ if((BAL_UTIL_OPER_SUB_TERM_ADD == bcmbal_msg_id_oper_get(msg) &&
+ BCMBAL_STATE_UP == p_sub_term_inst->current_sub_term_info.data.admin_state) ||
+ (BAL_UTIL_OPER_SUB_TERM_REMOVE == bcmbal_msg_id_oper_get(msg) &&
+ BCMBAL_STATE_DOWN == p_sub_term_inst->current_sub_term_info.data.admin_state))
+ {
+
+ if (bcm_topo_pon_get_pon_family(p_sub_term_inst->current_sub_term_info.key.intf_id) == BCM_TOPO_PON_FAMILY_EPON)
+ {
+ uint16_t tunnel_id;
+
+ /* Recover the tunnel_id from the indication message */
+ memcpy(&tunnel_id, ind_msg->data, sizeof(tunnel_id));
+
+ /* And store it in the sub_term instance, to be used by the switch */
+ p_sub_term_inst->current_sub_term_info.data.svc_port_id = tunnel_id;
+ }
+
+ p_sub_term_inst->current_sub_term_info.data.oper_status =
+ p_sub_term_inst->api_req_sub_term_info.data.oper_status;
+
+ /*
+ * The subscriber terminal has been successfully configured
+ */
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_CONFIGURED;
+
+ }
+
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Failed in state %s;%s\n",
+ sub_term_state_name_get(p_sub_term_inst->fsm_state),
+ bcmos_strerror(ret));
+ }
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_sub_term_inst->current_sub_term_info), BCMOS_FALSE);
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&p_sub_term_inst->current_sub_term_info.hdr,
+ log_id_sub_term);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process an
+ * IND message from one of the BAL apps while in the CONFIGURED state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_configured_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Process checks */
+ BUG_ON(NULL == p_sub_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ " Received a IND message from BAL UTIL (%s) during CONFIGURED state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ if((BAL_UTIL_OPER_SUB_TERM_REMOVE != bcmbal_msg_id_oper_get(msg)) &&
+ (BAL_UTIL_OPER_SUB_TERM_CLEAR != bcmbal_msg_id_oper_get(msg)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Received an unrecognized IND (%u) received in the configured state"
+ "- no further function\n", bcmbal_msg_id_oper_get(msg));
+ }
+ else
+ {
+
+
+ /* change subscriber terminal state to CONFIGURING */
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_CONFIGURING;
+
+ /* Set the oper_status upon success */
+ p_sub_term_inst->current_sub_term_info.data.oper_status = BCMBAL_STATUS_NOT_PRESENT;
+
+ /*
+ * Send the indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_sub_term_inst->current_sub_term_info.hdr,
+ log_id_sub_term);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process an
+ * AUTO IND message from one of the BAL apps while in the CONFIGURED state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_configuring_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Process checks */
+ BUG_ON(NULL == p_sub_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ " Received a AUTO IND message from BAL UTIL (%s) during CONFIGURING state\n",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ if(BAL_UTIL_OPER_SUB_TERM_DISCOVERY != bcmbal_msg_id_oper_get(msg))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Received an unrecognized AUTO IND in the configuring state"
+ "- no further function\n");
+ }
+ else
+ {
+ /*– Core calls Mac Utils to set the subscriber-terminal parameters using the applicable SDK calls */
+ /* send TRUE in last argument to indicate the request is after a ONU Discovery */
+ ret = mac_util_subscriber_terminal_set(p_sub_term_inst, BAL_UTIL_OPER_SUB_TERM_ADD, BCMOS_TRUE);
+ }
+
+ /* If there were errors during processing, then report the error to the API */
+ if(BCM_ERR_OK != ret)
+ {
+
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&p_sub_term_inst->current_sub_term_info.hdr,
+ log_id_sub_term);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process a
+ * message from one of the BAL apps while in the REMOVING state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_removing_process_util_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_sub_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ /*
+ * NOTE: AUTO_IND messages are not processed in this function,
+ * so there is no need to consider them in this logic.
+ */
+
+ /* Handle indication */
+ ret = ind_msg->status;
+
+ BCM_LOG(INFO, log_id_sub_term,
+ "Received a %s message from BAL APP (%s) during REMOVING state\n",
+ (BAL_MSG_TYPE_IND == bcmbal_type_minor_get(msg)) ? "IND" : "RSP",
+ subsystem_str[bcmbal_sender_get(msg)]);
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* Set the admin_state and oper_status to be DOWN and NOT_PRESENT respectively,
+ * since we are clearing this object anyway. These parameters are set in the free function,
+ * but they need to be set here for the indication below to be correct */
+ p_sub_term_inst->current_sub_term_info.data.admin_state = BCMBAL_STATE_DOWN;
+ p_sub_term_inst->current_sub_term_info.data.oper_status = BCMBAL_STATUS_NOT_PRESENT;
+ }
+
+ if(BCM_ERR_OK == ret)
+ {
+
+ /* Remove this subscriber_terminal from the list of subscriber_terminals associated with it's interface */
+ bcmbal_interface_sub_term_list_entry_remove(p_sub_term_inst->current_sub_term_info.key);
+
+ /*
+ * Send the success indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_sub_term_inst->current_sub_term_info.hdr,
+ log_id_sub_term);
+
+ /* Return the subscriber terminal to the free pool */
+ sub_term_free_by_entry(p_sub_term_inst);
+
+ BCM_LOG(DEBUG, log_id_sub_term, "sub term freed\n");
+
+ }
+ else
+ {
+ p_sub_term_inst->fsm_state = SUB_TERM_FSM_STATE_CONFIGURED;
+
+ /*
+ * Send the failure indication back to the BAL public API here
+ */
+ mgmt_msg_send_balapi_ind(ret,
+ &p_sub_term_inst->current_sub_term_info.hdr,
+ log_id_sub_term);
+
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Error encountered in REMOVING state (status is %s)\n",
+ bcmos_strerror(ret));
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM state processing function to process an
+ * AUTO IND message from one of the BAL apps while in the REMOVING state.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_removing_process_util_auto_msg(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_sub_term_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ BCM_LOG(DEBUG, log_id_sub_term,
+ "Received a AUTO IND in the removing state"
+ " - no further function\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Subscriber terminal FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_sub_term_inst Pointer to an subscriber terminal instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps
+ * @param p_event Pointer to an subscriber terminal event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_fsm_state_err(sub_term_inst *p_sub_term_inst,
+ void *msg,
+ sub_term_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(ERROR, log_id_sub_term,
+ "Error encountered processing SUB_TERM FSM - BAD EVENT ()\n");
+
+ return ret;
+}
+
+
+/*
+ * Helper functions
+ */
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a subscriber-terminal instance of the specified
+ * class.
+ *
+ * @param key A pointer to the key of the subscriber-terminal being
+ * referenced
+ * @param search_flag A flag specifying the type of subscriber-terminal
+ * instance to be retrieved
+ *
+ * @returns sub_term_inst_t* A pointer to the found subscriber-terminal instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+sub_term_inst *sub_term_inst_get(bcmbal_subscriber_terminal_key *key,
+ sub_term_flag search_flag)
+{
+ sub_term_inst *current_entry = NULL;
+ sub_term_inst *p_temp_entry;
+
+ /*
+ * First, check the active list
+ */
+ TAILQ_FOREACH(current_entry,
+ &SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ sub_term_inst_next)
+ {
+ if((current_entry->api_req_sub_term_info.key.sub_term_id == key->sub_term_id) &&
+ (current_entry->api_req_sub_term_info.key.intf_id == key->intf_id))
+ {
+ /* The sub_term instance pointer is in current_entry */
+ break;
+ }
+ }
+
+
+ if((SUB_TERM_FLAG_ANY == search_flag) && (NULL == current_entry))
+ {
+ /* Now check the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list,
+ sub_term_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list,
+ current_entry, sub_term_inst_next);
+
+ /* And add it to the active list */
+ TAILQ_INSERT_TAIL(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ current_entry, sub_term_inst_next);
+
+ /*
+ * Initialize the sub_term data
+ */
+ current_entry->fsm_state = SUB_TERM_FSM_STATE_NULL;
+
+ break;
+ }
+ }
+
+ if(NULL == current_entry)
+ {
+ /*
+ * A sub_term was not found on either list*/
+
+ BCM_LOG(DEBUG, log_id_sub_term, "no sub_term found\n");
+ }
+
+ return current_entry;
+}
+
+bcmos_errno sub_term_svc_port_id_get(bcmbal_sub_id sub_term_id,
+ uint16_t access_int_id,
+ bcmbal_service_port_id *p_svc_port_id)
+{
+ sub_term_inst *p_sub_term_inst;
+ bcmbal_subscriber_terminal_key sub_term_key;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BUG_ON(NULL == p_svc_port_id);
+
+ /* Create the key to find the subscriber terminal instance being referenced */
+ sub_term_key.sub_term_id = sub_term_id;
+ sub_term_key.intf_id = access_int_id;
+
+ if(NULL == (p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term, "Specified sub_term (sub:%d on int:%d) not found\n",
+ sub_term_id, access_int_id);
+ ret = BCM_ERR_NOENT;
+ }
+ else
+ {
+ *p_svc_port_id = p_sub_term_inst->current_sub_term_info.data.svc_port_id;
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to free a subscriber terminal instance specified
+ * by a the supplied entry pointer.
+ *
+ * @param p_entry A pointer to the entry to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno sub_term_free_by_entry(sub_term_inst *p_entry)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ sub_term_inst *current_entry;
+ sub_term_inst *p_temp_entry;
+
+ BUG_ON(NULL == p_entry);
+
+ /*
+ * First, check the active list (an active sub_term can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ sub_term_inst_next,
+ p_temp_entry)
+ {
+ if(current_entry == p_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->active_sub_term_list,
+ current_entry, sub_term_inst_next);
+ }
+ }
+
+ /* Initialize the svc_port_id and agg_port_id lists */
+ p_entry->num_svc_port_ids = 0;
+ TAILQ_INIT(&p_entry->svc_port_id_list);
+
+ p_entry->num_agg_port_ids = 0;
+ TAILQ_INIT(&p_entry->agg_port_id_list);
+
+ /* And add the entry to the free list */
+ p_entry->fsm_state = SUB_TERM_FSM_STATE_NULL;
+
+ /* And initialize the current object in the sub_term instance */
+ sub_term_inst_entry_obj_init(p_entry);
+
+ TAILQ_INSERT_TAIL(&SUB_TERM_FSM_SUB_TERM_LIST_CTX_PTR->free_sub_term_list,
+ p_entry, sub_term_inst_next);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_sub_term_svc_port_id_list_entry_add(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ svc_port_id_entry *current_entry;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "attempting to add a svc_port_id (%u) entry "
+ "to NULL subscriber terminal\n",
+ svc_port_id);
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* Check if the id is already on the list before adding it */
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->svc_port_id_list,
+ next)
+ {
+ if(current_entry->svc_port_id == svc_port_id)
+ {
+ ret = BCM_ERR_ALREADY;
+ break;
+ }
+ }
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* Get a new entry and configure it */
+ current_entry = bcmos_calloc(sizeof(svc_port_id_entry));
+
+ if (NULL == current_entry)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ current_entry->svc_port_id = svc_port_id;
+
+ /* Save the entry on the list of subscriber-terminal ids on this interface */
+ TAILQ_INSERT_TAIL(&p_sub_term_inst->svc_port_id_list,
+ current_entry, next);
+
+ (p_sub_term_inst->num_svc_port_ids)++;
+ }
+
+ current_entry->ref_count++;
+
+ } while (0);
+
+ return ret;
+
+}
+
+bcmos_errno bcmbal_sub_term_svc_port_id_list_entry_remove(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ svc_port_id_entry *current_entry, *p_temp_entry;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "attempting to remove a svc_port_id (%u) entry "
+ "from a NULL subscriber terminal\n",
+ svc_port_id);
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &p_sub_term_inst->svc_port_id_list,
+ next,
+ p_temp_entry)
+ {
+ if(current_entry->svc_port_id == svc_port_id)
+ {
+ if(0 == --current_entry->ref_count)
+ {
+ /* Remove it from the list of agg_port_ids on this subscriber terminal */
+ TAILQ_REMOVE(&p_sub_term_inst->svc_port_id_list,
+ current_entry, next);
+
+ bcmos_free(current_entry);
+
+ (p_sub_term_inst->num_svc_port_ids)--;
+ }
+
+ ret = BCM_ERR_OK;
+ break;
+ }
+ }
+ } while (0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_sub_term_agg_port_id_list_entry_add( sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ agg_port_id_entry *current_entry;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "attempting to add a svc_port_id (%u) entry "
+ "to a NULL subscriber terminal\n",
+ agg_port_id);
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* Check if the id is already on the list before adding it */
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->agg_port_id_list,
+ next)
+ {
+ if(current_entry->agg_port_id == agg_port_id)
+ {
+ ret = BCM_ERR_ALREADY;
+ break;
+ }
+ }
+
+ if(BCM_ERR_OK == ret)
+ {
+ /* Get a new entry and configure it */
+ current_entry = bcmos_calloc(sizeof(agg_port_id_entry));
+
+ if (NULL == current_entry)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ current_entry->agg_port_id = agg_port_id;
+
+ /* Save the entry on the list of subscriber-terminal ids on this interface */
+ TAILQ_INSERT_TAIL(&p_sub_term_inst->agg_port_id_list,
+ current_entry, next);
+
+ (p_sub_term_inst->num_agg_port_ids)++;
+ }
+
+ (current_entry->ref_count)++;
+
+ } while (0);
+
+ return ret;
+
+}
+
+bcmos_errno bcmbal_sub_term_agg_port_id_list_entry_remove(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ agg_port_id_entry *current_entry, *p_temp_entry;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "attempting to remove a agg_port_id (%u) entry "
+ "from a NULL subscriber terminal\n",
+ agg_port_id);
+
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &p_sub_term_inst->agg_port_id_list,
+ next,
+ p_temp_entry)
+ {
+ if(current_entry->agg_port_id == agg_port_id)
+ {
+ if(0 == --current_entry->ref_count)
+ {
+ /* Remove it from the list of agg_port_ids on this subscriber terminal */
+ TAILQ_REMOVE(&p_sub_term_inst->agg_port_id_list,
+ current_entry, next);
+
+ bcmos_free(current_entry);
+
+ (p_sub_term_inst->num_agg_port_ids)--;
+ }
+
+ ret = BCM_ERR_OK;
+ break;
+ }
+ }
+ } while (0);
+
+ return ret;
+}
+
+static bcmos_errno svc_port_id_list_fill(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id_list_u8 *svc_port_id_list)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ svc_port_id_entry *current_entry = NULL;
+ int ii = 0;
+
+ do
+ {
+ /* Traverse the list of svc_port_ids recorded and fill in the list to be returned */
+ svc_port_id_list->len = p_sub_term_inst->num_svc_port_ids;
+ svc_port_id_list->val = bcmos_calloc(sizeof(bcmbal_service_port_id) * svc_port_id_list->len);
+
+ if (NULL == svc_port_id_list->val)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->svc_port_id_list,
+ next)
+ {
+ svc_port_id_list->val[ii++] = current_entry->svc_port_id;
+ }
+
+ } while (0);
+
+ return ret;
+}
+
+static bcmos_errno agg_port_id_list_fill(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id_list_u8 *agg_port_id_list)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ agg_port_id_entry *current_entry = NULL;
+ int ii = 0;
+
+ do
+ {
+ /* Traverse the list of svc_port_ids recorded and fill in the list to be returned */
+ agg_port_id_list->len = p_sub_term_inst->num_agg_port_ids;
+ agg_port_id_list->val = bcmos_calloc(sizeof(bcmbal_aggregation_port_id) * agg_port_id_list->len);
+
+ if (NULL == agg_port_id_list->val)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->agg_port_id_list,
+ next)
+ {
+ agg_port_id_list->val[ii++] = current_entry->agg_port_id;
+ }
+
+ } while (0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_sub_term_check_svc_port_in_use(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ svc_port_id_entry *current_entry = NULL;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "NULL subscriber terminal\n");
+
+ break;
+ }
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->svc_port_id_list,
+ next)
+ {
+ if(current_entry->svc_port_id == svc_port_id)
+ {
+ ret = BCM_ERR_OK;
+ break;
+ }
+ }
+ } while (0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_sub_term_check_agg_port_in_use(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ agg_port_id_entry *current_entry = NULL;
+
+ do
+ {
+ if(NULL == p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "NULL subscriber terminal\n");
+
+ break;
+ }
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH(current_entry,
+ &p_sub_term_inst->agg_port_id_list,
+ next)
+ {
+ if(current_entry->agg_port_id == agg_port_id)
+ {
+ ret = BCM_ERR_OK;
+ break;
+ }
+ }
+ } while (0);
+
+ return ret;
+}
+
+
+
+static bcmos_errno bcmbal_sub_term_tm_scheds_set(const bcmbal_subscriber_terminal_cfg *p_sub_term_cfg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_key tm_sched_key;
+
+ do
+ {
+ if(BCMBAL_CFG_PROP_IS_SET(p_sub_term_cfg, subscriber_terminal, us_tm))
+ {
+ tm_sched_key.dir = BCMBAL_TM_SCHED_DIR_US;
+ tm_sched_key.id = p_sub_term_cfg->data.us_tm;
+ if(BCM_ERR_OK!= (ret = bcmbal_tm_sched_set_sub_term_owner(tm_sched_key, p_sub_term_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "failed to set sub term us_tm, ret = %s", bcmos_strerror(ret));
+ break;
+ }
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(p_sub_term_cfg, subscriber_terminal, ds_tm))
+ {
+ tm_sched_key.dir = BCMBAL_TM_SCHED_DIR_DS;
+ tm_sched_key.id = p_sub_term_cfg->data.ds_tm;
+
+ if(BCM_ERR_OK!= (ret = bcmbal_tm_sched_set_sub_term_owner(tm_sched_key, p_sub_term_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_sub_term,
+ "failed to set sub term ds_tm, ret = %s", bcmos_strerror(ret));
+ break;
+ }
+ }
+ }while(0);
+ return ret;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/sub_term_fsm.h b/bal_release/src/core/main/sub_term_fsm.h
new file mode 100755
index 0000000..3d7cf72
--- /dev/null
+++ b/bal_release/src/core/main/sub_term_fsm.h
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file sub_term_fsm.h
+ * @brief Code to support the BAL Subscriber Terminal FSM
+ *
+ * @defgroup sub_terminal Subscriber Terminal
+ * @ingroup core
+ */
+
+
+#ifndef SUB_TERM_FSM_H
+#define SUB_TERM_FSM_H
+
+/*@{*/
+
+#include <bal_api.h>
+
+/* The current implementation supports a global pool of
+ * ONU instances.
+ */
+#define NUM_SUPPORTED_SUB_TERMS (4096)
+
+typedef enum
+{
+ SUB_TERM_FSM_EVENT_TYPE_NONE = -1,
+ SUB_TERM_FSM_EVENT_TYPE_ADMIN_UP ,
+ SUB_TERM_FSM_EVENT_TYPE_ADMIN_DN ,
+ SUB_TERM_FSM_EVENT_TYPE_REMOVE ,
+ SUB_TERM_FSM_EVENT_TYPE_UTIL_MSG ,
+ SUB_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG ,
+
+
+ SUB_TERM_FSM_EVENT_TYPE__LAST,
+ SUB_TERM_FSM_EVENT_TYPE__NUM_OF
+} sub_term_fsm_event_type;
+
+
+
+typedef enum
+{
+ SUB_TERM_FSM_STATE_NONE = -1,
+ SUB_TERM_FSM_STATE_NULL ,
+ SUB_TERM_FSM_STATE_CONFIGURING ,
+ SUB_TERM_FSM_STATE_CONFIGURED ,
+ SUB_TERM_FSM_STATE_REMOVING ,
+
+
+ SUB_TERM_FSM_STATE__LAST,
+ SUB_TERM_FSM_STATE__NUM_OF
+} sub_term_fsm_state;
+
+
+typedef enum
+{
+ SUB_TERM_FLAG_ANY = 1, /**< ONLY USED in the sub_term get argument */
+ SUB_TERM_FLAG_ACTIVE , /**< A sub_term is on the active list */
+ SUB_TERM_FLAG_FREE /**< A sub_term is on the free list */
+} sub_term_flag;
+
+
+typedef struct sub_term_fsm_event
+{
+ sub_term_fsm_event_type event_type; /**< The sub_term FSM event */
+ void *msg;
+} sub_term_fsm_event;
+
+
+typedef struct svc_port_id_entry
+{
+ bcmbal_service_port_id svc_port_id;
+ uint8_t ref_count; /**< A count of the number of re-uses of this svc_port_id on this subscriber terminal */
+ TAILQ_ENTRY(svc_port_id_entry) next ; /**< TAILQ link */
+}svc_port_id_entry;
+
+typedef struct agg_port_id_entry
+{
+ bcmbal_aggregation_port_id agg_port_id;
+ uint8_t ref_count; /**< A count of the number of re-uses of this agg_port_id on this subscriber terminal */
+ TAILQ_ENTRY(agg_port_id_entry) next ; /**< TAILQ link */
+}agg_port_id_entry;
+
+typedef struct sub_term_inst sub_term_inst;
+struct sub_term_inst
+{
+ bcmbal_subscriber_terminal_cfg current_sub_term_info; /**< The current information for this sub_term (used for GET) */
+ bcmbal_subscriber_terminal_cfg api_req_sub_term_info; /**< The last sub_term object info received from the Public API */
+ sub_term_fsm_state fsm_state; /**< The sub_term instance FSM state */
+ uint16_t num_svc_port_ids; /**< The number of bearer traffic GEMs on this subscriber terminal */
+ TAILQ_HEAD(svc_port_id_list_head, svc_port_id_entry) svc_port_id_list; /* A list of svc_port_ids on this subscriber terminal */
+ uint16_t num_agg_port_ids; /**< The number of alloc ids on this subscriber terminal */
+ TAILQ_HEAD(agg_port_id_list_head, agg_port_id_entry) agg_port_id_list; /* A list of svc_port_ids on this subscriber terminal */
+ TAILQ_ENTRY(sub_term_inst) sub_term_inst_next ; /**< TAILQ link for active list and free list management */
+};
+
+
+/*
+ * Sub_Term FSM data structures
+ */
+typedef struct sub_term_fsm_ctx
+{
+ /* Lists of free sub_term entries and active sub_term entries
+ */
+ TAILQ_HEAD(free_sub_term_list_head, sub_term_inst) free_sub_term_list;
+
+ TAILQ_HEAD(active_sub_term_list_head, sub_term_inst) active_sub_term_list;
+
+} sub_term_fsm_ctx;
+
+
+/*
+ * Function declarations
+ */
+extern bcmos_errno sub_term_fsm_init(void);
+
+extern bcmos_errno sub_term_fsm_finish(void);
+
+extern bcmos_errno process_subscriber_terminal_object(void *msg_payload);
+
+extern bcmos_errno process_subscriber_terminal_util_msg(void *msg_payload);
+
+extern sub_term_inst *sub_term_inst_get(bcmbal_subscriber_terminal_key *key,
+ sub_term_flag sub_term_flag);
+
+extern bcmos_errno sub_term_svc_port_id_get(bcmbal_sub_id sub_term_id,
+ uint16_t access_int_id,
+ bcmbal_service_port_id *p_svc_port_id);
+
+extern bcmos_errno bcmbal_sub_term_svc_port_id_list_entry_add(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id);
+
+extern bcmos_errno bcmbal_sub_term_svc_port_id_list_entry_remove(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id);
+
+bcmos_errno bcmbal_sub_term_agg_port_id_list_entry_add(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id);
+
+bcmos_errno bcmbal_sub_term_agg_port_id_list_entry_remove(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id);
+
+bcmos_errno bcmbal_sub_term_check_agg_port_in_use(sub_term_inst *p_sub_term_inst,
+ bcmbal_aggregation_port_id agg_port_id);
+
+bcmos_errno bcmbal_sub_term_check_svc_port_in_use(sub_term_inst *p_sub_term_inst,
+ bcmbal_service_port_id svc_port_id);
+
+
+
+/*@}*/
+
+#endif /*SUB_TERM_FSM_H */
+
+
diff --git a/bal_release/src/core/main/tm_queue_fsm.c b/bal_release/src/core/main/tm_queue_fsm.c
new file mode 100755
index 0000000..a9999cb
--- /dev/null
+++ b/bal_release/src/core/main/tm_queue_fsm.c
@@ -0,0 +1,981 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file tm_queue_fsm.c
+ * @brief Code to support the BAL tm_queue FSM
+ *
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <tm_queue_fsm.h>
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include "rsc_mgr.h"
+
+#include <bal_objs.h>
+#include <fsm_common.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+ /*
+ * @brief The logging device id for tm queue
+ */
+static dev_log_id log_id_tm_queue;
+#endif
+
+/* local function declarations */
+
+static bcmos_errno tm_queue_free_by_entry(tm_queue_inst *p_entry);
+static bcmos_errno tm_queue_fsm_state_err(tm_queue_inst *p_tm_queue_inst, void *msg, tm_queue_fsm_event *p_event);
+static void tm_queue_inst_entry_obj_init(tm_queue_inst *p_entry);
+
+/*
+ * @brief The Global tm_queue fsm context data structure
+ */
+static tm_queue_fsm_ctx g_tm_queue_fsm_tm_queue_list_ctx;
+
+/*
+ * Macros for tm_queue ctx access
+ */
+#define TM_QUEUE_FSM_TM_QUEUE_LIST_CTX (g_tm_queue_fsm_tm_queue_list_ctx)
+#define TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR (&g_tm_queue_fsm_tm_queue_list_ctx)
+
+
+/*
+ * @brief The definition of a tm_queue FSM state processing function
+ */
+typedef bcmos_errno (* tm_queue_fsm_state_processor)(tm_queue_inst *, void *, tm_queue_fsm_event *);
+static bcmos_errno bcmbal_tm_queue_create(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event);
+
+static bcmos_errno bcmbal_tm_queue_active_destroy (tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event);
+static bcmos_errno bcmbal_tm_queue_inactive_destroy(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event);
+
+
+static tm_queue_fsm_state_processor tm_queue_states[TM_QUEUE_FSM_STATE__NUM_OF][TM_QUEUE_FSM_EVENT_TYPE__NUM_OF] =
+{
+ [TM_QUEUE_FSM_STATE_NULL] =
+ {
+ [TM_QUEUE_FSM_EVENT_TYPE_CREATE] = bcmbal_tm_queue_create,
+ },
+ [TM_QUEUE_FSM_STATE_INACTIVE] =
+ {
+ [TM_QUEUE_FSM_EVENT_TYPE_DESTROY] = bcmbal_tm_queue_inactive_destroy,
+ },
+ [TM_QUEUE_FSM_STATE_ACTIVE] =
+ {
+ [TM_QUEUE_FSM_EVENT_TYPE_DESTROY] = bcmbal_tm_queue_active_destroy,
+ },
+
+};
+
+static char *state_name_str[] =
+{
+ "TM_QUEUE_FSM_STATE_NULL",
+ "TM_QUEUE_FSM_STATE_INACTIVE",
+ "TM_QUEUE_FSM_STATE_ACTIVE",
+ "TM_QUEUE_FSM_STATE_IN_USE",
+ "TM_QUEUE_FSM_STATE_DELETING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT(TM_QUEUE_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), tm_queue_fsm_state);
+
+static char *tm_queue_state_name_get(tm_queue_fsm_state state)
+{
+ if(state < TM_QUEUE_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "TM_QUEUE_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "TM_QUEUE_FSM_CREATE_EVENT",
+ "TM_QUEUE_FSM_DESTROY_EVENT",
+ "FLOW_FSM_UTIL_MSG_EVENT",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT(TM_QUEUE_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), tm_queue_fsm_event_type);
+
+static char *tm_queue_event_name_get(tm_queue_fsm_event_type event)
+{
+ if(event < TM_QUEUE_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "TM_QUEUE_EVT_UNKNOWN";
+ }
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Tm queue FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_tm_queue_inst Pointer to a tm_queue instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a tm_queue event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_queue_fsm_state_err(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(DEBUG, log_id_tm_queue,
+ "Error encountered processing TM_queue FSM"
+ " - BAD EVENT ()\n");
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the Tm Queue FSM infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno tm_queue_fsm_init(void)
+{
+ int ii;
+ tm_queue_inst *new_entry;
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ log_id_tm_queue = bcm_dev_log_id_register("TM_QUEUE", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_tm_queue == DEV_LOG_INVALID_ID);
+#endif
+
+ /* Initialize all of the tm_queue queues */
+ TAILQ_INIT(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list);
+ TAILQ_INIT(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list);
+
+ /* Populate the free list with it's initial set of tm_queues
+ */
+ for(ii=0; ii<TM_QUEUE_ALLOCATION_BLOCK_SIZE; ii++)
+ {
+ new_entry = bcmos_calloc(sizeof(tm_queue_inst));
+ if(NULL == new_entry)
+ {
+ BCM_LOG(FATAL, log_id_tm_queue, "Failed to initialize the tm_queue free list - FATAL\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+ tm_queue_free_by_entry(new_entry);
+ }
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to un-initialize the Tm Queue FSM infrastructure.
+ *
+ * NOTE: This is called once on shutdown and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno tm_queue_fsm_finish(void)
+{
+
+ tm_queue_inst *current_entry, *p_temp_entry;
+
+ /* Free all the entries on the active list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list,
+ tm_queue_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list, current_entry, tm_queue_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ /* Free all the entries on the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list,
+ tm_queue_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list, current_entry, tm_queue_inst_next);
+
+ bcmos_free(current_entry);
+ }
+
+ return BCM_ERR_OK;
+}
+
+static void tm_queue_inst_entry_obj_init(tm_queue_inst *p_entry)
+{
+ /* The actual key content is irrelevant for free tm_queues */
+ bcmbal_tm_queue_key key = { .id = 0, .sched_id = 0, .sched_dir = BCMBAL_TM_SCHED_DIR_US};
+
+ /* And add it to the free list */
+ p_entry->fsm_state = TM_QUEUE_FSM_STATE_NULL;
+
+ BCMBAL_CFG_INIT(&p_entry->current_tm_queue_info,
+ tm_queue,
+ key);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_tm_queue_info), BCMOS_FALSE);
+}
+/*****************************************************************************/
+/**
+ * @brief A function to free a tm_queue instance specified by a the supplied
+ * entry pointer.
+ *
+ * @param p_entry A pointer to the entry to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_queue_free_by_entry(tm_queue_inst *p_entry)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_queue_inst *current_entry;
+ tm_queue_inst *p_temp_entry;
+
+ /*
+ * First, check the active list (an active tm_queue can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list,
+ tm_queue_inst_next,
+ p_temp_entry)
+ {
+ if(current_entry == p_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list, current_entry, tm_queue_inst_next);
+ break;
+ }
+ }
+ tm_queue_inst_entry_obj_init(p_entry);
+ TAILQ_INSERT_TAIL(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list, p_entry, tm_queue_inst_next);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The Tm queue FSM state processing executive function
+ * @param p_tm_queue_inst Pointer to a tm_queu instance
+ * @param p_event Pointer to a tm_Queue event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_queue_fsm_exec(tm_queue_inst *p_tm_queue_inst, tm_queue_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_queue_fsm_state pre_state;
+ tm_queue_fsm_state_processor tm_queue_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_tm_queue_inst);
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state for debug printing
+ */
+ pre_state = p_tm_queue_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ tm_queue_state_processor = tm_queue_states[p_tm_queue_inst->fsm_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if(tm_queue_state_processor)
+ {
+ ret = tm_queue_state_processor(p_tm_queue_inst, p_event->msg, p_event);
+ }
+ else
+ {
+ tm_queue_fsm_state_err(p_tm_queue_inst, p_event->msg, p_event);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "*** Error detected during state processing\n");
+ p_tm_queue_inst->fsm_state = pre_state;
+ }
+
+ BCM_LOG(DEBUG, log_id_tm_queue, "*** Event %s, State: %s --> %s\n\n",
+ tm_queue_event_name_get(p_event->event_type),
+ tm_queue_state_name_get(pre_state),
+ tm_queue_state_name_get(p_tm_queue_inst->fsm_state));
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a tm_queue instance of the specified class.
+ *
+ * @param key A pointer to the key of the tm_queue being referenced
+ * @param search_flag A flag specifying the type of tm_queue
+ * instance to be retrieved
+ *
+ * @returns tm_queue_inst_t* A pointer to the found tm_queue instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+tm_queue_inst *tm_queue_inst_get(bcmbal_tm_queue_key key, tm_queue_flag search_flag)
+{
+ tm_queue_inst *current_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ if(TM_QUEUE_FLAG_ACTIVE & search_flag)
+ {
+ TAILQ_FOREACH(current_entry,
+ &TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list,
+ tm_queue_inst_next)
+ {
+
+ if(current_entry->api_req_tm_queue_info.key.id == key.id
+ && current_entry->api_req_tm_queue_info.key.sched_id == key.sched_id
+ && current_entry->api_req_tm_queue_info.key.sched_dir == key.sched_dir)
+ {
+ BCM_LOG(DEBUG, log_id_tm_queue, "Found active tm_queue\n");
+ /* The tm_queue instance pointer is in current_entry */
+ break;
+ }
+ }
+ }
+ /*
+ * Next, check the free list if the caller has chosen to do so
+ */
+ if((TM_QUEUE_FLAG_FREE & search_flag) && (NULL == current_entry))
+ {
+ /* Now check the free list */
+ if(!TAILQ_EMPTY(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list))
+ {
+ /* Just grab the first entry */
+ current_entry = TAILQ_FIRST(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list);
+
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->free_tm_queue_list, current_entry, tm_queue_inst_next);
+
+ /* And add it to the active list */
+ TAILQ_INSERT_TAIL(&TM_QUEUE_FSM_TM_QUEUE_LIST_CTX_PTR->active_tm_queue_list, current_entry, tm_queue_inst_next);
+
+ /*
+ * Initialize the fsm state
+ */
+ current_entry->fsm_state = TM_QUEUE_FSM_STATE_NULL;
+
+ BCM_LOG(DEBUG, log_id_tm_queue, "Using new tm_queue\n");
+ }
+ }
+
+ if((TM_QUEUE_FLAG_ANY & search_flag) && (NULL == current_entry))
+ {
+ /*A tm_queue was not found on either list*/
+
+ BCM_LOG(DEBUG, log_id_tm_queue, "************** ERROR: no tm_queue found\n");
+ }
+
+ return current_entry;
+}
+
+static bcmos_errno bcmbal_tm_queue_validate(bcmbal_tm_queue_cfg *p_tm_queue_cfg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_key tm_sched_key = {.id = p_tm_queue_cfg->key.sched_id, .dir = p_tm_queue_cfg->key.sched_dir};
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ do
+ {
+ /*get the tm sched instance*/
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR: no related tm_sched found (id = %d dir = %s)\n",
+ tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir));
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ /*check it is not an agg port tm sched - as there are no queues to such node*/
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
+ {
+ if(BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT == p_tm_sched_inst->req_tm_sched_info.data.owner.type)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR: should not attach queue to node which is owned by agg port (id = %d dir = %s)\n",
+ tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir));
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+
+ /*sched level should be 'queue'*/
+ if(BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE != p_tm_sched_inst->req_tm_sched_info.data.sched_child_type)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR: tm sched sched level is invalid (%d), should be BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE\n",
+ p_tm_sched_inst->req_tm_sched_info.data.sched_child_type);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*based on sched type, check priority / weight is set and is valid */
+ if(BCMBAL_TM_SCHED_TYPE_SP == p_tm_sched_inst->req_tm_sched_info.data.sched_type)
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, priority))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue must be set with a priority, as its scheduler' sched_type is sp\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue can not be set with a weight, as its scheduler' sched_type is sp\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(p_tm_queue_cfg->data.priority >= p_tm_sched_inst->req_tm_sched_info.data.num_priorities)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue priority (%d) is higher than the allowed at parent scheduler (id = %d dir = %s num of priorities = %d )\n",
+ p_tm_queue_cfg->data.priority , tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir),
+ p_tm_sched_inst->req_tm_sched_info.data.num_priorities);
+
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ if(BCMBAL_TM_SCHED_TYPE_WFQ == p_tm_sched_inst->req_tm_sched_info.data.sched_type)
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue must be set with a weight, as its scheduler' sched_type sched_type is wfq\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, priority))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue can not be set with a priority, as its scheduler' sched_type sched_type is wfq \n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ if(BCMBAL_TM_SCHED_TYPE_SP_WFQ == p_tm_sched_inst->req_tm_sched_info.data.sched_type)
+ {
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, priority)
+ && BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue must be set with either weight or priority, not both. as its scheduler' sched_type is sp_wfq\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, priority)
+ && !BCMBAL_CFG_PROP_IS_SET(p_tm_queue_cfg, tm_queue, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Queue must be set with either weight or priority, as its scheduler' sched_type is sp_wfq\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }while(0);
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * tm_queue object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_tm_queue_object(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_queue_cfg *p_tm_queue_cfg = (bcmbal_tm_queue_cfg *)msg_payload;
+ tm_queue_inst *p_tm_queue_inst = NULL;
+ tm_queue_fsm_event fsm_event;
+ bcmbal_tm_queue_key tm_queue_key;
+ bcmbal_obj_msg_type oper_type;
+ bcmbal_tm_sched_key tm_sched_key;
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ bcmbal_interface_key intf_key;
+ bcmbal_tm_sched_owner owner;
+
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_tm_queue, "Processing a tm queue object\n");
+
+ tm_queue_key = p_tm_queue_cfg->key;
+ oper_type = p_tm_queue_cfg->hdr.hdr.type;
+
+ /*
+ * A message pointer may be passed inside the event structure.
+ */
+ fsm_event.msg = msg_payload;
+
+ /* SET or GET or CLEAR...? */
+ switch(oper_type)
+ {
+ case(BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ do
+ {
+ BCM_LOG(DEBUG, log_id_tm_queue, "Processing a tm queue SET REQ mgmt message\n");
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ /*Find the specified tm_queue instance is already created */
+ p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_ACTIVE);
+
+ if(NULL != p_tm_queue_inst)
+ {
+ /* This is a fatal error condition */
+ BCM_LOG(ERROR, log_id_tm_queue,
+ "ERROR - tm queue found. Set after create is currently not supported. No further processing\n");
+ ret = BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_FREE);
+ if(NULL == p_tm_queue_inst )
+ {
+ /* This is a fatal error condition */
+ BCM_LOG(ERROR, log_id_tm_queue,
+ "ERROR - tm queue not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+ if(BCM_ERR_OK != (ret = bcmbal_tm_queue_validate(p_tm_queue_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "tm_queue fsm validation Failed (%d)\n", ret);
+ tm_queue_free_by_entry(p_tm_queue_inst);
+ break;
+ }
+
+
+ /* Perform the validation check(s) that the utils require */
+ if(BCM_ERR_OK != (ret = sw_util_tm_queue_validate(p_tm_queue_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "tm_queue switch validation Failed (%d)\n", ret);
+ tm_queue_free_by_entry(p_tm_queue_inst);
+ break;
+ }
+
+
+
+ BCM_LOG(DEBUG, log_id_tm_queue,
+ "Creating a new tm queue\n");
+
+ }while(0);
+
+ ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_queue);
+
+ if(BCM_ERR_OK != ret )
+ {
+ break;
+ }
+
+ BCMBAL_CFG_PROP_SET(p_tm_queue_cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);
+
+ bcmbal_tm_queue_object_overlay(&p_tm_queue_inst->api_req_tm_queue_info, p_tm_queue_cfg);
+
+ fsm_event.event_type = TM_QUEUE_FSM_EVENT_TYPE_CREATE;
+ fsm_event.msg = msg_payload;
+ ret = tm_queue_fsm_exec(p_tm_queue_inst,&fsm_event);
+ }
+ break;
+
+ case(BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+ BCM_LOG(DEBUG, log_id_tm_queue, "Processing a tm queue GET REQ mgmt message\n");
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ }
+ else
+ {
+ /* Find the specified tm_queue instance */
+ p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_ACTIVE);
+ }
+
+ if(NULL == p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR - Specified tm_queue (%d) not found\n", tm_queue_key.id);
+ ret = BCM_ERR_NOENT;
+
+ }
+ else
+ {
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested */
+ p_tm_queue_inst->api_req_tm_queue_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_tm_queue_cfg *)msg_payload) = p_tm_queue_inst->api_req_tm_queue_info;
+ }
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_queue);
+ }
+ break;
+
+ case(BCMBAL_OBJ_MSG_TYPE_CLEAR):
+ {
+ do
+ {
+ BCM_LOG(DEBUG, log_id_tm_queue, "Processing a tm queue CLEAR REQ mgmt message\n");
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+ /*
+ * Find the specified tm_queue instance
+ */
+ p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_ACTIVE);
+
+ if(NULL == p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Specified tm_queue not found on CLEAR\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+
+ if(TM_QUEUE_FSM_STATE_IN_USE == p_tm_queue_inst->fsm_state)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Specified tm_queue is in use and can not be removed\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*TM_QUEUEs (either auto or manually created) that are associated with a TM_NODE with owner interface
+ may only be deleted when the associated interface is in the ADMIN-DOWN state*/
+ tm_sched_key.id = tm_queue_key.sched_id;
+ tm_sched_key.dir = tm_queue_key.sched_dir;
+
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "ERROR: no related tm_sched found (id = %d dir = %s)\n",
+ tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir));
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(&(p_tm_sched_inst->req_tm_sched_info), tm_sched, owner))
+ {
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ switch(owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ intf_key.intf_type = owner.u.interface.intf_type;
+ intf_key.intf_id = owner.u.interface.intf_id;
+ if(BCMBAL_STATUS_DOWN != bcmbal_interface_status_get(intf_key))
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Specified tm_queue is attached to sched that is owned by interface that is not admin down, and can be removed only when the associated interface is in the ADMIN-DOWN state\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*generate destroy event*/
+
+ fsm_event.event_type = TM_QUEUE_FSM_EVENT_TYPE_DESTROY;
+ fsm_event.msg = msg_payload;
+ ret = tm_queue_fsm_exec(p_tm_queue_inst,&fsm_event);
+
+ }while(0);
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_queue);
+ }
+ break;
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "Unsupported operation on tm queue object (%d)\n", oper_type );
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_queue);
+ }
+ }
+
+ BCM_LOG(DEBUG, log_id_tm_queue, "%s returns\n", __FUNCTION__);
+ return ret;
+
+}
+
+bcmos_errno bcmbal_tm_queue_auto_create(bcmbal_tm_queue_cfg cfg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_queue_inst *p_tm_queue_inst = NULL;
+ do
+ {
+ /*Find a free tm_queue instance */
+ p_tm_queue_inst = tm_queue_inst_get(cfg.key, TM_QUEUE_FLAG_FREE);
+ if(NULL == p_tm_queue_inst)
+ {
+ /* This is a fatal error condition*/
+ BCM_LOG(ERROR, log_id_tm_queue,"ERROR - tm queue not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+ p_tm_queue_inst->api_req_tm_queue_info = cfg;
+ ret = bcmbal_tm_queue_create(p_tm_queue_inst,NULL, NULL);
+ }while(0);
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_queue_activate(tm_queue_inst *p_tm_queue_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+
+ ret = sw_util_tm_queue_set(p_tm_queue_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue could not be set by switch\n");
+ break;
+ }
+
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_ACTIVE;
+ /* The hardware has properly accepted the object info, so the request object becomes
+ * the current state.
+ */
+ bcmbal_tm_queue_object_overlay(&p_tm_queue_inst->current_tm_queue_info,
+ &p_tm_queue_inst->api_req_tm_queue_info);
+
+ }while(0);
+ return ret;
+
+}
+
+bcmos_errno bcmbal_tm_queue_deactivate(tm_queue_inst *p_tm_queue_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BUG_ON(NULL == p_tm_queue_inst);
+
+ do
+ {
+ ret = sw_util_tm_queue_clear(p_tm_queue_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue could not be set by switch\n");
+ break;
+ }
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_INACTIVE;
+ }while(0);
+ return ret;
+
+}
+static bcmos_errno bcmbal_tm_queue_create(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_INACTIVE;
+
+ /*referenced tm sched exist for sure as it was already validated*/
+ ret = bcmbal_tm_sched_set_queue(p_tm_queue_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue could not be attched to node \n");
+ break;
+ }
+ }while(0);
+ return ret;
+
+}
+
+bcmos_errno bcmbal_tm_queue_set_owner(bcmbal_tm_queue_key key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_queue_inst *p_tm_queue_inst;
+ do
+ {
+ p_tm_queue_inst = tm_queue_inst_get(key,TM_QUEUE_FLAG_ACTIVE);
+ if(NULL == p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue,"ERROR - tm queue not found. No further processing\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_queue_activate(p_tm_queue_inst);
+ }while(0);
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_queue_unset_owner(bcmbal_tm_queue_key key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_queue_inst *p_tm_queue_inst;
+ do
+ {
+ p_tm_queue_inst = tm_queue_inst_get(key,TM_QUEUE_FLAG_ACTIVE);
+ if(NULL == p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue,"ERROR - tm queue not found. No further processing\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_queue_deactivate(p_tm_queue_inst);
+
+ }while(0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_queue_use_set(tm_queue_inst *p_tm_queue_inst, bcmos_bool is_in_use)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BUG_ON(NULL == p_tm_queue_inst);
+ if(is_in_use)
+ {
+ /*queue might already in requested state*/
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_IN_USE;
+ p_tm_queue_inst->api_req_tm_queue_info.data.ref_count++;
+ }
+ else
+ {
+ if(p_tm_queue_inst->api_req_tm_queue_info.data.ref_count)
+ {
+ p_tm_queue_inst->api_req_tm_queue_info.data.ref_count--;
+
+ if(0 == p_tm_queue_inst->api_req_tm_queue_info.data.ref_count)
+ {
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_ACTIVE;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue (sched.id = %d sched.dir = %s queue.id = %d) could not be unset as no flows assign to it \n", p_tm_queue_inst->api_req_tm_queue_info.key.sched_id, TM_SCHED_DIR_TO_STR(p_tm_queue_inst->api_req_tm_queue_info.key.sched_dir), p_tm_queue_inst->api_req_tm_queue_info.key.id);
+ ret = BCM_ERR_INTERNAL;
+ }
+ }
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_queue_destroy(tm_queue_inst *p_tm_queue_inst, bcmos_bool remove_from_node)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_DELETING;
+ if(remove_from_node)
+ {
+ ret = bcmbal_tm_sched_remove_queue(p_tm_queue_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue could not be cleaared from its tm sched\n");
+ break;
+ }
+ }
+ ret = tm_queue_free_by_entry(p_tm_queue_inst);
+ }while(0);
+ return ret;
+}
+
+static bcmos_errno bcmbal_tm_queue_inactive_destroy(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event)
+{
+ return bcmbal_tm_queue_destroy(p_tm_queue_inst, BCMOS_TRUE);
+}
+
+static bcmos_errno bcmbal_tm_queue_active_destroy(tm_queue_inst *p_tm_queue_inst,
+ void *msg,
+ tm_queue_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ p_tm_queue_inst->fsm_state = TM_QUEUE_FSM_STATE_DELETING;
+ ret = sw_util_tm_queue_clear(p_tm_queue_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_queue, "queue could not be cleaared from the switch\n");
+ break;
+ }
+ ret = bcmbal_tm_queue_inactive_destroy(p_tm_queue_inst, msg, p_event);
+ }while(0);
+ return ret;
+}
+/*@}*/
diff --git a/bal_release/src/core/main/tm_queue_fsm.h b/bal_release/src/core/main/tm_queue_fsm.h
new file mode 100755
index 0000000..1240cf1
--- /dev/null
+++ b/bal_release/src/core/main/tm_queue_fsm.h
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file tm_queue_fsm.h
+ * @brief Code to support the BAL tm_queue FSM
+ *
+ */
+
+#ifndef TM_QUEUE_FSM_H
+#define TM_QUEUE_FSM_H
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_api.h>
+
+/* set the total pool size of available tm queue to 4k */
+#define TM_QUEUE_ALLOCATION_BLOCK_SIZE (4096)
+
+typedef enum
+{
+ TM_QUEUE_FSM_EVENT_TYPE_NONE = -1,
+ TM_QUEUE_FSM_EVENT_TYPE_CREATE ,
+ TM_QUEUE_FSM_EVENT_TYPE_DESTROY ,
+ TM_QUEUE_FSM_EVENT_TYPE_UTIL_MSG ,
+
+ TM_QUEUE_FSM_EVENT_TYPE__LAST,
+ TM_QUEUE_FSM_EVENT_TYPE__NUM_OF
+} tm_queue_fsm_event_type;
+
+
+
+typedef enum
+{
+ TM_QUEUE_FSM_STATE_NONE = -1,
+ TM_QUEUE_FSM_STATE_NULL ,
+ TM_QUEUE_FSM_STATE_INACTIVE ,
+ TM_QUEUE_FSM_STATE_ACTIVE ,
+ TM_QUEUE_FSM_STATE_IN_USE ,
+ TM_QUEUE_FSM_STATE_DELETING ,
+
+ TM_QUEUE_FSM_STATE__LAST,
+ TM_QUEUE_FSM_STATE__NUM_OF
+} tm_queue_fsm_state;
+
+
+typedef enum
+{
+ TM_QUEUE_FLAG_ACTIVE = 1<<0, /**< A tm_queue is on the active list */
+ TM_QUEUE_FLAG_FREE = 1<<1, /**< A tm_queue is on the free list */
+ TM_QUEUE_FLAG_ANY = (TM_QUEUE_FLAG_ACTIVE | TM_QUEUE_FLAG_FREE), /**< A tm_queue is on either the active or free list */
+} tm_queue_flag;
+
+
+typedef struct tm_queue_fsm_event_t
+{
+ tm_queue_fsm_event_type event_type; /**< The tm_queue fsm events */
+ void *msg;
+
+ /* other necessary information */
+} tm_queue_fsm_event;
+
+
+typedef struct tm_queue_inst tm_queue_inst;
+struct tm_queue_inst
+{
+ bcmbal_tm_queue_cfg current_tm_queue_info; /**< The current information for this tm queue (used for GET) */
+ bcmbal_tm_queue_cfg api_req_tm_queue_info; /**< The tm queue object info received from the Public API */
+ tm_queue_fsm_state fsm_state; /**< The tm queue FSM state */
+
+ TAILQ_ENTRY(tm_queue_inst) tm_queue_inst_next; /**< TAILQ link */
+};
+
+
+/*
+ * tm_queue FSM data structures
+ */
+typedef struct tm_queue_fsm_ctx
+{
+ /* Lists of free tm_queue entries and active tm_queue entries
+ */
+ TAILQ_HEAD(free_tm_queue_list_head, tm_queue_inst) free_tm_queue_list;
+
+ TAILQ_HEAD(active_tm_queue_list_head, tm_queue_inst) active_tm_queue_list;
+
+} tm_queue_fsm_ctx;
+
+
+/* Function declarations */
+
+extern bcmos_errno tm_queue_fsm_init(void);
+extern bcmos_errno tm_queue_fsm_finish(void);
+extern bcmos_errno process_tm_queue_object(void *msg_payload);
+
+extern tm_queue_inst *tm_queue_inst_get(bcmbal_tm_queue_key key, tm_queue_flag search_flag);
+extern bcmos_errno bcmbal_tm_queue_auto_create(bcmbal_tm_queue_cfg tm_queue_default_cfg);
+extern bcmos_errno bcmbal_tm_queue_set_owner(bcmbal_tm_queue_key key);
+extern bcmos_errno bcmbal_tm_queue_unset_owner(bcmbal_tm_queue_key key);
+
+extern bcmos_errno bcmbal_tm_queue_activate(tm_queue_inst *p_tm_queue_inst);
+extern bcmos_errno bcmbal_tm_queue_deactivate(tm_queue_inst *p_tm_queue_inst);
+extern bcmos_errno bcmbal_tm_queue_use_set(tm_queue_inst *p_tm_queue_inst, bcmos_bool is_in_use);
+extern bcmos_errno bcmbal_tm_queue_destroy(tm_queue_inst *p_tm_queue_inst, bcmos_bool remove_from_node);
+
+
+
+/*@}*/
+
+#endif /*TM_QUEUE_FSM_H */
+
diff --git a/bal_release/src/core/main/tm_sched_fsm.c b/bal_release/src/core/main/tm_sched_fsm.c
new file mode 100644
index 0000000..50424cb
--- /dev/null
+++ b/bal_release/src/core/main/tm_sched_fsm.c
@@ -0,0 +1,2229 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file tm_sched_fsm.c
+ * @brief Code to support the BAL tm_sched FSM
+ *
+ *
+ */
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <tm_sched_fsm.h>
+#include <bal_msg.h>
+#include <bal_osmsg.h>
+#include "bal_worker.h"
+#include "bal_mac_util.h"
+#include "bal_switch_util.h"
+#include <bal_api.h>
+//#include <bal_mac_util_common_itu_pon.h>
+
+
+#include <bal_objs.h>
+#include <fsm_common.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+ /*
+ * @brief The logging device id for tm sched
+ */
+static dev_log_id log_id_tm_sched;
+#endif
+
+/* local function declarations */
+
+static bcmos_errno tm_sched_fsm_create(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+
+static bcmos_errno tm_sched_free_by_entry(tm_sched_inst *p_entry);
+static void tm_sched_inst_entry_obj_init(tm_sched_inst *p_entry);
+static bcmos_errno queues_list_fill(tm_sched_inst *p_tm_sched_inst,
+ bcmbal_tm_queue_id_list_u8 *queues_list);
+
+
+static bcmos_errno tm_sched_fsm_state_err(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+static bcmos_errno tm_sched_fsm_assigned_process_util_msg(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+static bcmos_errno tm_sched_fsm_deleting_process_util_msg(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+
+static bcmos_errno tm_sched_fsm_inactive_destroy(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+
+static bcmos_errno tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+
+static bcmos_errno tm_sched_fsm_assigned_destroy(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event);
+
+static bcmos_errno tm_sched_fsm_destroy(tm_sched_inst *p_tm_sched_inst);
+
+static bcmos_errno tm_sched_fsm_exec(tm_sched_inst *p_tm_sched_inst, tm_sched_fsm_event *p_event);
+
+static tm_sched_inst* tm_sched_find_by_owner(bcmbal_tm_sched_owner owner);
+
+static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id);
+static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id);
+
+static bcmos_errno sub_scheds_list_fill(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id_list_u8 *sub_scheds_list);
+/*
+ * @brief The Global tm_sched fsm context data structure
+ */
+static tm_sched_fsm_ctx g_tm_sched_fsm_tm_sched_list_ctx;
+
+/*
+ * Macros for tm_sched ctx access
+ */
+#define TM_SCHED_FSM_TM_SCHED_LIST_CTX (g_tm_sched_fsm_tm_sched_list_ctx)
+#define TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR (&g_tm_sched_fsm_tm_sched_list_ctx)
+
+
+/*
+ * @brief The definition of a tm_sched FSM state processing function
+ */
+typedef bcmos_errno (* tm_sched_fsm_state_processor)(tm_sched_inst *, void *, tm_sched_fsm_event *);
+/*
+ * @brief The tm sched FSM state processing array
+ */
+static tm_sched_fsm_state_processor tm_sched_states[TM_SCHED_FSM_STATE__NUM_OF][TM_SCHED_FSM_EVENT_TYPE__NUM_OF] =
+{
+
+ [TM_SCHED_FSM_STATE_NULL] =
+ {
+ [TM_SCHED_FSM_EVENT_TYPE_CREATE] = tm_sched_fsm_create,
+ [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG] = tm_sched_fsm_state_err,
+
+ },
+ [TM_SCHED_FSM_STATE_INACTIVE] =
+ {
+ [TM_SCHED_FSM_EVENT_TYPE_CREATE] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_inactive_destroy,
+ [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG] = tm_sched_fsm_state_err,
+ },
+ [TM_SCHED_FSM_STATE_ASSIGNED] =
+ {
+ [TM_SCHED_FSM_EVENT_TYPE_CREATE] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_assigned_destroy,
+ [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG] = tm_sched_fsm_assigned_process_util_msg,
+ },
+ [TM_SCHED_FSM_STATE_ACTIVE] =
+ {
+ [TM_SCHED_FSM_EVENT_TYPE_CREATE] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_active_destroy,
+ [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG] = tm_sched_fsm_state_err,
+ },
+
+ [TM_SCHED_FSM_STATE_DELETING] =
+ {
+ [TM_SCHED_FSM_EVENT_TYPE_CREATE] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
+ [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG] = tm_sched_fsm_deleting_process_util_msg,
+
+ },
+
+};
+
+static char *state_name_str[] =
+{
+ "TM_SCHED_FSM_STATE_NULL",
+ "TM_SCHED_FSM_STATE_INACTIVE",
+ "TM_SCHED_FSM_STATE_ASSIGNED",
+ "TM_SCHED_FSM_STATE_ACTIVE",
+ "TM_SCHED_FSM_STATE_DELETING",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT(TM_SCHED_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), tm_sched_fsm_state);
+
+static char *tm_sched_state_name_get(tm_sched_fsm_state state)
+{
+ if(state < TM_SCHED_FSM_STATE__LAST)
+ {
+ return state_name_str[state];
+ }
+ else
+ {
+ return "TM_SCHED_UNKNOWN";
+ }
+}
+
+static char *event_name_str[] =
+{
+ "TM_SCHED_FSM_CREATE_EVENT",
+ "TM_SCHED_FSM_DESTROY_EVENT",
+ "TM_SCHED_FSM_ASSIGN_EVENT",
+ "FLOW_FSM_UTIL_MSG_EVENT",
+};
+
+/* Ensure that the name array size matches the associated enum */
+BAL_STATIC_ASSERT(TM_SCHED_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), tm_sched_fsm_event_type);
+
+static char *tm_sched_event_name_get(tm_sched_fsm_event_type event)
+{
+ if(event < TM_SCHED_FSM_EVENT_TYPE__LAST)
+ {
+ return event_name_str[event];
+ }
+ else
+ {
+ return "TM_SCHED_EVT_UNKNOWN";
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/**
+ * @brief A function to initialize the tm sched FSM infrastructure.
+ *
+ * NOTE: This is called once on startup and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno tm_sched_fsm_init(void)
+{
+ int ii;
+ tm_sched_inst *new_entry;
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifdef ENABLE_LOG
+ log_id_tm_sched = bcm_dev_log_id_register("TM_SCHED", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_tm_sched == DEV_LOG_INVALID_ID);
+#endif
+
+ /* Initialize all of the tm_sched queues */
+ TAILQ_INIT(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list);
+ TAILQ_INIT(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list);
+
+ /* Populate the free list with it's initial set of tm_scheds */
+ for(ii=0; ii<TM_SCHED_ALLOCATION_BLOCK_SIZE; ii++)
+ {
+
+ new_entry = bcmos_calloc(sizeof(tm_sched_inst));
+
+ if(NULL == new_entry)
+ {
+ BCM_LOG(FATAL, log_id_tm_sched, "Failed to initialize the tm_sched free list - FATAL\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ tm_sched_free_by_entry(new_entry);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to un-initialize the tm sched FSM infrastructure.
+ *
+ * NOTE: This is called once on shutdown and NOT for each FSM instance.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno tm_sched_fsm_finish(void)
+{
+
+ tm_sched_inst *current_entry, *p_temp_entry;
+
+ /* Free all the entries on the active list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
+ tm_sched_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);
+
+ bcmos_free(current_entry);
+
+ }
+
+ /* Free all the entries on the free list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list,
+ tm_sched_inst_next,
+ p_temp_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, current_entry, tm_sched_inst_next);
+
+ bcmos_free(current_entry);
+ }
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to retrieve a tm_sched instance of the specified class.
+ *
+ * @param key A pointer to the key of the tm_sched being referenced
+ * @param search_flag A flag specifying the type of tm_sched
+ * instance to be retrieved
+ *
+ * @returns tm_sched_inst_t* A pointer to the found tm_sched instance,
+ * or NULL if one is not found
+ *****************************************************************************/
+tm_sched_inst *tm_sched_inst_get(bcmbal_tm_sched_key key, tm_sched_flag search_flag)
+{
+ tm_sched_inst *current_entry = NULL;
+
+ /*
+ * First, check the active list if the caller has chosen to do so
+ */
+ if(TM_SCHED_FLAG_ACTIVE & search_flag)
+ {
+ TAILQ_FOREACH(current_entry,
+ &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
+ tm_sched_inst_next)
+ {
+
+ if(current_entry->req_tm_sched_info.key.id == key.id
+ && current_entry->req_tm_sched_info.key.dir == key.dir)
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched, "Found active tm_sched\n");
+ /* The tm_sched instance pointer is in current_entry */
+ break;
+ }
+ }
+ }
+
+ /*
+ * Next, check the free list if the caller has chosen to do so
+ */
+ if((TM_SCHED_FLAG_FREE & search_flag) && (NULL == current_entry))
+ {
+ /* Now check the free list */
+ if(!TAILQ_EMPTY(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list))
+ {
+ /* Just grab the first entry */
+ current_entry = TAILQ_FIRST(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list);
+
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, current_entry, tm_sched_inst_next);
+
+ /* And add it to the active list */
+ TAILQ_INSERT_TAIL(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);
+
+ /*
+ * Initialize the fsm state
+ */
+ current_entry->fsm_state = TM_SCHED_FSM_STATE_NULL;
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "Using new tm_sched\n");
+
+ }
+ }
+
+ if((TM_SCHED_FLAG_ANY & search_flag) && (NULL == current_entry))
+ {
+ /*A tm_sched was not found on either list */
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "************** ERROR: no tm_sched found\n");
+ }
+
+ return current_entry;
+}
+
+static bcmos_errno bcmbal_tm_sched_validate_sched_parent(const bcmbal_tm_sched_cfg *p_tm_sched_cfg, tm_sched_inst **p_parent_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_key tm_sched_key;
+ tm_sched_key.dir = p_tm_sched_cfg->key.dir;
+ tm_sched_key.id = p_tm_sched_cfg->data.sched_parent.sched_id;
+
+ do
+ {
+ (*p_parent_tm_sched_inst) = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+ if(NULL == (*p_parent_tm_sched_inst))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent dir = %s id = %d does not exist and therefor can not be set at the tm sched parent\n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /*check weight/priority setting based on parent sched_type*/
+ if(BCMBAL_TM_SCHED_TYPE_SP == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
+ {
+ if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with a priority, as its sched_parent' sched_type is sp\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent can not be set with a weight, as its sched_parent' sched_type is sp\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(p_tm_sched_cfg->data.sched_parent.priority >= (*p_parent_tm_sched_inst)->req_tm_sched_info.data.num_priorities)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "sched priority (%d) is higher than the allowed at parent sched (id = %d dir = %s num of priorities = %d )\n",
+ p_tm_sched_cfg->data.sched_parent.priority , tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir),
+ (*p_parent_tm_sched_inst)->req_tm_sched_info.data.num_priorities);
+
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ if(BCMBAL_TM_SCHED_TYPE_WFQ == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
+ {
+ if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with a weight, as its sched_parent' sched_type is wrr\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent can not be set with a priority, as its sched_parent' sched_type is wrr \n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ if(BCMBAL_TM_SCHED_TYPE_SP_WFQ == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
+ {
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority)
+ && BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with either weight or priority, not both. as its sched_parent' sched_type is sp_wrr\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority)
+ && !BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with either weight or priority, as its sched_parent' sched_type is sp_wrr\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }while(0);
+
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief tm_sched_fsm_info_validate
+ *
+ * This routine is used to validate all input attributes required for a tm_sched
+ * settings
+ *
+ * @param p_tm_sched_cfg A pointer to a tm sched object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+static bcmos_errno tm_sched_fsm_info_validate(const bcmbal_tm_sched_cfg *p_tm_sched_cfg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_owner owner = p_tm_sched_cfg->data.owner;
+ bcmbal_interface_key intf_key;
+ bcmbal_subscriber_terminal_key sub_term_key;
+ sub_term_inst *p_sub_term_inst = NULL;
+ tm_sched_inst *p_tm_sched_inst;
+ bcmos_bool is_sched_type_and_level_mandatory = BCMOS_TRUE;
+
+ do
+ {
+ if(!_rsc_mgr_tm_sched_id_validate(p_tm_sched_cfg->key.id))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Illegal tm sched id (reserved for auto created) \n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, owner))
+ {
+ switch(owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ /*tm sched owned by agg port is the only case sched type might be unset*/
+ is_sched_type_and_level_mandatory = BCMOS_FALSE;
+
+ if(BCMBAL_TM_SCHED_DIR_US != p_tm_sched_cfg->key.dir)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "tm sched owned by agg port must be of US direction, while tm sched id = %d is not\n", p_tm_sched_cfg->key.dir);
+ return BCM_ERR_PARM;
+ }
+ /*agg port owned tm sched can not be part of hqos, therefor can not have sched parent set*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_parent))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "tm sched owned by agg port is a tsand alone and can not have sched_parent set to it");
+ return BCM_ERR_PARM;
+ }
+ /*validate all required parameters are set*/
+ if((owner.u.agg_port.intf_id == BAL_API_MAX_INTF_ID)
+ || (owner.u.agg_port.sub_term_id == BCMBAL_SUB_ID_UNKNOWN))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Illegal owner agg port settings intf_id = %d sub_id = %d \n",
+ owner.u.agg_port.intf_id, owner.u.agg_port.sub_term_id);
+ return BCM_ERR_PARM;
+ }
+
+ /*validate interface is up*/
+ intf_key.intf_id = owner.u.agg_port.intf_id;
+ intf_key.intf_type = BCMBAL_INTF_TYPE_PON;
+
+ if(bcmbal_interface_status_get(intf_key)!= BCMBAL_STATUS_UP)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "intf = %d is not UP\n",
+ intf_key.intf_id);
+ return BCM_ERR_NOT_CONNECTED;
+ }
+
+ /*validate sub terminal exist*/
+ sub_term_key.intf_id = owner.u.agg_port.intf_id;
+ sub_term_key.sub_term_id = owner.u.agg_port.sub_term_id;
+
+ p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if(!p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to get subscriber terminal with intf = %d id = %u\n",
+ sub_term_key.intf_id, sub_term_key.sub_term_id);
+ return BCM_ERR_NOENT;
+ }
+ }
+ break;
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ /*validate sub terminal exist*/
+ sub_term_key.intf_id = owner.u.uni.intf_id;
+ sub_term_key.sub_term_id = owner.u.uni.sub_term_id;
+
+ p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
+
+ if(!p_sub_term_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to get subscriber terminal with intf = %d id = %u\n",
+ sub_term_key.intf_id, sub_term_key.sub_term_id);
+ return BCM_ERR_NOENT;
+ }
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if(BCMOS_TRUE == is_sched_type_and_level_mandatory)
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_type))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched type is a mandatory parameter for setting tm sched\n");
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+ /*if sched type is sp or wrr_sp, num_of_priorities is a mandatory parameter*/
+ if(BCMBAL_TM_SCHED_TYPE_SP == p_tm_sched_cfg->data.sched_type
+ || BCMBAL_TM_SCHED_TYPE_SP_WFQ == p_tm_sched_cfg->data.sched_type)
+ {
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, num_priorities))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "num_priorities is a mandatory parameter for setting tm sched with sched type %s\n",
+ BCMBAL_TM_SCHED_TYPE_SP == p_tm_sched_cfg->data.sched_type ? "sp" : "sp_wrr");
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+ }
+ if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_child_type))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Sched child type is a mandatory parameter for setting tm sched\n");
+ ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+ }
+
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_parent))
+ {
+ if(BCM_ERR_OK == (ret = bcmbal_tm_sched_validate_sched_parent(p_tm_sched_cfg, &p_tm_sched_inst)))
+ {
+ if(BCM_ERR_OK != (ret = bcmbal_tm_sched_sub_scheds_list_entry_add(p_tm_sched_inst, p_tm_sched_cfg->key.id)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "could not set scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_cfg->data.sched_parent.sched_id,
+ TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->key.id, bcmos_strerror(ret));
+ break;
+ }
+ }
+ else
+ {
+
+ BCM_LOG(ERROR, log_id_tm_sched, "could not validate scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
+ TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->data.sched_parent.sched_id,
+ TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->key.id, bcmos_strerror(ret));
+ break;
+ }
+ }
+
+ }while(0);
+
+ return ret;
+
+}
+/*****************************************************************************/
+/**
+ * @brief A function called by the core worker thread to process an
+ * tm_sched object message (SET, GET, CLEAR, STATS) received
+ * from the BAL Public API.
+ *
+ * @param msg_payload Pointer to a BAL message received from the
+ * BAL Public API.
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_tm_sched_object(void *msg_payload)
+{
+ bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
+ bcmbal_tm_sched_cfg *p_tm_sched_cfg = (bcmbal_tm_sched_cfg *)msg_payload;
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ tm_sched_fsm_event fsm_event;
+ bcmbal_tm_sched_key tm_sched_key;
+ bcmbal_obj_msg_type oper_type;
+ bcmbal_tm_sched_owner owner;
+ uint32_t ref_count;
+ queue_entry *current_queue_entry;
+ bcmbal_tm_queue_key current_queue_key;
+ tm_queue_inst *current_queue_inst;
+ bcmbal_interface_key intf_key;
+
+ do
+ {
+ BUG_ON(NULL == msg_payload);
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "Processing a tm sched object\n");
+
+ tm_sched_key = p_tm_sched_cfg->key;
+ oper_type = p_tm_sched_cfg->hdr.hdr.type;
+
+ /*
+ * A message pointer may be passed inside the event structure.
+ */
+ fsm_event.msg = msg_payload;
+
+ /* SET or GET or CLEAR...? */
+ switch(oper_type)
+ {
+ case(BCMBAL_OBJ_MSG_TYPE_SET):
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched, "Processing a tm sched SET REQ mgmt message\n");
+ do
+ {
+ if(BCMBAL_STATUS_UP != acc_term_status_get())
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - Access-terminal is not UP. No further processing\n");
+ ret = BCM_ERR_STATE;
+ break;
+ }
+
+ /*Find the specified tm_sched instance is already created */
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL != p_tm_sched_inst)
+ {
+ /* This is a fatal error condition */
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - tm sched found. Set after create is currently not supported. No further processing\n");
+ ret = BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_FREE);
+ if(NULL == p_tm_sched_inst)
+ {
+ /* This is a fatal error condition */
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - tm sched not found. No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "Creating a new tm sched\n");
+
+ BCMBAL_CFG_PROP_SET(p_tm_sched_cfg, tm_sched, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);
+
+ /* Fill in given cfg with current tm sched instance API request data structure and validate it*/
+ bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->req_tm_sched_info, p_tm_sched_cfg);
+
+ /* Check if the mandatory tm sched attributes have been set, and range check where applicable */
+ if(BCM_ERR_OK != (ret = tm_sched_fsm_info_validate(p_tm_sched_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "tm_sched fsm validation Failed (%d)\n", ret);
+ tm_sched_free_by_entry(p_tm_sched_inst);
+ break;
+ }
+
+
+ /* Perform the validation check(s) that the utils require */
+ if(BCM_ERR_OK != (ret = sw_util_tm_sched_validate(p_tm_sched_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "tm_sched switch validation Failed (%d)\n", ret);
+ tm_sched_free_by_entry(p_tm_sched_inst);
+ break;
+ }
+
+ }while(0);
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+ rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);
+ if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
+ {
+ break;
+ }
+
+ /*
+ * Initial checks complete. Process the request
+ */
+ fsm_event.event_type = TM_SCHED_FSM_EVENT_TYPE_CREATE;
+ /*
+ * Run the tm sched FSM to process this event
+ */
+ ret = tm_sched_fsm_exec(p_tm_sched_inst, &fsm_event);
+
+ }//SET
+ break;
+
+ case(BCMBAL_OBJ_MSG_TYPE_GET):
+ {
+ bcmbal_tm_queue_id_list_u8 queues_list = {};
+ bcmbal_tm_sched_id_list_u8 sub_scheds_list = {};
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "Processing a tm sched GET REQ mgmt message\n");
+
+ /* Just return the tm sched data info that we have on record for tm sched instance */
+ /*Find the specified tm sched instance */
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched not found on GET\n");
+ ret = BCM_ERR_NOENT;
+ }
+ else
+ {
+ /* Return the queues list if requested */
+ BCMBAL_CFG_PROP_CLEAR(&p_tm_sched_inst->req_tm_sched_info,
+ tm_sched,
+ queues);
+
+ /* If the user requested the list of queues for this tm sched then return the list.*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg,
+ tm_sched,
+ queues))
+ {
+
+ if(BCM_ERR_OK == queues_list_fill(p_tm_sched_inst, &queues_list))
+ {
+ /* NOTE: The returned list may be empty */
+ BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info,
+ tm_sched,
+ queues,
+ queues_list);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Error trying to fill queues list to return\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ /* Return the sub scheds list if requested */
+ BCMBAL_CFG_PROP_CLEAR(&p_tm_sched_inst->req_tm_sched_info,
+ tm_sched,
+ sub_scheds);
+
+ /* If the user requested the list of sub scheds for this tm sched then return the list.*/
+ if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg,
+ tm_sched,
+ sub_scheds))
+ {
+
+ if(BCM_ERR_OK == sub_scheds_list_fill(p_tm_sched_inst, &sub_scheds_list))
+ {
+ /* NOTE: The returned list may be empty */
+ BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info,
+ tm_sched,
+ sub_scheds,
+ sub_scheds_list);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Error trying to fill sub_scheds list to return\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ /* We respond to the BAL public API backend with a result. We always
+ * send a complete msg_payload back to the API, but the data portion
+ * of the object is only relevant when a GET or GET-STATS has been requested.
+ */
+
+ p_tm_sched_inst->req_tm_sched_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
+ *((bcmbal_tm_sched_cfg *)msg_payload) = p_tm_sched_inst->req_tm_sched_info;
+
+ }
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);
+
+ /* Free the temporary lists if they were used */
+ if(queues_list.val)
+ {
+ bcmos_free(queues_list.val);
+ }
+ }//GET
+ break;
+
+ case(BCMBAL_OBJ_MSG_TYPE_CLEAR):
+ {
+ do
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched, "Processing a tm sched CLEAR REQ mgmt message\n");
+ /*Find the specified tm sched instance */
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched not found on Clear\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /*user can not clear auto created sched owned by agg port*/
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
+ {
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ if(BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT == owner.type
+ && BCMBAL_TM_CREATION_MODE_AUTO == p_tm_sched_inst->req_tm_sched_info.data.creation_mode)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is auto created, therefor can not be manually deleted\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /*check that a tm is not active,
+ if that tm owned by interface, it is active if any of its queue is active.
+ if it is owned by agg port, it is active if the agg port id has ref count > 1 */
+ switch(owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ rsc_mgr_alloc_id_get_ref_count(owner.u.agg_port.intf_id,owner.u.agg_port.agg_port_id,&ref_count);
+ if(ref_count > 1)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is active and therefor can not be deleted (if = %d agg id = %d, ref count = %d \n",
+ owner.u.agg_port.intf_id,owner.u.agg_port.agg_port_id, ref_count);
+ ret = BCM_ERR_PARM;
+ }
+ break;
+ }//BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ TAILQ_FOREACH(current_queue_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+ if(NULL != current_queue_entry)
+ {
+ current_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
+ current_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
+ current_queue_key.id = current_queue_entry->queue_id;
+ current_queue_inst = tm_queue_inst_get(current_queue_key, TM_QUEUE_FLAG_ACTIVE);
+ if(NULL == current_queue_inst)
+ {
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ if(TM_QUEUE_FSM_STATE_IN_USE == current_queue_inst->fsm_state)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is active (has an in use queue) and therefor can not be deleted (queue id = %d \n",
+ current_queue_key.id);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }//TAILQ_FOREACH
+ if(BCM_ERR_OK == ret)
+ {
+ /*TM_SCHEDs (either auto or manually created) with owner interface may only be deleted there are no attached TM_QUEUEs, and only when the associated interface is in the ADMIN-DOWN state*/
+ intf_key.intf_type = owner.u.interface.intf_type;
+ intf_key.intf_id = owner.u.interface.intf_id;
+ if(BCMBAL_STATUS_DOWN != bcmbal_interface_status_get(intf_key))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is owned by interface that is not admin down, and can be removed only when the associated interface is in the ADMIN-DOWN state\n");
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ }//BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE
+ break;
+
+ default:
+ break;
+ }//switch owner.type
+ }//owner is set
+ /*generate destroy event*/
+ if(BCM_ERR_OK == ret)
+ {
+ fsm_event.event_type = TM_SCHED_FSM_EVENT_TYPE_DESTROY;
+ fsm_event.msg = msg_payload;
+ ret = tm_sched_fsm_exec(p_tm_sched_inst,&fsm_event);
+ }
+ }while(0);
+
+ mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);
+ }//CLEAR
+ break;
+
+ default:
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Unsupported operation on tm sched object (%d)\n",
+ oper_type);
+ ret = BCM_ERR_NOT_SUPPORTED;
+ }
+ }
+ }while(0);
+ BCM_LOG(DEBUG, log_id_tm_sched, "%s returns\n", __FUNCTION__);
+
+ return ret;
+}
+
+
+static void tm_sched_inst_entry_obj_init(tm_sched_inst *p_entry)
+{
+ /* The actual key content is irrelevant for free tm_scheds */
+ bcmbal_tm_sched_key key = { .id = 0, .dir = BCMBAL_TM_SCHED_DIR_DS};
+
+ BCMBAL_CFG_INIT(&p_entry->current_tm_sched_info,
+ tm_sched,
+ key);
+ p_entry->fsm_state = TM_SCHED_FSM_STATE_NULL;
+ /* Initialize the queues and suc scheds lists */
+ p_entry->num_queues_on_node = 0;
+ TAILQ_INIT(&p_entry->queues_list);
+
+ p_entry->num_sub_scheds_on_node = 0;
+ TAILQ_INIT(&p_entry->sub_scheds_list);
+
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_tm_sched_info), BCMOS_FALSE);
+}
+/*****************************************************************************/
+/**
+ * @brief A function to free a tm_sched instance specified by a the supplied
+ * entry pointer.
+ *
+ * @param p_entry A pointer to the entry to be freed
+ *
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_sched_free_by_entry(tm_sched_inst *p_entry)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *current_entry;
+ tm_sched_inst *p_temp_entry;
+ /*
+ * First, check the active list (an active tm_sched can be in the adding or removing state)
+ */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
+ tm_sched_inst_next,
+ p_temp_entry)
+ {
+ if(current_entry == p_entry)
+ {
+ /* Remove it from the active list */
+ TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);
+ break;
+ }
+ }
+ tm_sched_inst_entry_obj_init(p_entry);
+
+ /* And add it to the free list */
+ TAILQ_INSERT_TAIL(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, p_entry, tm_sched_inst_next);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The tm sched FSM state processing executive function
+ *
+ * @param p_tm_sched_inst Pointer to a tm_sched instance
+ * @param p_event Pointer to a tm_sched event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_sched_fsm_exec(tm_sched_inst *p_tm_sched_inst, tm_sched_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_fsm_state pre_state;
+ tm_sched_fsm_state_processor tm_sched_state_processor;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_tm_sched_inst);
+ BUG_ON(NULL == p_event);
+
+ /* Record the present state for debug printing
+ */
+ pre_state = p_tm_sched_inst->fsm_state;
+
+ /*
+ * Get the state processing function
+ */
+ tm_sched_state_processor = tm_sched_states[p_tm_sched_inst->fsm_state][p_event->event_type];
+
+ /*
+ * If there's a state processing function for this event and state, execute it.
+ * Otherwise, process a generic error.
+ */
+ if(tm_sched_state_processor)
+ {
+ ret = tm_sched_state_processor(p_tm_sched_inst, p_event->msg, p_event);
+ }
+ else
+ {
+ tm_sched_fsm_state_err(p_tm_sched_inst, p_event->msg, p_event);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "*** Error detected during state processing\n");
+ p_tm_sched_inst->fsm_state = pre_state;
+ }
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "*** Event %s, State: %s --> %s\n\n",
+ tm_sched_event_name_get(p_event->event_type),
+ tm_sched_state_name_get(pre_state),
+ tm_sched_state_name_get(p_tm_sched_inst->fsm_state));
+
+ return ret;
+}
+
+
+
+/*****************************************************************************/
+/**
+ * @brief The tm sched FSM function which is executed when an error
+ * is encountered during FSM processing.
+ *
+ * @param p_tm_sched_inst Pointer to a tm_sched instance
+ * @param msg Pointer to a BAL message received from one of
+ * the BAL apps.
+ * @param p_event Pointer to a tm_sched event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_sched_fsm_state_err(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event)
+{
+ bcmos_errno ret = BCM_ERR_INVALID_OP;
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "Error encountered processing TM_SCHED FSM"
+ " - BAD EVENT ()\n");
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to process a tm sched object event received
+ * from one of the BAL apps.
+ *
+ * @param msg_payload A pointer to the util message
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno process_tm_sched_util_msg(void *msg_payload)
+{
+
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_msg_type type;
+ bcmbal_tm_sched_key key;
+ tm_sched_inst *p_tm_sched_inst;
+ tm_sched_fsm_event tm_sched_event;
+
+
+ BUG_ON(NULL == msg_payload);
+ do
+ {
+ type = bcmbal_type_minor_get(msg_payload);
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "Processing a tm sched %s util message from %s\n",
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+
+ if(BAL_MSG_TYPE_IND == type)
+ {
+
+ /* recover the key from the message */
+ key = ((bal_util_msg_ind *)msg_payload)->obj_key.tm_sched_key;
+
+
+ /*
+ * Get the sub_term instance that's being referenced
+ */
+ p_tm_sched_inst = tm_sched_inst_get(key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "invalid tm sched (dir %s id %d) found while processing a util message type %s from %s\n",
+ TM_SCHED_DIR_TO_STR(key.dir),
+ key.id,
+ bcmbal_msg_t_str[type],
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ tm_sched_event.msg = msg_payload;
+
+ tm_sched_event.event_type = TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG;
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "p_tm_sched_inst->fsm_state=%d, tm_sched_event.event_type = %d\n",
+ p_tm_sched_inst->fsm_state, tm_sched_event.event_type);
+ /*Run the tm sched FSM to process this event */
+ if(BCM_ERR_OK == ret)
+ {
+ ret = tm_sched_fsm_exec(p_tm_sched_inst, &tm_sched_event);
+ }
+ }
+
+ else
+ {
+ ret = BCM_ERR_NOT_SUPPORTED;
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Unknown message type received from the APP (not one of RSP:ACK:IND:AUTO_IND) (type:%d)\n",
+ type);
+ }
+ }while(0);
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief The tm sched FSM state processing for a tm sched create command received
+ * from the BAL Public API.
+ *
+ * @param p_tm_sched_inst Pointer to a tm sched instance
+ * @param msg Pointer to a BAL message received from the BAL Public API
+ * @param p_event Pointer to a tm sched event structure
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+static bcmos_errno tm_sched_fsm_create(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_INACTIVE;
+
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched,owner))
+ {
+ ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst);
+ }
+
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_sched_set_owner(tm_sched_inst *p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_owner owner;
+ bcmbal_tm_queue_key tm_queue_key;
+ bcmbal_tm_sched_key tm_sched_key = p_tm_sched_inst->req_tm_sched_info.key;
+ queue_entry *current_queue_entry;
+
+
+ BUG_ON(NULL == p_tm_sched_inst);
+ do
+ {
+ if( BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched,owner))
+ {
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ASSIGNED;
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ switch(owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ /*no need to validate owner attributes as these are read only and set by VALID internal objects*/
+ if(BCM_ERR_OK != (ret = sw_util_tm_sched_set(p_tm_sched_inst)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "error %s detected by switch util while adding tm sched\n", bcmos_strerror(ret));
+ break;
+ }
+ /* The hardware has properly accepted the object info, so the request object becomes the current state. */
+ bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->current_tm_sched_info,
+ &p_tm_sched_inst->req_tm_sched_info);
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ACTIVE;
+ /*configure all assigned queues*/
+
+ TAILQ_FOREACH(current_queue_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+ tm_queue_key.id = current_queue_entry->queue_id;
+ tm_queue_key.sched_id = tm_sched_key.id;
+ tm_queue_key.sched_dir = tm_sched_key.dir;
+ if(BCM_ERR_OK != (ret = bcmbal_tm_queue_set_owner(tm_queue_key)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Could not set queue sched id = %d sched dir = %s queue id = %d of the tm sched (%s)\n",
+ tm_queue_key.sched_id, TM_SCHED_DIR_TO_STR(tm_queue_key.sched_dir), tm_queue_key.id, bcmos_strerror(ret));
+ break;
+ }
+ }
+ BCMBAL_OBJ_IN_PROGRESS_SET(&(p_tm_sched_inst->current_tm_sched_info), BCMOS_FALSE);
+ p_tm_sched_inst->current_tm_sched_info.hdr.hdr.status = ret;
+
+ }
+ break;
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ bcmbal_interface_key intf_key = {.intf_type = BCMBAL_INTF_TYPE_PON, .intf_id = owner.u.agg_port.intf_id};
+ bcmbal_subscriber_terminal_key sub_key = {.sub_term_id = owner.u.agg_port.sub_term_id, .intf_id = intf_key.intf_id};
+ /*for agg port, should validate intf and sub term validity*/
+ if(NULL == sub_term_inst_get(&sub_key, SUB_TERM_FLAG_ACTIVE))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Can not set an agg port for onu (if-%d id-%d) which does not exist\n", intf_key.intf_id, sub_key.sub_term_id);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ BCM_LOG(DEBUG, log_id_tm_sched, "Getting a new ALLOC ID from resource manager\n");
+
+ owner.u.agg_port.agg_port_id = 0; /* 0 is a magic number telling the resource manager that it should provide the initial allocation of the ALLOC ID */
+ ret = rsc_mgr_alloc_id_alloc(intf_key.intf_id, &owner.u.agg_port.agg_port_id, 1, NULL);
+
+ if(BCM_ERR_OK != ret)
+ {
+ /* An error has occurred trying to get mandatory data */
+ BCM_LOG(ERROR, log_id_tm_sched, "Failed to get ALLOC ID from resource manager\n");
+ ret = BCM_ERR_NORES;
+ break;
+ }
+ /*set the agg port id into the inst*/
+ BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
+
+ ret = mac_util_agg_port_set(p_tm_sched_inst, BAL_UTIL_OPER_AGG_PORT_ADD);
+ if(BCM_ERR_OK != ret)
+ {
+ /* An error has occurred trying to configure mac*/
+ BCM_LOG(ERROR, log_id_tm_sched, "Failed to configure ALLOC ID at mac (%s)\n",bcmos_strerror(ret));
+ break;
+ }
+ }
+ break;
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ default:
+ BCM_LOG(ERROR, log_id_tm_sched, "nothing to do with owner type %d \n", p_tm_sched_inst->current_tm_sched_info.data.owner.type);
+ return BCM_ERR_PARM;
+ break;
+ }
+ }
+ }while(0);
+
+ return ret;
+}
+
+
+bcmos_errno bcmbal_tm_sched_unset_owner(tm_sched_inst *p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_owner *owner;
+ bcmbal_tm_queue_key tm_queue_key;
+ queue_entry *current_queue_entry;
+ tm_sched_inst *p_parent_tm_sched_inst;
+
+ BUG_ON(NULL == p_tm_sched_inst);
+
+ tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
+ tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
+
+ do
+ {
+ if( BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
+ {
+ owner = &(p_tm_sched_inst->req_tm_sched_info.data.owner);
+ switch(owner->type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ /*remove all assigned queues*/
+ TAILQ_FOREACH(current_queue_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+ tm_queue_key.id = current_queue_entry->queue_id;
+ if(BCM_ERR_OK != (ret = bcmbal_tm_queue_unset_owner(tm_queue_key)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Could not unset queue sched id = %d sched dir = %s queue id = %d of the tm sched (%s) \n",
+ tm_queue_key.sched_id, TM_SCHED_DIR_TO_STR(tm_queue_key.sched_dir), tm_queue_key.id, bcmos_strerror(ret));
+ break;
+ }
+ }
+ /*unset from parent scheduler*/
+ if(BCMBAL_CFG_PROP_IS_SET(&(p_tm_sched_inst->req_tm_sched_info), tm_sched, sched_parent))
+ {
+ if(BCM_ERR_OK == (ret = bcmbal_tm_sched_validate_sched_parent(&(p_tm_sched_inst->req_tm_sched_info), &p_parent_tm_sched_inst)))
+ {
+ if(BCM_ERR_OK == (ret = bcmbal_tm_sched_sub_scheds_list_entry_remove(p_parent_tm_sched_inst, p_tm_sched_inst->req_tm_sched_info.key.id)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "could not remove scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.data.sched_parent.sched_id,
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id, bcmos_strerror(ret));
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "could not validate scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.data.sched_parent.sched_id,
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id, bcmos_strerror(ret));
+ }
+ }
+
+ /*no need to validate owner attributes as these are read only and set by VALID internal objects*/
+ if(BCM_ERR_OK != (ret = sw_util_tm_sched_clear(p_tm_sched_inst)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "error %s detected by switch util while clearing tm sched\n", bcmos_strerror(ret));
+ break;
+ }
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_INACTIVE;
+
+ }
+ break;
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ default:
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "nothing to do with unsetting owner type %d \n",
+ p_tm_sched_inst->current_tm_sched_info.data.owner.type);
+ ret = BCM_ERR_PARM;
+ }
+ break;
+ }
+ }
+ }while(0);
+ return ret;
+
+}
+
+/*for the auto create, only key dir is set, id will be allocated from rsc mgr*/
+bcmos_errno bcmbal_tm_sched_auto_create(bcmbal_tm_sched_cfg cfg, tm_sched_inst **p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ cfg.key.id = 0; /* 0 is a magic number telling the resource manager that it should provide the initial allocation of the tm sched id*/
+ if(BCM_ERR_OK != (ret = _rsc_mgr_tm_sched_auto_id_alloc(&cfg.key.id)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,"Could not allocate a tm sched auto id \n");
+ break;
+ }
+ *p_tm_sched_inst = tm_sched_inst_get(cfg.key, TM_SCHED_FLAG_FREE);
+ if(NULL == p_tm_sched_inst)
+ {
+ /* This is a fatal error condition */
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not allocate tm sched No further processing\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "\n Tm Sched id %d dir %s was created \n", cfg.key.id, TM_SCHED_DIR_TO_STR(cfg.key.dir));
+
+ (*p_tm_sched_inst)->req_tm_sched_info = cfg;
+ ret = tm_sched_fsm_create(*p_tm_sched_inst, NULL,NULL);
+ }while(0);
+ return ret;
+}
+
+static bcmos_errno bcmbal_tm_sched_queues_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_queue_key queue_key)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ queue_entry *current_entry;
+
+ do
+ {
+ /* Check if the id is already on the list before adding it */
+ TAILQ_FOREACH(current_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+ if(current_entry->queue_id == queue_key.id)
+ {
+ return BCM_ERR_ALREADY;
+ }
+ }
+
+ /* Get a new entry and configure it */
+ current_entry = bcmos_calloc(sizeof(queue_entry));
+
+ if(NULL == current_entry)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "No memory available to add queue\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ current_entry->queue_id = queue_key.id;
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "adding queue id %u to tm sched %u\n", queue_key.id, p_tm_sched_inst->req_tm_sched_info.key.id);
+
+ /* Save the entry on the list of queues ids on this sched*/
+ TAILQ_INSERT_TAIL(&p_tm_sched_inst->queues_list,
+ current_entry, next);
+ (p_tm_sched_inst->num_queues_on_node)++;
+ } while(0);
+ return ret;
+}
+
+static bcmos_errno bcmbal_tm_sched_queues_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_queue_key queue_key)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ queue_entry *current_entry, *p_temp_entry;
+
+ do
+ {
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &p_tm_sched_inst->queues_list,
+ next,
+ p_temp_entry)
+ {
+ if(current_entry->queue_id == queue_key.id)
+ {
+ /* Remove it from the list of queues ids on this sched*/
+ TAILQ_REMOVE(&p_tm_sched_inst->queues_list,
+ current_entry, next);
+
+ bcmos_free(current_entry);
+
+ (p_tm_sched_inst->num_queues_on_node)--;
+ ret = BCM_ERR_OK;
+ break;
+
+ }
+ }
+ } while(0);
+
+ return ret;
+}
+
+static bcmos_errno queues_list_fill(tm_sched_inst *p_tm_sched_inst,
+ bcmbal_tm_queue_id_list_u8 *queues_list)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ queue_entry *current_entry = NULL;
+ int ii = 0;
+
+ do
+ {
+
+ /* Traverse the list of queues recorded and fill in the list to be returned */
+ queues_list->len = p_tm_sched_inst->num_queues_on_node;
+ queues_list->val = bcmos_calloc(sizeof(bcmbal_tm_queue_id) * queues_list->len);
+
+ if(NULL == queues_list->val)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ TAILQ_FOREACH(current_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "adding queue %d to response at array location %d\n",
+ current_entry->queue_id,
+ ii);
+ queues_list->val[ii++] = current_entry->queue_id;
+ }
+ } while(0);
+ return ret;
+}
+
+static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ sub_sched_entry *current_entry;
+
+ BUG_ON(NULL == p_tm_sched_inst);
+
+ do
+ {
+ /* Check if the id is already on the list before adding it */
+ TAILQ_FOREACH(current_entry,
+ &p_tm_sched_inst->sub_scheds_list,
+ next)
+ {
+ if(current_entry->sched_id == sched_id)
+ {
+ return BCM_ERR_ALREADY;
+ }
+ }
+
+ /* Get a new entry and configure it */
+ current_entry = bcmos_calloc(sizeof(sub_sched_entry));
+
+ if(NULL == current_entry)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "No memory available to add sub sched\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ current_entry->sched_id = sched_id;
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "adding sub sched id %u to tm sched dir = %s id = %u\n",
+ sched_id, TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id);
+
+ /* Save the entry on the list of sub_scheds on that tm sched */
+ TAILQ_INSERT_TAIL(&p_tm_sched_inst->sub_scheds_list,
+ current_entry, next);
+ (p_tm_sched_inst->num_sub_scheds_on_node)++;
+
+ } while(0);
+ return ret;
+}
+
+static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id)
+{
+ bcmos_errno ret = BCM_ERR_NOENT;
+ sub_sched_entry *current_entry, *p_temp_entry;
+
+ do
+ {
+
+ /* Check if the id is on the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &p_tm_sched_inst->sub_scheds_list,
+ next,
+ p_temp_entry)
+ {
+ if(current_entry->sched_id == sched_id)
+ {
+ /* Remove it from the list of sub_scheds ids on this sched*/
+ TAILQ_REMOVE(&p_tm_sched_inst->sub_scheds_list,
+ current_entry, next);
+
+ bcmos_free(current_entry);
+
+ (p_tm_sched_inst->num_sub_scheds_on_node)--;
+ ret = BCM_ERR_OK;
+ break;
+
+ }
+ }
+ } while(0);
+
+ return ret;
+}
+
+static bcmos_errno sub_scheds_list_fill(tm_sched_inst *p_tm_sched_inst,
+ bcmbal_tm_sched_id_list_u8 *sub_scheds_list)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ sub_sched_entry *current_entry = NULL;
+ int ii = 0;
+
+ do
+ {
+
+ /* Traverse the list of sub_scheds_ids recorded and fill in the list to be returned */
+ sub_scheds_list->len = p_tm_sched_inst->num_sub_scheds_on_node;
+ sub_scheds_list->val = bcmos_calloc(sizeof(bcmbal_tm_sched_id) * sub_scheds_list->len);
+
+ if(NULL == sub_scheds_list->val)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "No memory available\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ TAILQ_FOREACH(current_entry,
+ &p_tm_sched_inst->sub_scheds_list,
+ next)
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "adding sub sched %d to response at array location %d\n",
+ current_entry->sched_id,
+ ii);
+ sub_scheds_list->val[ii++] = current_entry->sched_id;
+ }
+
+ } while(0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_sched_set_queue(tm_queue_inst *p_tm_queue_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ bcmbal_tm_sched_key tm_sched_key;
+ BUG_ON(NULL == p_tm_queue_inst);
+ do
+ {
+ tm_sched_key.id = p_tm_queue_inst->api_req_tm_queue_info.key.sched_id;
+ tm_sched_key.dir= p_tm_queue_inst->api_req_tm_queue_info.key.sched_dir;
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not find an active tm sched (dir = %s id = %d) to attach the queue (id = %d)\n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id,p_tm_queue_inst->api_req_tm_queue_info.key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ ret = bcmbal_tm_sched_queues_list_entry_add(p_tm_sched_inst, p_tm_queue_inst->api_req_tm_queue_info.key);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not add the queue entry to the sched\n");
+ break;
+ }
+ if(TM_SCHED_FSM_STATE_ACTIVE == p_tm_sched_inst->fsm_state)
+ {
+ if(BCM_ERR_OK != (ret = bcmbal_tm_queue_activate(p_tm_queue_inst)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not activate the newly added queue \n");
+ break;
+ }
+ }
+ }while(0);
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_sched_remove_queue(tm_queue_inst *p_tm_queue_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ bcmbal_tm_sched_key tm_sched_key;
+ BUG_ON(NULL == p_tm_queue_inst);
+ do
+ {
+ tm_sched_key.id = p_tm_queue_inst->api_req_tm_queue_info.key.sched_id;
+ tm_sched_key.dir= p_tm_queue_inst->api_req_tm_queue_info.key.sched_dir;
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+
+ if(NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not find an active tm sched (dir = %s id = %d) to attach the queue (id = %d)\n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id,p_tm_queue_inst->api_req_tm_queue_info.key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ if(BCM_ERR_OK != (ret = bcmbal_tm_sched_queues_list_entry_remove(p_tm_sched_inst, p_tm_queue_inst->api_req_tm_queue_info.key)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "ERROR - could not remove the queue entry from the sched\n");
+ break;
+ }
+
+ }while(0);
+ return ret;
+}
+
+/*tm_sched_find_by_owner - currently might be called for agg port and uni port only*/
+static tm_sched_inst* tm_sched_find_by_owner(bcmbal_tm_sched_owner owner)
+{
+ tm_sched_inst *current_entry = NULL;
+
+ TAILQ_FOREACH(current_entry,
+ &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
+ tm_sched_inst_next)
+ {
+ if(BCMBAL_CFG_PROP_IS_SET(¤t_entry->req_tm_sched_info, tm_sched,owner))
+ {
+ switch(current_entry->req_tm_sched_info.data.owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ if((owner.u.agg_port.intf_id == current_entry->req_tm_sched_info.data.owner.u.agg_port.intf_id)
+ && (owner.u.agg_port.agg_port_id == current_entry->req_tm_sched_info.data.owner.u.agg_port.agg_port_id))
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched, "Found active tm_sched dir = us id= %d for agg_port_id %d intf_id %d\n",
+ current_entry->req_tm_sched_info.key.id, owner.u.agg_port.agg_port_id, owner.u.agg_port.intf_id);
+ return current_entry;
+ }
+ }
+ break;
+
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ if((owner.u.uni.intf_id == current_entry->req_tm_sched_info.data.owner.u.uni.intf_id)
+ && (owner.u.uni.sub_term_id == current_entry->req_tm_sched_info.data.owner.u.uni.sub_term_id)
+ && (owner.u.uni.idx == current_entry->req_tm_sched_info.data.owner.u.uni.idx))
+ {
+ BCM_LOG(DEBUG, log_id_tm_sched, "Found active tm_sched id = %d for uni intf_id = %d sub_id = %d uni_id = %d\n",
+ current_entry->req_tm_sched_info.key.id, owner.u.uni.intf_id, owner.u.uni.sub_term_id, owner.u.uni.idx);
+ return current_entry;
+ }
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ return current_entry;
+}
+
+tm_sched_inst* tm_sched_find_agg_port_node(uint8_t intf_id, bcmbal_aggregation_port_id agg_port_id)
+{
+ bcmbal_tm_sched_owner owner;
+ owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
+ owner.u.agg_port.intf_id = intf_id;
+ owner.u.agg_port.agg_port_id = agg_port_id;
+
+ return tm_sched_find_by_owner(owner);
+}
+
+
+
+static bcmos_errno tm_sched_fsm_assigned_process_util_msg(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
+{
+
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_tm_sched_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ " Received a IND message from BAL UTIL (%s) during %s state\n",
+ subsystem_str[bcmbal_sender_get(msg)],
+ tm_sched_state_name_get(p_tm_sched_inst->fsm_state));
+
+ /* Handle response */
+ ret = ind_msg->status;
+
+ if(BCM_ERR_OK == ret)
+ {
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ACTIVE;
+ bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->current_tm_sched_info,
+ &p_tm_sched_inst->req_tm_sched_info);
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed in state %s;%s\n",
+ tm_sched_state_name_get(p_tm_sched_inst->fsm_state),
+ bcmos_strerror(ret));
+ }
+
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&p_tm_sched_inst->current_tm_sched_info.hdr,
+ log_id_tm_sched);
+
+ return ret;
+}
+
+/*currently handling util msg of alloc id setting complete only for agg port tm sched only*/
+static bcmos_errno tm_sched_fsm_deleting_process_util_msg(tm_sched_inst *p_tm_sched_inst,
+ void *msg,
+ tm_sched_fsm_event *p_event)
+{
+ bcmos_errno ret;
+ bal_util_msg_ind *ind_msg;
+
+ /* Parameter checks */
+ BUG_ON(NULL == p_tm_sched_inst);
+ BUG_ON(NULL == msg);
+ BUG_ON(NULL == p_event);
+
+ do
+ {
+ ind_msg = (bal_util_msg_ind *)msg;
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ " Received a IND message from BAL UTIL (%s) during %s state\n",
+ subsystem_str[bcmbal_sender_get(msg)],
+ tm_sched_state_name_get(p_tm_sched_inst->fsm_state));
+
+ /* Handle response */
+ ret = ind_msg->status;
+
+ if(BCM_ERR_OK == ret)
+ {
+ ret = tm_sched_fsm_destroy(p_tm_sched_inst);
+ }
+ else
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed in state %s;%s\n",
+ tm_sched_state_name_get(p_tm_sched_inst->fsm_state),
+ bcmos_strerror(ret));
+ }
+ }while(0);
+ return ret;
+}
+
+static bcmos_errno tm_sched_fsm_destroy(tm_sched_inst *p_tm_sched_inst)
+{
+ queue_entry *current_entry = NULL;
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_queue_key tm_queue_key;
+ tm_queue_inst *p_tm_queue_inst;
+ int i=0;
+ bcmbal_tm_sched_owner owner;
+
+ do
+ {
+ switch(p_tm_sched_inst->req_tm_sched_info.data.owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_NULL;
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+
+ ret = rsc_mgr_alloc_id_free(owner.u.agg_port.intf_id, owner.u.agg_port.agg_port_id, NULL);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to free alloc id if=%d id=%d at resource manager",
+ owner.u.agg_port.intf_id, owner.u.agg_port.agg_port_id);
+ break;
+ }
+ ret = tm_sched_fsm_destroy(p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to free auto created tm sched id, id=%d at resource manager",
+ p_tm_sched_inst->req_tm_sched_info.key.id);
+ break;
+ }
+ break;
+ }
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
+ tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
+
+ /*delete all attached queues*/
+ TAILQ_FOREACH(current_entry,
+ &p_tm_sched_inst->queues_list,
+ next)
+ {
+
+ BCM_LOG(DEBUG, log_id_tm_sched,
+ "deleting queue %u (location %u)\n",
+ current_entry->queue_id,
+ i);
+ tm_queue_key.id = current_entry->queue_id;
+
+ p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_ACTIVE);
+ if(NULL == p_tm_queue_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,"ERROR - tm queue not found. No further processing\n");
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ ret = bcmbal_tm_queue_destroy(p_tm_queue_inst, BCMOS_FALSE);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,"ERROR - could not destroy tm queue %d .No further processing\n",
+ tm_queue_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ bcmos_free(current_entry);
+ i++;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ if(p_tm_sched_inst->req_tm_sched_info.data.creation_mode == BCMBAL_TM_CREATION_MODE_AUTO)
+ {
+ ret = _rsc_mgr_tm_sched_auto_id_free(p_tm_sched_inst->req_tm_sched_info.key.id);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to free auto created tm sched id, id=%d at resource manager ",
+ p_tm_sched_inst->req_tm_sched_info.key.id);
+ break;
+ }
+ }
+
+ mgmt_msg_send_balapi_ind(ret,
+ (void *)&p_tm_sched_inst->req_tm_sched_info.hdr,
+ log_id_tm_sched);
+
+ ret = tm_sched_free_by_entry(p_tm_sched_inst);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "Failed to free tm sched id=%d dir = %s",p_tm_sched_inst->req_tm_sched_info.key.id,
+ TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir));
+ break;
+ }
+ }while(0);
+ return ret;
+
+}
+
+static bcmos_errno tm_sched_fsm_inactive_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
+{
+ return tm_sched_fsm_destroy(p_tm_sched_inst);
+}
+
+static bcmos_errno tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
+{
+ return bcmbal_tm_sched_fsm_active_destroy(p_tm_sched_inst);
+}
+
+static bcmos_errno tm_sched_fsm_assigned_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
+{
+ bcmos_errno ret = bcmbal_tm_sched_fsm_active_destroy(p_tm_sched_inst);
+ if (BCM_ERR_OK == ret)
+ ret = tm_sched_fsm_destroy(p_tm_sched_inst);
+
+ return ret;
+
+}
+bcmos_errno bcmbal_tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_owner owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ bcmbal_interface_key intf_key;
+
+
+ switch(owner.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ uint32_t ref_count;
+ ret = rsc_mgr_alloc_id_get_ref_count(p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.intf_id,
+ p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.agg_port_id, &ref_count);
+ if(1!= ref_count)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "Cant destroy tm sched owned by agg port (if %d id %d) "
+ "with reference count %d (greated than 1)\n",
+ p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.intf_id,
+ p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.agg_port_id, ref_count);
+ ret = BCM_ERR_INTERNAL;
+ break;
+
+ }
+ ret = mac_util_agg_port_set(p_tm_sched_inst, BAL_UTIL_OPER_AGG_PORT_REMOVE);
+ if(BCM_ERR_OK != ret)
+ {
+ /* An error has occurred trying to configure mac*/
+ BCM_LOG(ERROR, log_id_tm_sched, "Failed to remove ALLOC ID at mac (%s)\n",bcmos_strerror(ret));
+ break;
+ }
+ else
+ {
+ p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_DELETING;
+ }
+ break;
+ }
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ /*remove the setting of the sched from the owner configuration*/
+ intf_key.intf_type = owner.u.interface.intf_type;
+ intf_key.intf_id = owner.u.interface.intf_id;
+ ret = interface_tm_sched_unset(intf_key, p_tm_sched_inst->req_tm_sched_info.key);
+ tm_sched_fsm_destroy(p_tm_sched_inst);
+ break;
+ }
+
+ default:
+ break;
+ }
+ return ret;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to set an interface as a tm sched owner
+ *
+ * @param interface_key the interface to become the owner
+ * @param p_tm_sched_inst the tm sched instance to be set
+ *
+ * @returns bcmos_errno
+ *****************************************************************************/
+bcmos_errno bcmbal_tm_sched_set_interface_owner(bcmbal_interface_key interface_key, tm_sched_inst *p_tm_sched_inst)
+{
+ BUG_ON(NULL == p_tm_sched_inst);
+
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_tm_sched_owner owner;
+ do
+ {
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
+ {
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ if (BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE!= owner.type )
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "tm sched %s%d is already assigned with an owner of type %d",
+ p_tm_sched_inst->current_tm_sched_info.key.dir == BCMBAL_TM_SCHED_DIR_US ? "us" : "ds",
+ p_tm_sched_inst->current_tm_sched_info.key.id, owner.type );
+ break;
+ }
+ if(owner.u.interface.intf_type != interface_key.intf_type
+ || owner.u.interface.intf_id != interface_key.intf_id)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched, "tm sched %s%d is already assigned with an interface owner",
+ p_tm_sched_inst->current_tm_sched_info.key.dir == BCMBAL_TM_SCHED_DIR_US ? "us" : "ds",
+ p_tm_sched_inst->current_tm_sched_info.key.id);
+
+ ret = BCM_ERR_ALREADY;
+ break;
+ }
+ }
+ else
+ {
+ owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE;
+ owner.u.interface.intf_type = interface_key.intf_type;
+ owner.u.interface.intf_id = interface_key.intf_id;
+ BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
+ ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst);
+ }
+ }while(0);
+ return ret;
+}
+
+#define BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES 4
+#define BCMBAL_INTERFACE_DEFAULT_SCHED_TYPE BCMBAL_TM_SCHED_TYPE_SP_WFQ
+#define BCMBAL_INTERFACE_DEFAULT_SCHED_CHILD_TYPE BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE
+
+#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_SIZE 128
+#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_SBR 128
+#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_PBR 128
+#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_BURST_SIZE 128
+
+bcmos_errno bcmbal_tm_sched_interface_tm_auto_create(bcmbal_interface_cfg *p_interface_info)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst = NULL;
+ bcmbal_tm_sched_cfg tm_sched_default_cfg;
+ bcmbal_tm_queue_cfg tm_queue_default_cfg;
+ bcmbal_tm_shaping default_shaping;
+ bcmbal_tm_sched_key tm_sched_key;
+ bcmbal_tm_queue_key tm_queue_key;
+ int i;
+
+ do
+ {
+ /*create the auto tm sched*/
+ tm_sched_key.dir = p_interface_info->key.intf_type == BCMBAL_INTF_TYPE_PON ? BCMBAL_TM_SCHED_DIR_DS : BCMBAL_TM_SCHED_DIR_US;
+ BCMBAL_CFG_INIT(&tm_sched_default_cfg, tm_sched, tm_sched_key);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, sched_type, BCMBAL_INTERFACE_DEFAULT_SCHED_TYPE);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, sched_child_type, BCMBAL_INTERFACE_DEFAULT_SCHED_CHILD_TYPE);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, num_priorities, BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, creation_mode, BCMBAL_TM_CREATION_MODE_AUTO);
+
+ if (BCM_ERR_OK != (ret = bcmbal_tm_sched_auto_create(tm_sched_default_cfg, &p_tm_sched_inst)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,"Could not create the auto tm sched \n");
+ break;
+ }
+ if (tm_sched_key.dir == BCMBAL_TM_SCHED_DIR_US)
+ {
+ BCMBAL_CFG_PROP_SET(p_interface_info, interface, us_tm, p_tm_sched_inst->req_tm_sched_info.key.id);
+ }
+ else
+ {
+ BCMBAL_CFG_PROP_SET(p_interface_info, interface, ds_tm, p_tm_sched_inst->req_tm_sched_info.key.id);
+ }
+
+ /*SET THE DEFAULT ATTRIBUTES FOR AUTO CREATED QUEUE*/
+ tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
+ tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
+ default_shaping.sbr = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_SBR;
+ default_shaping.pbr = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_PBR;
+ default_shaping.burst = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_BURST_SIZE;
+ BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, rate, default_shaping);
+ BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_AUTO);
+
+ /*create its queues*/
+ for(i=0; i<BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES; i++)
+ {
+ tm_queue_key.id = i;
+ BCMBAL_CFG_INIT(&tm_queue_default_cfg, tm_queue, tm_queue_key);
+
+ BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, priority, i);
+ BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, rate, default_shaping);
+ if (BCM_ERR_OK != (ret = bcmbal_tm_queue_auto_create(tm_queue_default_cfg)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,"Could not create the %d tm queue\n", i);
+ break;
+ }
+ }
+
+ ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
+
+ }while(0);
+
+ return ret;
+}
+
+bcmos_errno bcmbal_tm_sched_set_sub_term_owner( bcmbal_tm_sched_key tm_sched_key, const bcmbal_subscriber_terminal_cfg *p_sub_term_cfg)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ tm_sched_inst *p_tm_sched_inst;
+ bcmbal_tm_sched_owner owner;
+
+ do
+ {
+ p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
+ if (NULL == p_tm_sched_inst)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "tm sched dir = %s id = %d which is set as the subscriber tm does not exist \n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
+ {
+ /*check if it is already owned by that sub term*/
+ owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
+ if (owner.type != BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "tm sched dir = %s id = %d which is set as the subscriber tm already owned with owner type %d\n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id, owner.type);
+ ret = BCM_ERR_PARM;
+ break;
+
+ }
+ if (owner.u.sub_term.intf_id != p_sub_term_cfg->key.intf_id
+ || owner.u.sub_term.sub_term_id != p_sub_term_cfg->key.sub_term_id)
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "tm sched dir = %s id = %d which is set as the subscriber tm already owned by sub_term intf_id = %d sub_term_id = %d\n",
+ TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id, owner.u.sub_term.intf_id, owner.u.sub_term.sub_term_id);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else
+ {
+ owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM;
+ owner.u.sub_term.intf_id = p_sub_term_cfg->key.intf_id;
+ owner.u.sub_term.sub_term_id = p_sub_term_cfg->key.sub_term_id;
+ BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
+
+ if (BCM_ERR_OK!= (ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst)))
+ {
+ BCM_LOG(ERROR, log_id_tm_sched,
+ "could not set sub term intf_id = %d sub_term_id = %d as the owner of tm sched dir = %s id = %d which is set as the subscriber tm \n",
+ owner.u.sub_term.intf_id, owner.u.sub_term.sub_term_id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
+ break;
+ }
+ }
+ }while (0);
+ return ret;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/main/tm_sched_fsm.h b/bal_release/src/core/main/tm_sched_fsm.h
new file mode 100644
index 0000000..ea39a4f
--- /dev/null
+++ b/bal_release/src/core/main/tm_sched_fsm.h
@@ -0,0 +1,156 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file tm_sched_fsm.h
+ * @brief Code to support the BAL TM Sched FSM
+ *
+ */
+
+#ifndef TM_SCHED_FSM_H
+#define TM_SCHED_FSM_H
+
+/*@{*/
+
+#include <bcmos_system.h>
+#include <bal_api.h>
+#include <tm_queue_fsm.h>
+
+/* set the total pool size of available tm sched instances to 4k */
+#define TM_SCHED_ALLOCATION_BLOCK_SIZE (4096)
+
+typedef enum
+{
+ TM_SCHED_FSM_EVENT_TYPE_NONE = -1,
+ TM_SCHED_FSM_EVENT_TYPE_CREATE ,
+ TM_SCHED_FSM_EVENT_TYPE_DESTROY ,
+ TM_SCHED_FSM_EVENT_TYPE_ASSIGN ,
+ TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG ,
+
+ TM_SCHED_FSM_EVENT_TYPE__LAST,
+ TM_SCHED_FSM_EVENT_TYPE__NUM_OF
+} tm_sched_fsm_event_type;
+
+
+
+typedef enum
+{
+ TM_SCHED_FSM_STATE_NONE = -1,
+ TM_SCHED_FSM_STATE_NULL ,
+ TM_SCHED_FSM_STATE_INACTIVE ,
+ TM_SCHED_FSM_STATE_ASSIGNED ,
+ TM_SCHED_FSM_STATE_ACTIVE ,
+ TM_SCHED_FSM_STATE_DELETING ,
+
+ TM_SCHED_FSM_STATE__LAST,
+ TM_SCHED_FSM_STATE__NUM_OF
+} tm_sched_fsm_state;
+
+
+typedef enum
+{
+ TM_SCHED_FLAG_ACTIVE = 1<<0, /**< A tm_sched is on the active list */
+ TM_SCHED_FLAG_FREE = 1<<1, /**< A tm_sched is on the free list */
+ TM_SCHED_FLAG_ANY = (TM_SCHED_FLAG_ACTIVE | TM_SCHED_FLAG_FREE), /**< A tm_sched is on either the active or free list */
+} tm_sched_flag;
+
+
+typedef struct tm_sched_fsm_event_t
+{
+ tm_sched_fsm_event_type event_type; /**< The tm_sched fsm events */
+ void *msg;
+
+ /* other necessary information */
+} tm_sched_fsm_event;
+
+typedef struct queue_entry
+{
+ bcmbal_tm_queue_id queue_id;
+ TAILQ_ENTRY(queue_entry) next; /**< TAILQ link */
+}queue_entry;
+
+typedef struct sub_sched_entry
+{
+ bcmbal_tm_sched_id sched_id;
+ TAILQ_ENTRY(sub_sched_entry) next; /**< TAILQ link */
+}sub_sched_entry;
+
+typedef struct tm_sched_inst tm_sched_inst;
+struct tm_sched_inst
+{
+ bcmbal_tm_sched_cfg current_tm_sched_info; /**< The current information for this tm_sched (used for GET) */
+ bcmbal_tm_sched_cfg req_tm_sched_info; /**< The last tm_sched object info received from the Public API */
+ uint16_t num_queues_on_node; /**< The number of queues attached to this node */
+ TAILQ_HEAD(queues_list_head, queue_entry) queues_list;
+ uint16_t num_sub_scheds_on_node; /**< The number of sub schedulers for this tm sched */
+ TAILQ_HEAD(sub_scheds_list_head, sub_sched_entry) sub_scheds_list;
+ tm_sched_fsm_state fsm_state; /**< The tm_sched FSM state */
+ TAILQ_ENTRY(tm_sched_inst) tm_sched_inst_next; /**< TAILQ link */
+};
+
+
+/*
+ * Group FSM data structures
+ */
+typedef struct tm_sched_fsm_ctx
+{
+ /* Lists of free tm_sched entries and active tm_sched entries
+ */
+ TAILQ_HEAD(free_tm_sched_list_head, tm_sched_inst) free_tm_sched_list;
+
+ TAILQ_HEAD(active_tm_sched_list_head, tm_sched_inst) active_tm_sched_list;
+
+} tm_sched_fsm_ctx;
+
+
+/* Function declarations */
+
+extern bcmos_errno tm_sched_fsm_init(void);
+extern bcmos_errno tm_sched_fsm_finish(void);
+extern bcmos_errno process_tm_sched_util_msg(void *msg_payload);
+extern bcmos_errno process_tm_sched_object(void *msg_payload);
+
+tm_sched_inst *tm_sched_inst_get(bcmbal_tm_sched_key key, tm_sched_flag search_flag);
+bcmos_errno bcmbal_tm_sched_auto_create(bcmbal_tm_sched_cfg cfg, tm_sched_inst **p_tm_sched_inst);
+bcmos_errno bcmbal_tm_sched_set_owner(tm_sched_inst *p_tm_sched_inst);
+bcmos_errno bcmbal_tm_sched_unset_owner(tm_sched_inst *p_tm_sched_inst);
+bcmos_errno bcmbal_tm_sched_set_queue(tm_queue_inst *p_tm_queue_inst);
+bcmos_errno bcmbal_tm_sched_remove_queue(tm_queue_inst *p_tm_queue_inst);
+tm_sched_inst * tm_sched_find_agg_port_node(uint8_t intf_id, bcmbal_aggregation_port_id agg_port_id);
+bcmos_errno bcmbal_tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst);
+
+
+
+#define TM_SCHED_DIR_TO_STR(dir) ((dir) == BCMBAL_TM_SCHED_DIR_DS ? "ds" : "us")
+/*@}*/
+
+#endif /*TM_SCHED_FSM_H */
+
diff --git a/bal_release/src/core/platform/bcmos_platform.h b/bal_release/src/core/platform/bcmos_platform.h
new file mode 100644
index 0000000..a2e95b4
--- /dev/null
+++ b/bal_release/src/core/platform/bcmos_platform.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef BCMOS_PLATFORM_H_
+#define BCMOS_PLATFORM_H_
+
+#ifndef BCMOS_SYSTEM_H_
+#error Please do not include bcmos_platform.h directly. Include bcmos_system.h
+#endif
+
+#include <bal_osmsg.h>
+
+/** BAL CORE CPU core
+ * \ingroup system_task */
+typedef enum
+{
+ BCMOS_CPU_CORE_ANY, /**< Any core */
+
+ BCMOS_CPU_CORE__NUM_OF = 1, /**< Number of cores */
+} bcmos_core;
+
+/*
+ * BAL CORE modules
+ *
+ * \ingroup system_module
+ */
+typedef enum
+{
+ BCMOS_MODULE_ID_NONE, /**< no module */
+
+ BCMOS_MODULE_ID_WORKER_MGMT, /** worker module for MGMT message handling */
+ BCMOS_MODULE_ID_WORKER_API_IND, /** worker module for BAL API INDICATION message handling */
+ BCMOS_MODULE_ID_WORKER_BAL_CORE_FOR_AGENT, /** worker module for the BAL CORE when running as an OF agent */
+ BCMOS_MODULE_ID_USER_APPL_EON, /** EON module */
+ BCMOS_MODULE_ID_USER_APPL_EPON_OAM, /** EPON OAM module */
+ BCMOS_MODULE_ID_OFPAL, /** OF-PAL module */
+ BCMOS_MODULE_ID_OMCI_TRANSPORT, /** OMCI Transport module */
+
+ BCMOS_MODULE_ID__NUM_OF, /**< Number of modules */
+ BCMOS_MODULE_ID_INVALID = BCMOS_MODULE_ID_NONE
+} bcmos_module_id;
+
+/*
+ * BAL CORE event group. Each group supports up to 32 events.
+ *
+ * \ingroup system_event
+ */
+typedef enum
+{
+ BCMOS_EVENT_FIRST,
+
+ BCMOS_EVENT_ID__NUM_OF, /**< Number of event groups */
+} bcmos_event_id;
+
+/** Message hash size
+ * \ingroup system_msg
+ */
+#define BCMOS_MSG_HASH_SIZE 512
+
+/*
+ * Task priorities
+ */
+#define TASK_PRIORITY_IPC_RX BCMOS_TASK_PRIORITY_3
+#define TASK_PRIORITY_CLI BCMOS_TASK_PRIORITY_15
+#define TASK_PRIORITY_WORKER BCMOS_TASK_PRIORITY_16
+#define TASK_PRIORITY_USER_APPL_EON BCMOS_TASK_PRIORITY_17
+#define TASK_PRIORITY_OFPAL BCMOS_TASK_PRIORITY_18
+#define TASK_PRIORITY_OMCI_TRANSPORT BCMOS_TASK_PRIORITY_20
+#define TASK_PRIORITY_DEV_LOG BCMOS_TASK_PRIORITY_30
+
+#endif /* BCMOS_PLATFORM_H_ */
diff --git a/bal_release/src/core/util/mac/Makefile b/bal_release/src/core/util/mac/Makefile
new file mode 100644
index 0000000..8594d20
--- /dev/null
+++ b/bal_release/src/core/util/mac/Makefile
@@ -0,0 +1,43 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL core CLI application
+#
+MOD_NAME = bal_mac_util
+MOD_TYPE = lib
+MOD_DEPS = dev_log utils maple_sdk os_cli bal_api bal_app_utils balutils topology
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../main
+
+srcs = bal_mac_util.c bal_mac_util_gpon.c bal_mac_util_xgpon.c bal_mac_util_common_itu_pon.c bal_mac_util_db_apis.c bal_mac_util_loopback.c bal_mac_util_epon.c
+
+ifeq ("$(SWITCH)", "qax")
+ MOD_DEFS += -DQAX_SWITCH
+endif
+
diff --git a/bal_release/src/core/util/mac/bal_mac_util.c b/bal_release/src/core/util/mac/bal_mac_util.c
new file mode 100644
index 0000000..3824996
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util.c
@@ -0,0 +1,2467 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util.c
+ *
+ * @brief mac util interfaces definition used by Bal Core
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_common_itu_pon.h>
+#include <bal_mac_util_epon.h>
+
+#include <bal_worker.h>
+#include <bal_core.h>
+#include <bal_cli.h>
+
+#ifdef BOARD
+#include <bcmolt_board.h>
+#include <bcmolt_board_cli.h>
+#endif
+#include <bcm_api_cli.h>
+#include <bcmolt_dev_selector.h>
+#include <bcmolt_host_sw_version.h>
+#include <bcmolt_model_revision.h>
+
+#ifdef ENABLE_LOG
+
+#define INBOLD_BAD(a) "\033[31m"a"\033[0m"
+/*
+ * mac util logging for generic logging, as well as on per PON basis
+ */
+dev_log_id log_id_mac_util;
+dev_log_id log_id_mac_util_pon_if[NUM_SUPPORTED_SUBSCRIBER_INTERFACES];
+
+/** @def size of log Id string */
+#define MAC_UTIL_LOG_STR_SZ 64
+
+/** @def to make a log string for a PON interface, to register with logging module during initialization */
+#define MAC_UTIL_MAKE_LOG_STR_FOR_PON_IF(_pon_if_id, _buf, _buf_sz) \
+ do \
+ { \
+ int n = 0; \
+ n = snprintf((_buf), (_buf_sz), "MAC_UTIL_PON_%d", (_pon_if_id)); \
+ BUG_ON((0 > n) || ((_buf_sz) <= n)); \
+ } while (0); \
+
+static bcmos_errno mac_util_register_logging_per_pon (void);
+#endif //ENABLE_LOG
+
+/* This is not exposed in the object model, so we can use BCMOLT_SYSTEM_MODE__NUM_OF as a special value for loopback. */
+#define BCMOLT_SYSTEM_MODE_LOOPBACK BCMOLT_SYSTEM_MODE__NUM_OF
+#define BCM_TOPO_PON_MODE_LOOPBACK BCM_TOPO_PON_MODE__NUM_OF
+
+static bcmos_errno mac_util_indication_handle_for_device (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_system_mode_get(bcmolt_devid device_id);
+
+/* Maple CLI directory */
+static bcmcli_entry *maple_dir;
+
+/** @brief array stores the list of device related auto indications from Maple to subscribe */
+static mac_util_ind_obj_and_handlers mac_util_device_ind_handlers[] =
+{
+ {BCMOLT_OBJ_ID_DEVICE, "BCMOLT_OBJ_ID_DEVICE", mac_util_indication_handle_for_device}
+};
+
+
+
+#if !defined(WRX_BUILD)
+/* external structures to be used with bcmos_tr
+ * specifying IP:Port assignments of the remote mac device */
+extern uint32_t bcmtr_olt_ip[BCMTR_MAX_OLTS];
+extern uint16_t bcmtr_olt_udp_port[BCMTR_MAX_OLTS];
+extern uint16_t bcmtr_host_udp_port;
+#endif
+
+
+
+/**
+ * @brief BAL request handlers for system mode specific set & validate
+ **/
+static mac_util_bal_req_handlers_for_system_mode_t mac_util_bal_req_handlers_for_system_mode[] =
+{
+ [BCMOLT_SYSTEM_MODE_GPON__16_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_gpon_16,
+ .acc_term_post_indication_set = mac_util_access_terminal_post_indication_set_for_gpon
+ },
+ [BCMOLT_SYSTEM_MODE_GPON__8_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_gpon_8,
+ .acc_term_post_indication_set = mac_util_access_terminal_post_indication_set_for_gpon
+ },
+ [BCMOLT_SYSTEM_MODE_XGPON_1__8_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_xgpon_8,
+ .acc_term_post_indication_set = mac_util_access_terminal_post_indication_set_for_xgpon_xgs
+ },
+ [BCMOLT_SYSTEM_MODE_XGS__2_X_10_G] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_xgs,
+ .acc_term_post_indication_set = mac_util_access_terminal_post_indication_set_for_xgpon_xgs
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_8_tdma,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_4_tdma,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__16_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_16_1g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__8_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_8_1g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__4_X] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_4_1g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__8_X_10_G] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_8_10g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__4_X_10_G] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_4_10g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_EPON__2_X_10_G] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_epon_2_10g,
+ .acc_term_post_indication_set = NULL
+ },
+ [BCMOLT_SYSTEM_MODE_LOOPBACK] =
+ {
+ .acc_term_set = mac_util_access_terminal_set_for_loopback,
+ .acc_term_post_indication_set = NULL
+ }
+};
+
+/**
+ * @brief BAL request handlers for PON protocol specific set & validate
+ *
+ * @note The handling would be like object-oriented programming. The common
+ * handling would be done in the top level call. And then based on protocol,
+ * the mac specific handling will be done in the corresponding mac specific
+ * handler functions.
+ **/
+mac_util_handlers_per_pon_mode_t mac_util_bal_req_handlers_for_pon_mode [BCM_TOPO_PON_MODE__NUM_OF + 1] =
+{
+ [BCM_TOPO_PON_MODE_GPON] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_gpon,
+ .sub_term_validate = mac_util_validate_subscriber_terminal_info_for_gpon,
+ .sub_term_set = mac_util_subscriber_terminal_set_for_gpon,
+ .flow_validate = mac_util_validate_flow_info_for_gpon,
+ .flow_set = mac_util_flow_set_for_gpon,
+ .group_validate = NULL,
+ .group_set = mac_util_group_set_for_gpon,
+ .sla_us_rate_factor = 1
+ },
+ [BCM_TOPO_PON_MODE_XGPON] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_xgpon,
+ .sub_term_validate = mac_util_validate_subscriber_terminal_info_for_xgpon,
+ .sub_term_set = mac_util_subscriber_terminal_set_for_xgpon,
+ .flow_validate = mac_util_validate_flow_info_for_xgpon,
+ .flow_set = mac_util_flow_set_for_xgpon,
+ .group_validate = NULL,
+ .group_set = mac_util_group_set_for_xgpon,
+ .sla_us_rate_factor = 2
+ },
+ [BCM_TOPO_PON_MODE_XGS] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_xgpon,
+ .sub_term_validate = mac_util_validate_subscriber_terminal_info_for_xgpon,
+ .sub_term_set = mac_util_subscriber_terminal_set_for_xgpon,
+ .flow_validate = mac_util_validate_flow_info_for_xgpon,
+ .flow_set = mac_util_flow_set_for_xgpon,
+ .group_validate = NULL,
+ .group_set = mac_util_group_set_for_xgpon,
+ .sla_us_rate_factor = 8
+ },
+ [BCM_TOPO_PON_MODE_EPON_TDMA] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_epon,
+ .sub_term_validate = NULL,
+ .sub_term_set = NULL,
+ .flow_validate = NULL,
+ .flow_set = NULL,
+ .group_validate = NULL,
+ .group_set = NULL,
+ .sla_us_rate_factor = 0
+ },
+ [BCM_TOPO_PON_MODE_EPON_1G] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_epon,
+ .sub_term_validate = NULL,
+ .sub_term_set = NULL,
+ .flow_validate = NULL,
+ .flow_set = NULL,
+ .group_validate = NULL,
+ .group_set = NULL,
+ .sla_us_rate_factor = 0
+ },
+ [BCM_TOPO_PON_MODE_EPON_10G] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_epon,
+ .sub_term_validate = NULL,
+ .sub_term_set = NULL,
+ .flow_validate = NULL,
+ .flow_set = NULL,
+ .group_validate = NULL,
+ .group_set = NULL,
+ .sla_us_rate_factor = 0
+ },
+ [BCM_TOPO_PON_MODE_LOOPBACK] =
+ {
+ .if_validate = NULL,
+ .if_set = mac_util_interface_set_for_loopback,
+ .sub_term_validate = NULL,
+ .sub_term_set = mac_util_subscriber_terminal_set_for_loopback,
+ .flow_validate = NULL,
+ .flow_set = mac_util_flow_set_for_loopback,
+ .group_validate = NULL,
+ .group_set = NULL,
+ .sla_us_rate_factor = 1
+ }
+};
+
+static f_bcmolt_msg_handler g_indication_handler;
+
+static bcm_topo_pon_mode mac_util_get_pon_mode(uint32_t logical_intf_id)
+{
+ bcm_topo_pon_mode mode;
+ if (bcmbal_is_mac_in_loopback())
+ mode = BCM_TOPO_PON_MODE_LOOPBACK;
+ else
+ mode = bcm_topo_pon_get_pon_mode(logical_intf_id);
+ return mode;
+}
+
+static uint16_t oper_status_from_pon_state_get(uint32_t logical_intf_id, uint16_t state)
+{
+ uint16_t oper_status;
+ bcm_topo_pon_family pon_family;
+
+ pon_family = bcm_topo_pon_get_pon_family(logical_intf_id);
+
+ switch (pon_family)
+ {
+ case BCM_TOPO_PON_FAMILY_EPON:
+ oper_status = (((bcmolt_epon_ni_en_state)state == BCMOLT_EPON_NI_EN_STATE_ENABLED) ?
+ BAL_UTIL_OPER_IF_UP : BAL_UTIL_OPER_IF_DOWN);
+ break;
+
+ case BCM_TOPO_PON_FAMILY_GPON:
+ oper_status = (((bcmolt_pon_state)state == BCMOLT_PON_STATE_ACTIVE_WORKING) ?
+ BAL_UTIL_OPER_IF_UP : BAL_UTIL_OPER_IF_DOWN);
+ break;
+
+ case BCM_TOPO_PON_FAMILY_INVALID:
+ default:
+ BCMOS_TRACE_ERR("Unknown PON family on intf %u: %d\n", logical_intf_id, pon_family);
+ oper_status = BAL_UTIL_OPER_IF_DOWN;
+ break;
+ }
+
+ return oper_status;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Function to send a util indication message to the core
+ *
+ * @param msg_payload A pointer to a well formed MAC util indication message
+ *
+ * @returns bcmos_errno == BCM_ERR_OK
+ *
+ *****************************************************************************/
+static bcmos_errno mac_util_ind_send(bal_util_msg_ind *msg_payload)
+{
+ bcmos_errno rc;
+
+ rc = bcmos_msg_dispatch(bcmbal_bcmos_hdr_get(msg_payload), BCMOS_MSG_SEND_AUTO_FREE);
+
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Couldn't dispatch indication message from MAC util (%d:%d)\n",
+ (int)(bcmbal_bcmos_hdr_get(msg_payload))->type,
+ (int)(bcmbal_bcmos_hdr_get(msg_payload))->instance);
+ }
+
+ return rc;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Function to send a util auto indication message to the core
+ *
+ * @param msg_payload A pointer to a well formed MAC util indication message
+ *
+ * @returns bcmos_errno == BCM_ERR_OK
+ *
+ *****************************************************************************/
+static bcmos_errno mac_util_auto_ind_send(bal_util_msg_auto_ind *msg_payload)
+{
+ bcmos_errno rc;
+
+ rc = bcmos_msg_dispatch(bcmbal_bcmos_hdr_get(msg_payload), BCMOS_MSG_SEND_AUTO_FREE);
+
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Couldn't dispatch auto indication message from MAC util (%d:%d)\n",
+ (int)(bcmbal_bcmos_hdr_get(msg_payload))->type,
+ (int)(bcmbal_bcmos_hdr_get(msg_payload))->instance);
+ }
+
+ return rc;
+}
+
+/* Report acc_term event */
+void mac_util_report_acc_term_event(uint16_t event)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_ind))))
+ {
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+
+ /* device connect */
+ if (BCMOLT_DEVICE_AUTO_ID_CONNECTION_COMPLETE == event)
+ {
+ p_bal_util_ind_msg->status = BCM_ERR_OK;
+ }
+ else
+ {
+ p_bal_util_ind_msg->status = BCM_ERR_PARM;
+ }
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_ACCESS_TERMINAL,
+ BAL_UTIL_OPER_ACC_TERM_CONNECT,
+ 0);
+
+ BCM_LOG(INFO, log_id_mac_util, "Reporting to Core: BAL_UTIL_OPER_ACC_TERM_CONNECT indication. Status=%s\n",
+ bcmos_strerror(p_bal_util_ind_msg->status));
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Could not allocate memory for access-terminal IND message\n");
+ }
+}
+
+
+/**
+ * @brief Report interface event
+ * @note we consider both err and result for reporting the status to Core
+ * */
+void mac_util_report_if_event(bcmbal_intf_id intf_id,
+ bcmbal_intf_type intf_type,
+ bcmos_errno err,
+ bcmolt_result result,
+ bcmolt_pon_state new_state)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_ind))))
+ {
+
+ /** @todo validate inf_id is within range based on intf_type */
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+ p_bal_util_ind_msg->obj_key.if_key.intf_id = intf_id;
+ p_bal_util_ind_msg->obj_key.if_key.intf_type = intf_type;
+
+ if ((BCM_ERR_OK == err) && (BCMOLT_RESULT_SUCCESS != result))
+ {
+ err = BCM_ERR_INTERNAL;
+ }
+ p_bal_util_ind_msg->status = err;
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_INTERFACE,
+ oper_status_from_pon_state_get(intf_id, new_state),
+ 0);
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_id), "Reporting to Core: interface id %d %s indication: %s\n",
+ intf_id,
+ (BAL_UTIL_OPER_IF_UP == oper_status_from_pon_state_get(intf_id, new_state)) ? "UP" : "DOWN",
+ bcmos_strerror(p_bal_util_ind_msg->status));
+
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_id),
+ "Could not allocate memory for interface IND message\n");
+ }
+}
+
+/* Report subscriber terminal event */
+
+/**
+ * @note p_serial_number may be NULL and is only valid when an ONU
+ * is being reported as DISCOVERED
+ * @note result is config status reported by Maple, whereas err is messaging status
+ * between the MAC util & Maple
+ * */
+void mac_util_report_sub_term_event(bcmbal_intf_id pon_ni,
+ bcmbal_sub_id onu_id,
+ bcmolt_serial_number *p_serial_number,
+ bal_util_oper_sub_term oper,
+ bcmos_errno err,
+ bcmolt_result result,
+ bcmolt_activation_fail_reason fail_reason,
+ bcmolt_epon_tunnel_id tunnel_id)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+ uint16_t total_msglen;
+ bcm_topo_pon_family pon_family;
+
+ total_msglen = sizeof(bal_util_msg_ind);
+
+ pon_family = bcm_topo_pon_get_pon_family(pon_ni);
+ /**
+ * @note if pon mode is invalid then this error should have been caught in the validation stage itself.
+ * However, still checking here to make sure and report an error if needed.
+ */
+ if (pon_family == BCM_TOPO_PON_FAMILY_INVALID)
+ {
+ result = BCMOLT_RESULT_FAIL;
+ }
+
+ if (pon_family == BCM_TOPO_PON_FAMILY_EPON)
+ {
+ total_msglen += sizeof(bcmolt_epon_tunnel_id);
+ }
+ else if(NULL != p_serial_number)
+ {
+ total_msglen += sizeof(bcmbal_serial_number);
+ }
+
+
+ /* consolidate "err" and "result" into one report status */
+ if ((BCM_ERR_OK == err) && (BCMOLT_RESULT_SUCCESS != result))
+ {
+ err = BCM_ERR_INTERNAL;
+ }
+
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(total_msglen)))
+ {
+ /* set the object key */
+ p_bal_util_ind_msg->obj_key.sub_term_key.intf_id = pon_ni;
+ p_bal_util_ind_msg->obj_key.sub_term_key.sub_term_id = onu_id;
+
+ /* set bal util msg version */
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ (BAL_UTIL_OPER_SUB_TERM_DISCOVERY == oper) ? BAL_MSG_TYPE_AUTO_IND : BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL,
+ oper,
+ 0);
+
+ /*
+ * Set all the message header parameters
+ */
+ if ((BCM_ERR_OK == err) &&
+ (((BAL_UTIL_OPER_SUB_TERM_ADD == oper) && (fail_reason == BCMOLT_ACTIVATION_FAIL_REASON_NONE)) ||
+ ((BAL_UTIL_OPER_SUB_TERM_ADD != oper) && (fail_reason == MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE))) )
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_ni),
+ "Reporting to Core: %s "
+ "indication from mac util: Success\n",
+ (BAL_UTIL_OPER_SUB_TERM_ADD == oper) ? "BAL_UTIL_OPER_SUB_TERM_ADD" :
+ (BAL_UTIL_OPER_SUB_TERM_REMOVE == oper) ? "BAL_UTIL_OPER_SUB_TERM_REMOVE" :
+ "BAL_UTIL_OPER_SUB_TERM_DISCOVERY");
+
+ p_bal_util_ind_msg->status = BCM_ERR_OK;
+
+ if (pon_family == BCM_TOPO_PON_FAMILY_EPON)
+ {
+ memcpy(&p_bal_util_ind_msg->data, &tunnel_id, sizeof(bcmolt_epon_tunnel_id));
+ }
+ else if (NULL != p_serial_number)
+ {
+ /* This assumes an identical definition of serial number between BAL and MAPLE */
+ memcpy(&p_bal_util_ind_msg->data, p_serial_number, sizeof(bcmbal_serial_number));
+ }
+
+ }
+ else
+ {
+ p_bal_util_ind_msg->status = err;
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_ni),
+ "Reporting to Core: %s Indication from mac util: Failure, with status = %s, fail_reason = %d\n",
+ ((BAL_UTIL_OPER_SUB_TERM_ADD == oper) ? "BAL_UTIL_OPER_SUB_TERM_ADD" :
+ (BAL_UTIL_OPER_SUB_TERM_REMOVE == oper) ? "BAL_UTIL_OPER_SUB_TERM_REMOVE" :
+ "BAL_UTIL_OPER_SUB_TERM_DISCOVERY"),
+ bcmos_strerror(err), fail_reason);
+ }
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_ni),
+ "Could not allocate memory for subscriber-terminal IND message\n");
+ }
+}
+
+
+/**
+ * Notify core flow FSM that flow add/modify/remove was success or failed
+ *
+ * @param flow_key
+ * @param pon_if pon interface
+ * @param op_type ADD, REMOVE, MODIFY
+ * @param err error code to be sent up
+ *
+ **/
+static void _mac_util_report_flow_set_indication(bcmbal_flow_key flow_key, uint32_t pon_if, bal_util_oper_flow op_type, bcmos_errno err)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_ind))))
+ {
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "Reporting to Core: flow %d, %s %s, result=%s\n",
+ flow_key.flow_id,
+ (BCMBAL_FLOW_TYPE_UPSTREAM == flow_key.flow_type ? "upstream" :
+ BCMBAL_FLOW_TYPE_DOWNSTREAM == flow_key.flow_type ? "downstream" :
+ BCMBAL_FLOW_TYPE_MULTICAST == flow_key.flow_type ? "multicast" :"broadcast"),
+ (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW ADD":
+ (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW REMOVE" : "FLOW_CLEAR")),
+ bcmos_strerror(err));
+
+
+ /* set bal app p_msg version */
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+ p_bal_util_ind_msg->obj_key.flow_key = flow_key;
+ p_bal_util_ind_msg->status = err; /* set the error code */
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_FLOW,
+ op_type,
+ 0);
+
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "Could not allocate memory for flow IND message\n");
+ }
+}
+
+void mac_util_report_tm_sched_set_indication(bcmbal_tm_sched_key tm_sched_key, bcmos_errno err, bcmolt_result ind_result)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+
+ if ((BCM_ERR_OK == err) && (BCMOLT_RESULT_SUCCESS != ind_result))
+ {
+ err = BCM_ERR_INTERNAL;
+ }
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_ind))))
+ {
+
+ BCM_LOG(INFO, log_id_mac_util, "Reporting to Core: tm sched %d, %s, result=%s\n",
+ tm_sched_key.id,
+ (BCMBAL_TM_SCHED_DIR_US == tm_sched_key.dir ? "upstream" :"downstream"),
+ bcmos_strerror(err));
+
+
+ /* set bal app p_msg version */
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+ p_bal_util_ind_msg->obj_key.tm_sched_key = tm_sched_key;
+ p_bal_util_ind_msg->status = err; /* set the error code */
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_TM_SCHED,
+ BAL_UTIL_OPER_AGG_PORT_ADD,
+ 0);
+
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Could not allocate memory for tm sched IND message\n");
+ }
+}
+
+/**
+ * Notify core group FSM that group set request was success or failed
+ *
+ * @param group_key
+ * @param op_type ADD, REMOVE, SET, CREATE, DESTROY
+ * @param err error code to be sent up
+ *
+ **/
+static void _mac_util_report_group_set_indication (bcmbal_group_key group_key, bal_util_oper_group op_type, bcmos_errno err)
+{
+ bal_util_msg_ind *p_bal_util_ind_msg;
+
+ if(NULL != (p_bal_util_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_ind))))
+ {
+
+ BCM_LOG(INFO, log_id_mac_util, "Reporting to Core: group %d, %s, result=%s\n",
+ group_key.group_id,
+ BCMBAL_UTIL_GROUP_OPER_STR_GET(op_type),
+ bcmos_strerror(err));
+
+
+ /* set bal app p_msg version */
+ p_bal_util_ind_msg->version = BAL_UTIL_MSG_VERSION;
+ p_bal_util_ind_msg->obj_key.group_key = group_key;
+ p_bal_util_ind_msg->status = err; /* set the error code */
+
+ bcmbal_msg_hdr_set(p_bal_util_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_GROUP,
+ op_type,
+ 0);
+
+
+ mac_util_ind_send(p_bal_util_ind_msg);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Could not allocate memory for group IND message\n");
+ }
+}
+
+/**
+ * Notify core flow FSM that flow operational state was changed
+ *
+ * @param pon_if - the flow interface
+ * @param flow_key
+ * @param op_type - relevant flow latest operation
+ * @param ind - success/fail represent current flow state is up/down
+ *
+ **/
+
+void mac_util_report_flow_auto_ind (uint32_t pon_if, bcmbal_flow_key flow_key ,bal_util_oper_flow op_type, bal_util_flow_ind ind)
+{
+ bal_util_msg_auto_ind *p_bal_util_auto_ind_msg;
+
+ if(NULL != (p_bal_util_auto_ind_msg = bcmbal_msg_calloc(sizeof(bal_util_msg_auto_ind) + sizeof(bcmbal_status))))
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "Reporting to Core: flow %d, %s %s, change to %s\n",
+ flow_key.flow_id,
+ (BCMBAL_FLOW_TYPE_UPSTREAM == flow_key.flow_type ? "upstream" :
+ BCMBAL_FLOW_TYPE_DOWNSTREAM == flow_key.flow_type ? "downstream" :
+ BCMBAL_FLOW_TYPE_MULTICAST == flow_key.flow_type ? "multicast" :"broadcast"),
+ (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW ADD":
+ (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW REMOVE" : "FLOW_CLEAR")),
+ ind == BAL_UTIL_FLOW_IND_SEND_FAIL ? "fail" : "success");
+
+ /* set bal app p_msg version */
+ p_bal_util_auto_ind_msg->version = BAL_UTIL_MSG_VERSION;
+ p_bal_util_auto_ind_msg->obj_key.flow_key = flow_key;
+
+ /*data will indicate the new operational state*/
+ *(p_bal_util_auto_ind_msg->data) = ((ind == BAL_UTIL_FLOW_IND_SEND_FAIL) ? BCMBAL_STATUS_DOWN : BCMBAL_STATUS_UP);
+ p_bal_util_auto_ind_msg->status = BCM_ERR_OK;
+
+ bcmbal_msg_hdr_set(p_bal_util_auto_ind_msg,
+ BCMBAL_MAC_UTIL_MSG,
+ BAL_MSG_TYPE_AUTO_IND,
+ BAL_SUBSYSTEM_MAC_UTIL,
+ BCMBAL_OBJ_ID_FLOW,
+ op_type,
+ 0);
+
+ mac_util_auto_ind_send(p_bal_util_auto_ind_msg);
+ }
+}
+
+
+/** @brief Wrapper routine to Notify core flow FSM that flow ADD Success */
+void mac_util_report_flow_add_success(bcmbal_flow_key flow_key, uint32_t pon_if)
+{
+ _mac_util_report_flow_set_indication(flow_key, pon_if, BAL_UTIL_OPER_FLOW_ADD, BCM_ERR_OK);
+}
+
+/** @brief Wrapper routine to Notify core flow FSM that flow Add failed, based on result in indication msg from Maple */
+void mac_util_report_flow_add_failed(bcmbal_flow_key flow_key, uint32_t pon_if, bcmos_errno err)
+{
+ _mac_util_report_flow_set_indication(flow_key, pon_if, BAL_UTIL_OPER_FLOW_ADD, err);
+}
+
+/** @brief Wrapper routine to Notify core flow FSM that flow REMOVE is Success */
+void mac_util_report_flow_remove_success(bcmbal_flow_key flow_key, uint32_t pon_if, bal_util_oper_flow op_type)
+{
+ _mac_util_report_flow_set_indication(flow_key, pon_if, op_type, BCM_ERR_OK);
+}
+
+/** @brief Wrapper routine to Notify core flow FSM that flow Remove failed, based on result in indication msg from Maple */
+void mac_util_report_flow_remove_failed(bcmbal_flow_key flow_key, uint32_t pon_if, bal_util_oper_flow op_type, bcmos_errno err)
+{
+ _mac_util_report_flow_set_indication(flow_key, pon_if, op_type, err);
+}
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_access_terminal_info_validate
+ *
+ * This routine is used to validate all input attributes required for an acc term
+ * setting received from the core.
+ *
+ * @param p_acc_term_req the acc term request info
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_access_terminal_info_validate(const bcmbal_access_terminal_cfg *p_acc_term_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (BCMOS_TRUE != BCMBAL_CFG_PROP_IS_SET(p_acc_term_req, access_terminal, iwf_mode))
+ {
+ /*
+ * This is an error because the iwf mode is implicitly set by the core, based
+ * either on a parameter in the bal_config.txt file, or it is assigned a
+ * default value. Either way, this property must be set when this code
+ * executes.
+ */
+ rc = BCM_ERR_PARM;
+ }
+
+ return rc;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief check_send_flow_bal_ind_msg
+ * the routine checks the indication status of a specific given flow, which its entry was just updated
+ * As flows may be 'waiting' for a single of few maple gem port configuration complete indications
+ * before an indication of complete flow setup can be indicated to bal_core
+ *
+ * @note this send routine is called multiple times for the scenario multiple flows per GEM/Alloc Id.
+ *
+ * @todo this routine currently assumes just flow add. This should handle a flow Remove case too
+ *
+ * @param p_flow - flow instance pointer from mac util DB
+ * @param err - remote error in msg from Maple
+ * @param ind_result - the status(BCMOLT_RESULT_SUCCESS/BCMOLT_RESULT_FAIL) of indication from Maple
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno check_send_flow_bal_ind_msg (flow_list_entry *p_flow, bcmos_errno err, bcmolt_result ind_result)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmos_bool send_ind = BCMOS_TRUE;
+
+ /* for a ds flow, indication should be sent only if all constraints fulfilled:
+ indication was not sent yet
+ flow configuration completed - all related gem ports were configured to maple
+ all related gem ports configuration complete indication were received from device
+ */
+ if (NULL == p_flow)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "%s: NULL flow passed in: flow\n", __FUNCTION__);
+
+ return BCM_ERR_NOENT;
+ }
+ else
+ {
+ if (BCMOS_FALSE == p_flow->is_configuration_completed
+ || BCMOS_TRUE == p_flow->is_waiting_for_svc_port_active
+ || BAL_UTIL_FLOW_IND_SEND_NONE != p_flow->ind_sent)
+ {
+ send_ind = BCMOS_FALSE;
+ }
+ //else all conditions satisfied for sending an indication up to Core.
+ }
+
+ if ((BCM_ERR_OK == err) && (BCMOLT_RESULT_SUCCESS != ind_result))
+ {
+ err = BCM_ERR_INTERNAL;
+ }
+
+ if (BCMOS_TRUE == send_ind)
+ {
+ switch (p_flow->op_type)
+ {
+ case BAL_UTIL_OPER_FLOW_ADD:
+ if (BCM_ERR_OK != err)
+ {
+ /* report flow failed to Core; It is upto the core to cleanup the flows */
+
+ p_flow->ind_sent = BAL_UTIL_FLOW_IND_SEND_FAIL;
+ mac_util_report_flow_add_failed(p_flow->bal_flow_key, p_flow->if_id, err);
+ }
+ else
+ {
+
+ p_flow->ind_sent = BAL_UTIL_FLOW_IND_SEND_SUCCESS;
+ mac_util_report_flow_add_success(p_flow->bal_flow_key, p_flow->if_id);
+ }
+
+ break;
+
+ case BAL_UTIL_OPER_FLOW_REMOVE:
+ case BAL_UTIL_OPER_FLOW_CLEAR:
+ if (BCM_ERR_OK != err)
+ {
+ /* report flow failed to Core; It is upto the core to cleanup the flows */
+
+ p_flow->ind_sent = BAL_UTIL_FLOW_IND_SEND_FAIL;
+ mac_util_report_flow_remove_failed(p_flow->bal_flow_key, p_flow->if_id, p_flow->op_type, err);
+ }
+ else
+ {
+
+ p_flow->ind_sent = BAL_UTIL_FLOW_IND_SEND_SUCCESS;
+ mac_util_report_flow_remove_success(p_flow->bal_flow_key, p_flow->if_id, p_flow->op_type);
+ }
+
+ /* One more step for Flow Remove: remove from DB & Free the flow */
+ _mac_util_db_flow_remove (p_flow->if_id, p_flow);
+ _mac_util_db_flow_free (p_flow->if_id, p_flow);
+
+ break;
+
+ default:
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief mac_util_indication_cb
+ * this routine is the callback function that is registered by mac_util_indication_handler_register()
+ * to handle any indications coming from maple device
+ * this is the entry point for the device towards mac_util/bal
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return void
+ *
+ * @todo Note that the pon interface in Auto Indication msgs from Maple is a physical interface
+ * on a device. The PON interface that is used by Core in it's requests to MAC Util,
+ * and stored in local DBs will be logical interface.
+ * So the rule of thumb would be anything coming from Maple side, translate (device + physical Interface)
+ * to Logical interface and use for logging, internal DB access etc.
+ */
+void mac_util_indication_cb(bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ switch (p_msg->obj_type)
+ {
+ case BCMOLT_OBJ_ID_DEVICE:
+ {
+ rc = mac_util_indication_handle_for_device (device_id, p_msg);
+ }
+ break;
+
+ case BCMOLT_OBJ_ID_GPON_NI:
+ case BCMOLT_OBJ_ID_GPON_ONU:
+ case BCMOLT_OBJ_ID_GPON_ALLOC:
+ case BCMOLT_OBJ_ID_GPON_GEM_PORT:
+ {
+ rc = mac_util_handle_all_olt_ind_for_gpon (device_id, p_msg);
+ }
+ break;
+
+ case BCMOLT_OBJ_ID_XGPON_NI:
+ case BCMOLT_OBJ_ID_XGPON_ONU:
+ case BCMOLT_OBJ_ID_XGPON_ALLOC:
+ {
+ rc = mac_util_handle_all_olt_ind_for_xgpon (device_id, p_msg);
+ }
+ break;
+
+ default:
+ BCM_LOG(DEBUG, log_id_mac_util, "Unhandled message indication for obj type %d\n",
+ p_msg->obj_type);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Error handling Auto Indication from Maple for obj type %d\n", p_msg->obj_type);
+ }
+
+ return;
+}
+
+
+
+/**
+ * @brief get string for the indication object type for device
+ */
+static char *mac_util_indication_get_obj_type_str_for_device (bcmolt_obj_id obj_type)
+{
+ int i = 0;
+ for (i=0; i < BCM_SIZEOFARRAY(mac_util_device_ind_handlers); i++)
+ {
+ if (obj_type == mac_util_device_ind_handlers[i].obj_type)
+ {
+ return mac_util_device_ind_handlers[i].obj_type_str;
+ }
+ }
+
+ return "Unhandled";
+}
+
+/**
+ * @brief check if mac util should report access terminal connect event to core.
+ * event will be sent only when all devices are connected successfully
+ *
+ * @return bcmos_bool
+ */
+
+static bcmos_bool mac_util_check_acc_term_report_event (void)
+{
+
+ bcmolt_devid device_id;
+
+ BCM_TOPO_FOR_EACH_DEV(device_id)
+ {
+ if (!acc_term_connectivity.devices[device_id].is_connected)
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ return BCMOS_TRUE;
+}
+
+/**
+ * @brief Handler function for Maple auto indications for a OLT Device
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_device (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_mac_util,
+ "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
+ p_msg->obj_type, mac_util_indication_get_obj_type_str_for_device(p_msg->obj_type),
+ p_msg->group, p_msg->subgroup);
+
+ if (BCMOLT_DEVICE_AUTO_ID_CONNECTION_COMPLETE == p_msg->subgroup)
+ {
+ BCM_LOG(INFO, log_id_mac_util, "Device %u is ready.\n", device_id);
+
+ acc_term_connectivity.devices[device_id].is_connected = BCMOS_TRUE;
+
+ if (mac_util_check_acc_term_report_event())
+ {
+ mac_util_report_acc_term_event(p_msg->subgroup);
+ }
+
+ if (mac_util_bal_req_handlers_for_system_mode[acc_term_connectivity.devices[device_id].system_mode].acc_term_post_indication_set)
+ {
+ rc = mac_util_bal_req_handlers_for_system_mode[acc_term_connectivity.devices[device_id].system_mode].acc_term_post_indication_set(device_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "%s: post indication set FAILED: rc = %s (%d)\n",
+ __FUNCTION__, bcmos_strerror(rc), rc);
+ }
+ }
+ }
+ else if (BCMOLT_DEVICE_AUTO_ID_CONNECTION_FAILURE == p_msg->subgroup)
+ {
+ BCM_LOG(INFO, log_id_mac_util, "Device %u connection failed.\n", device_id);
+ if(!acc_term_connectivity.fail_reported)
+ {
+ mac_util_report_acc_term_event(p_msg->subgroup);
+ }
+ acc_term_connectivity.fail_reported = BCMOS_TRUE;
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Common routine to get string of indication object
+ *
+ * @param obj_type obj type to get string for
+ * @param obj_types_and_handlers obj types array
+ * @param num_obj_types num obj types
+ *
+ * @return char*
+ */
+char *_mac_util_get_obj_type_str_for_indications ( bcmolt_obj_id obj_type,
+ mac_util_ind_obj_and_handlers obj_types_and_handlers[], uint16_t num_obj_types)
+{
+ int i;
+
+ for (i = 0; i < num_obj_types; i++)
+ {
+ if (obj_type == obj_types_and_handlers[i].obj_type)
+ {
+ return obj_types_and_handlers[i].obj_type_str;
+ }
+ }
+
+ return "Unhandled";
+}
+
+
+/**
+ * @brief Common routine to register for Maple auto indications
+ *
+ * @param p_rx_cfg handler config structure
+ * @param obj_types_and_handlers obj types to subscribe
+ * @param num_obj_types num obj types
+ * @param device_id specific device id (for multiple devices support)
+ *
+ * @return bcmos_errno
+ *
+ * @todo with multiple devices in future this needs to be done on per device basis and based on epon or gpon mode
+ */
+bcmos_errno _mac_util_register_for_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg,
+ mac_util_ind_obj_and_handlers obj_types_and_handlers[], uint16_t num_obj_types,
+ bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ int i;
+
+ for (i = 0; i < num_obj_types; i++)
+ {
+ /* set to specific auto indication object type */
+ p_rx_cfg->obj_type = obj_types_and_handlers[i].obj_type;
+ rc = bcmolt_auto_rx_cb_set(device_id, p_rx_cfg);
+ if (BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief Maple auto indication register for specific device based indications
+ *
+ * @param p_rx_cfg handler config structure
+ *@param device_id specific device id (for multiple devices support)
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_register_for_device_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
+{
+ return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_device_ind_handlers, BCM_SIZEOFARRAY(mac_util_device_ind_handlers),device_id);
+}
+
+
+/**
+ * @brief mac_util_indication_handler_register
+ * this local routine registers the local function 'mac_util_indication_cb'
+ * as the callback for any indications coming from maple device
+ *
+ *@param device_id specific device id (for multiple devices support)
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handler_register(bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ struct bcmolt_rx_cfg rx_cfg =
+ {
+ .obj_type = BCMOLT_OBJECT_ANY,
+ .rx_cb = g_indication_handler,
+ .flags = BCMOLT_AUTO_FLAGS_DISPATCH,
+ .module = BCMOS_MODULE_ID_WORKER_MGMT,
+ .pon_ni_mask = 0 /** Bitmask of pon_ni interfaces the registration applies to. 0=all interfaces. */
+ };
+
+
+ rc = mac_util_register_for_device_auto_indications(&rx_cfg, device_id);
+ if (BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ rc = mac_util_register_for_gpon_auto_indications(&rx_cfg, device_id);
+ if (BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ rc = mac_util_register_for_xgpon_auto_indications(&rx_cfg, device_id);
+ if (BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief reset mac_util access terminal internal db
+ * all devices marked as disconnected
+ */
+
+static void mac_util_access_terminal_reset (void)
+{
+ bcmolt_devid device_id;
+
+ BCM_TOPO_FOR_EACH_DEV(device_id)
+ {
+ acc_term_connectivity.devices[device_id].is_connected = BCMOS_FALSE;
+ }
+
+ acc_term_connectivity.fail_reported = BCMOS_FALSE;
+}
+
+/**
+ * @brief reset a single maple device
+ *
+ * @param device_id the maple device id to be reset
+ *
+ * @return bcmos_errno
+ */
+
+static bcmos_errno reset_device(bcmolt_devid device_id)
+{
+
+ bcmolt_device_key key = {};
+ bcmolt_device_reset oper;
+
+ BCMOLT_OPER_INIT(&oper, device, reset, key);
+ BCMOLT_OPER_PROP_SET(&oper, device, reset, mode, BCMOLT_DEVICE_RESET_MODE_DEVICE);
+
+ return bcmolt_oper_submit(device_id , &oper.hdr);
+}
+
+/**
+ * @brief common config across mac modes during access terminal set.
+ * currently only the admin up case is supported (op_type is ignored))
+ * @note this is called from individual mac handler files rather than calling upfront here in this file
+ * in access_terminal_set(), because this is not to be called for loopback mode.
+ *
+ *
+ * @return bcmos_errno
+ */
+
+bcmos_errno maple_access_terminal_set_common (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+
+ rc = reset_device(device_id);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Failed to reset device %d (%s)\n", device_id, bcmos_strerror(rc));
+ return rc;
+ }
+ /* Because there is no indication coming from Maple that device reset is complete, we should sleep here. 1 second should be enough. */
+ bcmos_usleep(1000000);
+
+ /* register for maple indications - doing it after reset to avoid catching stale indications */
+ rc = mac_util_indication_handler_register(device_id);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Failed to register for device %d indications (%s)\n", device_id, bcmos_strerror(rc));
+ return rc;
+ }
+ /* using 1 second delay between the indication registration and configuration setup
+ to let the maple proxy queue get empty */
+ bcmos_usleep(1000000);
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno maple_access_terminal_connect_common (bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+ bcmolt_device_connect dev_connect_oper;
+ bcmolt_device_key key = {};
+
+ /* invoking the connect operation */
+ BCMOLT_OPER_INIT(&dev_connect_oper, device, connect, key);
+
+ rc = bcmolt_oper_submit(device_id, &dev_connect_oper.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Failed to submit connect operation for device %d (%s), err_text = %s\n",
+ device_id, bcmos_strerror(rc), dev_connect_oper.hdr.hdr.err_text);
+ }
+
+ return rc;
+}
+
+/* Derive a specific device system mode from topology and store it at the internal db*/
+static bcmos_errno mac_util_system_mode_get(bcmolt_devid device_id)
+{
+ uint32_t logical_pon;
+ uint32_t pon_mode2max_physical_pons[BCM_TOPO_PON_MODE__NUM_OF] = {};
+
+ BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
+ {
+ uint32_t physical_pon;
+ bcm_topo_pon_mode pon_mode;
+
+ pon_mode = bcm_topo_pon_get_pon_mode(logical_pon);
+ bcm_topo_pon_get_logical2physical(logical_pon, &device_id, &physical_pon);
+ /* Get the number of physical PONs mapped.
+ * For example, if the user mapped only 4 physical PONs out of 16 in GPON mode, and the maximum physical PON mapped was 11, then the system mode should be GPONx16, not GPONx8. */
+ pon_mode2max_physical_pons[pon_mode] = MAX(pon_mode2max_physical_pons[pon_mode], physical_pon + 1);
+
+ }
+
+ if (bcmbal_is_mac_in_loopback())
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_LOOPBACK;
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_GPON])
+ {
+ if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_GPON] <= 8)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_GPON__8_X;
+ else
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_GPON__16_X;
+ }
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_XGPON])
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_XGPON_1__8_X;
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_XGS])
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_XGS__2_X_10_G;
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_TDMA])
+ {
+ if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_TDMA] <= 4)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA;
+ else
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA;
+ }
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_1G])
+ {
+ if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_1G] <= 4)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__4_X;
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_1G] <= 8)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__8_X;
+ else
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__16_X;
+ }
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_10G])
+ {
+ if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_10G] <= 2)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__2_X_10_G;
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_EPON_10G] <= 4)
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__4_X_10_G;
+ else
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_EPON__8_X_10_G;
+ }
+ else if (pon_mode2max_physical_pons[BCM_TOPO_PON_MODE_LOOPBACK])
+ acc_term_connectivity.devices[device_id].system_mode = BCMOLT_SYSTEM_MODE_LOOPBACK;
+ else
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Cannot determine system mode from topology\n");
+ return BCM_ERR_PARM;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief Command Set setup routine for access terminal connect to the mac devices
+ *
+ * This routine is called by acc_term_fsm in the BAL core, at an admin up operation
+ * and will result in setting and connecting all the access terminal devices
+ *
+ * @param p_acc_term Pointer to access terminal instance
+ * @param op_type Operation type on access terminal instance
+ *
+ * @return bcmos_errno
+ *
+ * @todo this code will change with multiple devices
+ */
+bcmos_errno mac_util_access_terminal_set(acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_devid device_id;
+ bcmos_bool is_wait_for_report = BCMOS_FALSE;
+
+ BCM_TOPO_FOR_EACH_DEV(device_id)
+ {
+ /*will reset and connect, in case the device is not already connected*/
+ if (!acc_term_connectivity.devices[device_id].is_connected)
+ {
+ /* Add timeout between bringing up maple devices.
+ * Otherwise, maple APIs can time out
+ */
+ if (is_wait_for_report)
+ bcmos_usleep(10000000);
+ is_wait_for_report = BCMOS_TRUE;
+ /* mac mode specific acc term set */
+ if (mac_util_bal_req_handlers_for_system_mode[acc_term_connectivity.devices[device_id].system_mode].acc_term_set)
+ {
+ rc = mac_util_bal_req_handlers_for_system_mode[acc_term_connectivity.devices[device_id].system_mode].acc_term_set(p_acc_term, op_type, device_id);
+ }
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "%s: FAILED: rc = %s (%d)\n",
+ __FUNCTION__, bcmos_strerror(rc), rc);
+ return rc;
+ }
+ }
+ }
+ if (!is_wait_for_report)
+ {
+ mac_util_report_acc_term_event(BCMOLT_DEVICE_AUTO_ID_CONNECTION_COMPLETE);
+ }
+
+ return rc;
+}
+
+/*---------------------------------------------------------------------------------------------*/
+/*----------------------------------interface set handling-------------------------------------------*/
+
+/**
+ * @brief Command Set setup routine for interface up to mac application
+ *
+ * This routine is called by if_fsm in the BAL core to initialize the command
+ * set to up the interface of the mac application. The cmdset actually
+ * consists of two commands, one is to send the if up request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param op_type Operation type on interface instance
+ *
+ * @return bcmos_errno
+ *
+ * @todo system mode to identify handler function is global across olt now.
+ * This should be queried for per pon interface and used to identify the protocol
+ * and the corresponding handler.
+ */
+bcmos_errno mac_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
+{
+ /* Parameter checks */
+ BUG_ON(NULL == p_interface_inst);
+
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
+ bcm_topo_pon_mode pon_mode;
+
+ /* First check if it is for PON interface. If not (i.e. NNI), then just return a success without
+ * forwarding anything to MAC hardware.
+ */
+ if (BCMBAL_INTF_TYPE_PON != intf_key.intf_type)
+ {
+ mac_util_report_if_event(intf_key.intf_id,
+ intf_key.intf_type,
+ BCM_ERR_OK, BCMOLT_RESULT_SUCCESS,
+ ((BAL_UTIL_OPER_IF_UP == op_type) ? BCMOLT_PON_STATE_ACTIVE_WORKING : BCMOLT_PON_STATE_INACTIVE));
+
+ return BCM_ERR_OK;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "SET if %s , intf_type: %s, intf_id: %d\n",
+ (BAL_UTIL_OPER_IF_UP == op_type ? "UP" : "DOWN"),
+ (BCMBAL_INTF_TYPE_PON == intf_key.intf_type ? "PON":"NNI"),
+ intf_key.intf_id);
+
+ /* query PON mode */
+ pon_mode = mac_util_get_pon_mode(intf_key.intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ rc = BCM_ERR_INTERNAL;
+
+ /* system mode specific interface set */
+ if ((BCM_ERR_OK == rc) && mac_util_bal_req_handlers_for_pon_mode[pon_mode].if_set)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].if_set(p_interface_inst, op_type);
+ }
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed INTERFACE-%s operation for IF %d\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN", intf_key.intf_id);
+ }
+
+ return rc;
+}
+
+
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_subscriber_terminal_info_validate
+ *
+ * This routine is used to validate all input attributes required for a sub term setting
+ * received from core
+ *
+ * @param p_sub_term_req A pointer to a subscriber terminal object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_subscriber_terminal_info_validate(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_sub_term_req->key.intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ rc = BCM_ERR_INTERNAL;
+
+ /* validate system mode specific things */
+ if ((BCM_ERR_OK == rc) && mac_util_bal_req_handlers_for_pon_mode[pon_mode].sub_term_validate)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].sub_term_validate(p_sub_term_req);
+ }
+
+ return rc;
+}
+
+
+/*----------------------------------subscriber terminal set handling-----------------------------------*/
+
+/**
+ * @brief Command Set setup routine for subscriber terminal connect to mac application
+ *
+ * This routine is called by sub_term_fsm in the BAL core to initialize the command
+ * set to connect the subscriber terminal of the mac application. The cmdset actually
+ * consists of two commands, one is to send the sub_term request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_sub_term_inst A pointer to a subscriber terminal instance
+ * @param op_type Type of operation being performed on the subscriber terminal instance
+ * @param is_post_discovery Used for ADD, indicates if this request is after a ONU Discovery
+ *
+ * @return bcmos_errno
+ */
+
+bcmos_errno mac_util_subscriber_terminal_set(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
+ bcm_topo_pon_mode pon_mode;
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "IN : %s pon_id = %d onu_id= %d "
+ "omci_gem_port = %d\n",
+ __FUNCTION__,
+ p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id, p_sub_term_req->data.svc_port_id);
+
+ if ((BAL_UTIL_OPER_SUB_TERM_ADD != op_type)
+ && (BAL_UTIL_OPER_SUB_TERM_REMOVE != op_type)
+ && (BAL_UTIL_OPER_SUB_TERM_CLEAR != op_type))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Unsupported operation %d for sub_term %u\n",
+ op_type, p_sub_term_req->key.sub_term_id);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_sub_term_req->key.intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ rc = BCM_ERR_INTERNAL;
+
+ /* system mode specific sub term set */
+ if ((BCM_ERR_OK == rc) && mac_util_bal_req_handlers_for_pon_mode[pon_mode].sub_term_set)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].sub_term_set(p_sub_term_inst, op_type, is_post_discovery);
+ }
+
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s: Failed: rc = %s (%d)\n",
+ __FUNCTION__, bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+
+
+
+/*---------------------------------------------------------------------------------------------*/
+/*------------------group set handling GROUP routines and helper functions-------------------*/
+/*---------------------------------------------------------------------------------------------*/
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_group_info_validate
+ *
+ * This routine is used to validate all input attributes required for a group
+ * setting received from core
+ *
+ * @param p_group_req A pointer to a group object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_group_info_validate(const bcmbal_group_cfg *p_group_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ int i;
+
+ do
+ {
+ /* if the group has no owner, no need to check as service port will not be assigned */
+ if (p_group_req->data.owner == BCMBAL_GROUP_OWNER_NONE)
+ {
+ break;
+ }
+ /* if group member command is set, there has to be member info,
+ for remove, service port is an option
+ */
+ if (BCMBAL_CFG_PROP_IS_SET(p_group_req, group, members_cmd))
+ {
+ if(p_group_req->data.members.len)
+ {
+ for(i=0; i< p_group_req->data.members.len; i++)
+ {
+ /* all members should have the service port as non-zero */
+ if (!p_group_req->data.members.val[i].svc_port_id)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "svc_port_id is a mandatory parameter for a group member, and it can not set to zero\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ break;
+ }
+ }
+ }
+ }
+
+ }while(0);
+
+ return rc;
+}
+
+/**
+ * @brief Core interface: setup routine for group
+ *
+ * This routine is called by group_fsm in the BAL core to
+ * add/remove/set group in the mac application. Unlike flow request,
+ * the mac driver does not send indication messages back upon completion.
+ * This routine needs to fake an indication message to core to trigger the group_fsm.
+ *
+ * @param p_grp_inst Pointer to group instance
+ * @param op_type Operation type on group instance
+ * @param send_ind TRUE - send indication, FALSE - don't send indication
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_group_set(group_inst *p_grp_inst, bal_util_oper_group op_type, bcmos_bool send_ind)
+{
+ bcmbal_group_cfg *p_group_req = &p_grp_inst->api_req_group_info;
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_group_cfg *p_group_lookup_info = NULL;
+ bcm_topo_pon_mode pon_mode;
+
+ do
+ {
+ /* if the group has no owner, no need to access the HW as service port will not be set */
+ if (p_group_req->data.owner == BCMBAL_GROUP_OWNER_NONE)
+ {
+ break;
+ }
+
+ /*
+ * When we are doing a GROUP_ADD, the API request has the information we need,
+ * When we are doing a GROUP_DESTROY, the current group info has this information (because
+ * the GROUP_DESTROY request only has the group key populated. The current flow info has
+ * all of the attributes used when create the group.
+ */
+ p_group_lookup_info = (BAL_UTIL_OPER_GROUP_DESTROY == op_type) ? &p_grp_inst->current_group_info : p_group_req;
+
+ BCM_LOG(INFO, log_id_mac_util, "%s group_id = %d with oper type %s\n ",
+ __FUNCTION__,
+ p_group_lookup_info->key.group_id,
+ BCMBAL_UTIL_GROUP_OPER_STR_GET(op_type)
+ );
+
+ /* mac only need to response to set member when op_type is ADD/REMOVE/SET - configure multicast service ports */
+ if ((BAL_UTIL_OPER_GROUP_ADD == op_type ||
+ BAL_UTIL_OPER_GROUP_REMOVE == op_type ||
+ BAL_UTIL_OPER_GROUP_SET == op_type ) &&
+ BCMBAL_CFG_PROP_IS_SET(p_group_req, group, members))
+ {
+ /* assume all members are of same mode */
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_group_req->data.members.val[0].intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ {
+ rc = BCM_ERR_INTERNAL;
+ }
+ /* system mode specific group set */
+ else if ( mac_util_bal_req_handlers_for_pon_mode[pon_mode].group_set)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].group_set(p_group_req, op_type, p_grp_inst);
+ }
+
+ }
+
+ /* special case - destroy with valid members, then need to remove all members */
+ else if ((BAL_UTIL_OPER_GROUP_DESTROY == op_type && p_group_lookup_info->data.members.len != 0))
+ {
+ /* query system mode - use first member as default */
+ pon_mode = mac_util_get_pon_mode(p_group_lookup_info->data.members.val[0].intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ {
+ rc = BCM_ERR_INTERNAL;
+ }
+ /* system mode specific group set */
+ else if ( mac_util_bal_req_handlers_for_pon_mode[pon_mode].group_set)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].group_set(p_group_lookup_info, BAL_UTIL_OPER_GROUP_REMOVE, p_grp_inst);
+ }
+ }
+ }while(0);
+
+ /* return an indication message to core */
+ if(send_ind)
+ {
+ _mac_util_report_group_set_indication(p_group_req->key, op_type, rc);
+ }
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "%s Failed: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+
+/*---------------------------------------------------------------------------------------------*/
+/*------------------flow set handling Interface routines and helper functions-------------------*/
+/*---------------------------------------------------------------------------------------------*/
+
+
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_flow_info_validate
+ *
+ * This routine is used to validate all input attributes required for a flow
+ * setting received from core
+ *
+ * @param p_flow_req A pointer to a flow object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_flow_info_validate(const bcmbal_flow_cfg *p_flow_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+
+ do
+ {
+ if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_MULTICAST)
+ {
+ /* nothing to do in multicast FLOW - validate in GROUP*/
+ break;
+ }
+ if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, group_id) )
+ {
+ /* nothing to do in DS N:1 FLOW - validate in GROUP */
+ break;
+ }
+
+ if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, access_int_id))
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "access if id is a mandatory parameter for a flow, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+
+ break; /* if interface id not set then skip rest of the checks */
+ }
+
+ if (p_flow_req->key.flow_type != BCMBAL_FLOW_TYPE_BROADCAST)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, sub_term_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "sub term id is a mandatory parameter for a flow, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+
+ if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, svc_port_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "svc_port_id is a mandatory parameter for a flow, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+
+ /* validate flow id */
+ if (BCMOS_FALSE == MAC_UTIL_FLOW_DB_FLOW_ID_IS_VALID(p_flow_req->key.flow_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "flow Id from user is not within range: %d <= flow id <= %d\n",
+ MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL, MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL);
+ rc = BCM_ERR_PARM;
+ }
+
+
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_flow_req->data.access_int_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ {
+ rc = BCM_ERR_INTERNAL;
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "could not get system mode for pon interface\n");
+ }
+ }
+
+ /* system mode specific validation */
+ if ((BCM_ERR_OK == rc) && mac_util_bal_req_handlers_for_pon_mode[pon_mode].flow_validate)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].flow_validate(p_flow_req);
+ /* the called function will log any protocol specific validation errors */
+ }
+
+ } while (0);
+
+ return rc;
+}
+
+/**
+ * @brief Core interface: setup routine for flow
+ *
+ * This routine is called by flow_fsm in the BAL core to initialize the command
+ * to add flow to the mac application. The cmdset actually
+ * consists of two commands, one is to send the flow request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_flow_core Pointer to flow instance from core fsm
+ * @param op_type Operation type on flow instance
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_flow_set(flow_inst *p_flow_core, bal_util_oper_flow op_type)
+{
+ bcmbal_flow_cfg *p_flow_req = &p_flow_core->api_req_flow_info;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_flow_cfg *p_flow_lookup_info = NULL;
+ bcm_topo_pon_mode pon_mode;
+
+ /*
+ * When we are doing a FLOW_ADD, the API request has the information we need,
+ * When we are doing a FLOW_REMOVE, the current flow info has this information (because
+ * the FLOW_REMOVE request only has the flow key populated. The current flow info has
+ * all of the attributes used to create the flow in the first place.
+ */
+ p_flow_lookup_info = (BAL_UTIL_OPER_FLOW_ADD == op_type) ? p_flow_req : &p_flow_core->current_flow_info;
+
+ bcmos_bool flow_is_destined_to_host = BAL_UTIL_OPER_FLOW_ADD == op_type ?
+
+ ((BCMBAL_CFG_PROP_IS_SET(&p_flow_core->api_req_flow_info, flow, action) &&
+ (p_flow_core->api_req_flow_info.data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)) ? BCMOS_TRUE : BCMOS_FALSE) :
+
+ ((BCMBAL_CFG_PROP_IS_SET(&p_flow_core->current_flow_info, flow, action) &&
+ (p_flow_core->current_flow_info.data.action.cmds_bitmask &
+ BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)) ? BCMOS_TRUE : BCMOS_FALSE);
+
+ /* There's no need to do anything with the MAC in downstream flows that
+ * that are destined to the host CPU (i.e. NNI->CPU)
+ */
+ if(((BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type) &&
+ flow_is_destined_to_host))
+ {
+ /* When the flow is downstream and destined to the host (i.e. NNI->CPU), then there
+ * is nothing to do in the MAC, so just return an indication to allow the FSM to continue on.
+ */
+ if (BAL_UTIL_OPER_FLOW_ADD == op_type)
+ {
+ mac_util_report_flow_add_success(p_flow_req->key, p_flow_req->data.access_int_id);
+ }
+ else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) || (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ mac_util_report_flow_remove_success(p_flow_req->key, p_flow_req->data.access_int_id, op_type);
+ }
+ }
+ /* for multicast flow all works are done in GROUP object, simply send the indication to Core */
+ else if (BCMBAL_FLOW_TYPE_MULTICAST == p_flow_req->key.flow_type)
+ {
+ /* there is no access_int_id for multicast flow, pass 0 as parameter.
+ The interface number is just used for logging purpose in the indication API */
+ _mac_util_report_flow_set_indication(p_flow_req->key, 0, op_type, rc);
+ }
+ /* for downstream n:1 flow all works are done in GROUP object, simply send the indication to Core */
+ else if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type &&
+ (BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, group_id)) )
+ {
+ /* there is no access_int_id for DS N:1 flow, pass 0 as parameter.
+ The interface number is just used for logging purpose in the indication API */
+ _mac_util_report_flow_set_indication(p_flow_req->key, 0, op_type, rc);
+ }
+ else
+ {
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "%s flow_id = %d dir = %s, pon_id = %d "
+ "onu_id= %d alloc_id = %d gem_port = %d, op_type = %s\n",
+ __FUNCTION__,
+ p_flow_lookup_info->key.flow_id,
+ p_flow_lookup_info->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "up":"down",
+ p_flow_lookup_info->data.access_int_id,
+ p_flow_lookup_info->data.sub_term_id,
+ p_flow_lookup_info->data.agg_port_id,
+ p_flow_lookup_info->data.svc_port_id,
+ (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW_ADD":
+ (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW_REMOVE" : "FLOW_CLEAR")));
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_flow_req->data.access_int_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ rc = BCM_ERR_INTERNAL;
+
+ /* system mode specific flow set */
+ if ((BCM_ERR_OK == rc) && mac_util_bal_req_handlers_for_pon_mode[pon_mode].flow_set)
+ {
+ rc = mac_util_bal_req_handlers_for_pon_mode[pon_mode].flow_set(p_flow_lookup_info, op_type, p_flow_core);
+ }
+ }
+
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "%s Failed: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_tm sched_info_validate
+ *
+ * This routine is used to validate all input attributes required for a tm sched
+ * setting received from core
+ *
+ * @param p_tm_sched_req A pointer to a tm sched object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_tm_sched_info_validate(const bcmbal_tm_sched_cfg *p_tm_sched_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+ do
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_req, tm_sched, owner))
+ {
+ /* nothing to do in MAC */
+ break;
+ }
+
+ if (p_tm_sched_req->data.owner.type != BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT)
+ {
+ /* nothing to do in MAC */
+ break;
+ }
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_tm_sched_req->data.owner.u.agg_port.intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ rc = BCM_ERR_INTERNAL;
+
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_tm_sched_req->data.owner.u.agg_port.intf_id),
+ "could not get system mode for pon interface\n");
+ }
+ } while (0);
+ return rc;
+}
+
+bcmos_errno mac_util_agg_port_set(tm_sched_inst *p_tm_sched, bal_util_oper_agg_port op_type)
+{
+ bcmbal_tm_sched_cfg *p_agg_port_req = &p_tm_sched->req_tm_sched_info;
+ bcmos_errno rc = BCM_ERR_OK;
+
+
+ bcm_topo_pon_mode pon_mode;
+ do
+ {
+
+ /* query system mode */
+ pon_mode = mac_util_get_pon_mode(p_agg_port_req->data.owner.u.agg_port.intf_id);
+ if (pon_mode == BCM_TOPO_PON_MODE_INVALID)
+ {
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ rc = maple_mac_util_agg_port_set(p_agg_port_req, op_type, p_tm_sched);
+
+ }while(0);
+ return rc;
+}
+
+#if !defined(WRX_BUILD)
+/* Internal function that finds UDP port to bind to */
+static bcmos_errno _mac_util_find_free_udp_port(uint16_t *p_port)
+{
+#define MAX_UDP_PORT_TRY_ITER 100 /* Try 100 times, then give up */
+#define MAX_UDP_PORT 60000
+#define MIN_UDP_PORT (MAX_UDP_PORT / 2)
+ uint16_t port;
+ struct sockaddr_in sa;
+ int sock;
+ int bind_rc;
+ int i = 0;
+
+ /* Open UDP socket */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Can't create UDP socket. error %s\n", strerror(errno));
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = INADDR_ANY;
+
+ do
+ {
+ port = rand() % MAX_UDP_PORT;
+ if (port < MIN_UDP_PORT)
+ port += MIN_UDP_PORT;
+ sa.sin_port = htons(port);
+ bind_rc = bind(sock, (struct sockaddr *)&sa, sizeof(sa));
+ } while (bind_rc < 0 && ++i < MAX_UDP_PORT_TRY_ITER);
+
+ /* Yes, yes. There is a possible race condition that someone will take the port we've just found
+ * before we had a chance to bind it again.
+ * In this unlikely case BAL application will fail on startup and will have to be restarted.
+ */
+ close(sock);
+
+ if (bind_rc < 0)
+ {
+ BCMOS_TRACE_RETURN(BCM_ERR_NORES, "Couldn't find unused UDP port after %d tries. Giving up.\n", i);
+ }
+
+ *p_port = port;
+
+ return BCM_ERR_OK;
+}
+#endif
+
+static void bal_indication_cb(bcmolt_devid olt, bcmolt_msg *p_msg)
+{
+ mac_util_indication_cb(olt, p_msg);
+
+ bcmolt_msg_free(p_msg);
+}
+
+#ifdef ENABLE_LOG
+/**
+ * @brief routine to register per pon log strings with logger
+ *
+ * @param system_mode -OLT system mode
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_register_logging_per_pon (void)
+{
+ char log_str_buf[MAC_UTIL_LOG_STR_SZ] = {0};
+ bcmolt_devid device_id;
+ uint32_t logical_pon;
+
+ /** @note if by any chance the system mode is set multiple times, then we want to avoid
+ * re-registering already registered pon interfaces, because there is currently no way
+ * to de-register those interfaces first. We will just register the not-registered ones.
+ */
+ /* register log Ids for each PON interface, that is not already registered */
+ BCM_TOPO_FOR_EACH_PON(device_id, logical_pon)
+ {
+ if (0 != log_id_mac_util_pon_if[logical_pon])
+ {
+ continue;
+ }
+
+ /* make a log id string */
+ MAC_UTIL_MAKE_LOG_STR_FOR_PON_IF(logical_pon, log_str_buf, sizeof(log_str_buf));
+ /* register log id string for pon interface */
+ log_id_mac_util_pon_if[logical_pon] = bcm_dev_log_id_register(log_str_buf, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_mac_util_pon_if[logical_pon] == DEV_LOG_INVALID_ID);
+ }
+
+ return BCM_ERR_OK;
+}
+#endif
+
+
+
+/**
+ * @brief get ip & port for MAC/Maple
+ */
+bcmos_errno mac_util_init_parse_mac_ip_and_port (const char *maple_address)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+#if !defined(WRX_BUILD)
+ rc = app_util_parse_ip_port(maple_address, &bcmtr_olt_ip[0], &bcmtr_olt_udp_port[0]);
+ if (rc)
+ {
+ return rc;
+ }
+
+ srand(bcmos_timestamp());
+ rc = _mac_util_find_free_udp_port(&bcmtr_host_udp_port);
+#endif
+
+ return rc;
+}
+
+
+/**
+ * @brief mac_util_init routine for mac application
+ * @param maple_address - pointer to maple device instance
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_init(const char *maple_address)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_devid device_id;
+
+ do
+ {
+#ifdef ENABLE_LOG
+ /* register a generic MAC util log Id too, for use other than PON If related logs */
+ log_id_mac_util = bcm_dev_log_id_register("MAC_UTIL", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_mac_util == DEV_LOG_INVALID_ID);
+#endif
+
+ if (!bcmbal_is_mac_in_loopback())
+ {
+ rc = mac_util_init_parse_mac_ip_and_port (maple_address);
+ if (BCM_ERR_OK != rc)
+ break;
+ }
+
+ g_indication_handler = bal_indication_cb;
+
+ BCM_TOPO_FOR_EACH_DEV(device_id)
+ {
+ rc = mac_util_system_mode_get(device_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "%s: system mode get for device %d FAILED: rc = %s (%d)\n",
+ __FUNCTION__, device_id, bcmos_strerror(rc), rc);
+ break;
+ }
+ }
+
+#ifdef ENABLE_LOG
+ /* register logging for each PON based on mac mode*/
+ mac_util_register_logging_per_pon();
+#endif
+
+ mac_util_access_terminal_reset();
+
+ } while(0);
+
+ return rc;
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief This function is the helper for the mac app print_flows CLI command backend
+ * which print the full internal flows list
+ *
+ * @param sess Pointer to the current cli session
+ * @param parm An array of parameters from the CLI command, which will be empty on that no parameters command case
+ * @param nParms The number of elements in the parm array (above) that have
+ * valid data, which will be 0 on that case.
+ *
+ * @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise
+ *
+ *****************************************************************************/
+static bcmos_errno _cmd_flows_print(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ flow_list_entry *p_current_entry = NULL;
+ flow_list_entry *p_next_entry = NULL;
+ uint32_t if_id = 0;
+
+ printf("Flow DB: starting flow id=%d, max flow id=%d\n",
+ MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL, MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL);
+
+ for (if_id=0; if_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES; if_id++)
+ {
+ /* before every db segment, NULL the current entry */
+ p_current_entry = NULL;
+ p_next_entry = NULL;
+
+ /* get first */
+ p_current_entry = _mac_util_db_flow_get_next_w_flow_key (if_id, p_current_entry, &p_next_entry);
+ while (NULL != p_current_entry)
+ {
+ printf("\n------------------------------\n");
+ printf ("\nflow_id = %d flow_type = %d\n", p_current_entry->bal_flow_key.flow_id, p_current_entry->bal_flow_key.flow_type);
+ printf ("\n if_id = %d sub_term_id = %d svc_port_id = %d agg_id = %d vlan_id = %d\n",
+ p_current_entry->if_id, p_current_entry->sub_term_id, p_current_entry->svc_port_id, p_current_entry->agg_id, p_current_entry->vlan_id);
+ printf("\n is_waiting_for_svc_port_active = %s is_configuration_completed=%s ind_sent = %d\n",
+ p_current_entry->is_waiting_for_svc_port_active==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->is_configuration_completed==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->ind_sent);
+ printf("\n------------------------------\n");
+
+ /* get next */
+ p_current_entry = _mac_util_db_flow_get_next_w_flow_key (if_id, p_current_entry, &p_next_entry);
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno _cmd_flows_print_for_gem(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ flow_list_entry *p_current_entry = NULL;
+ void *p_rsc_mgr_curr_entry = NULL;
+ void *p_rsc_mgr_next_entry = NULL;
+
+ uint32_t if_id = 0;
+
+ printf("Flow DB for a GEM port [%ld]: starting flow id=%d, max flow id=%d\n",
+ parm[0].value.unumber, MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL, MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL);
+
+ for (if_id=0; if_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES; if_id++)
+ {
+ /* before every db segment, NULL the current entry */
+ p_current_entry = NULL;
+
+ /* get first */
+ p_current_entry = _mac_util_db_flow_get_next_w_gem (if_id, parm[0].value.unumber, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ while (NULL != p_current_entry)
+ {
+ printf("\n------------------------------\n");
+ printf ("\nflow_id = %d flow_type = %d\n", p_current_entry->bal_flow_key.flow_id, p_current_entry->bal_flow_key.flow_type);
+ printf ("\n if_id = %d sub_term_id = %d svc_port_id = %d agg_id = %d vlan_id = %d\n",
+ p_current_entry->if_id, p_current_entry->sub_term_id, p_current_entry->svc_port_id, p_current_entry->agg_id, p_current_entry->vlan_id);
+ printf("\n is_waiting_for_svc_port_active = %s is_configuration_completed=%s ind_sent = %d\n",
+ p_current_entry->is_waiting_for_svc_port_active==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->is_configuration_completed==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->ind_sent);
+ printf("\n------------------------------\n");
+
+ /* get next */
+ p_current_entry = _mac_util_db_flow_get_next_w_gem (if_id, parm[0].value.unumber, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+static bcmos_errno _cmd_flows_print_for_alloc_id(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ flow_list_entry *p_current_entry = NULL;
+ void *p_rsc_mgr_curr_entry = NULL;
+ void *p_rsc_mgr_next_entry = NULL;
+
+ uint32_t if_id = 0;
+
+ printf("Flow DB for a Alloc Id [%ld]: starting flow id=%d, max flow id=%d\n",
+ parm[0].value.unumber, MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL, MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL);
+
+ for (if_id=0; if_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES; if_id++)
+ {
+ /* before every db segment, NULL the current entry */
+ p_current_entry = NULL;
+
+ /* get first */
+ p_current_entry = _mac_util_db_flow_get_next_w_alloc_id (if_id, parm[0].value.unumber, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ while (NULL != p_current_entry)
+ {
+ printf("\n------------------------------\n");
+ printf ("\nflow_id = %d flow_type = %d\n", p_current_entry->bal_flow_key.flow_id, p_current_entry->bal_flow_key.flow_type);
+ printf ("\n if_id = %d sub_term_id = %d svc_port_id = %d agg_id = %d vlan_id = %d\n",
+ p_current_entry->if_id, p_current_entry->sub_term_id, p_current_entry->svc_port_id, p_current_entry->agg_id, p_current_entry->vlan_id);
+ printf("\n is_waiting_for_svc_port_active = %s is_configuration_completed=%s ind_sent = %d\n",
+ p_current_entry->is_waiting_for_svc_port_active==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->is_configuration_completed==BCMOS_TRUE ? "true" : "false",
+ p_current_entry->ind_sent);
+ printf("\n------------------------------\n");
+
+ /* get next */
+ p_current_entry = _mac_util_db_flow_get_next_w_alloc_id (if_id, parm[0].value.unumber, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/* Update CLI based on the system mode */
+static void handle_system_mode_change(bcmolt_devid dev)
+{
+ if (dev == current_device)
+ {
+ bcmcli_entry *cur_dir = bcmcli_dir_get(current_session);
+ char old_dir_name[32] = "";
+
+ if (cur_dir)
+ strncpy(old_dir_name, bcmcli_token_name(cur_dir), sizeof(old_dir_name) - 1);
+
+ bcmcli_dir_set(current_session, maple_dir);
+ api_cli_set_commands(current_session);
+
+ /* Restore current CLI directory */
+ cur_dir = bcmcli_dir_find(NULL, old_dir_name);
+ bcmcli_dir_set(current_session, cur_dir);
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * @brief mac_util_cli_init
+ *
+ * This routine is called from main to initialize the mac_app cli,
+ *that is used for internal unit testing.
+ *
+ * @param cli_dir - a pointer to the cli directory to init that cli in
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_cli_init(bcmcli_entry *cli_dir)
+{
+ bcmcli_entry *p_cli_dir;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ do
+ {
+ p_cli_dir = bcmcli_dir_add(cli_dir, "Mac_Util", "Mac Util (debug)", BCMCLI_ACCESS_ADMIN, NULL);
+
+ BCMCLI_MAKE_CMD_NOPARM(p_cli_dir, "print_flows", "print mac app flows list", _cmd_flows_print);
+ BCMCLI_MAKE_CMD(p_cli_dir, "print_flows_for_gem", "print mac flows sharing a GEM port", _cmd_flows_print_for_gem,
+ BCMCLI_MAKE_PARM("gem_port_id", "GEM Port Id", BCMCLI_PARM_UNUMBER, 0));
+ BCMCLI_MAKE_CMD(p_cli_dir, "print_flows_for_alloc_id", "print mac flows sharing an Alloc Id", _cmd_flows_print_for_alloc_id,
+ BCMCLI_MAKE_PARM("alloc_id", "Alloc Id", BCMCLI_PARM_UNUMBER, 0));
+
+ /* Initialize the bal api cli UI */
+ maple_dir = bcmcli_dir_add(NULL, "maple", "Maple API access", BCMCLI_ACCESS_ADMIN, NULL);
+
+ sm_change_cb = handle_system_mode_change;
+
+ /* Init device selector */
+ rc = bcmolt_dev_sel_init(maple_dir);
+
+ /* Add Maple API commands */
+ rc = rc ? rc : api_cli_init(maple_dir, current_session);
+
+#ifdef BOARD
+ rc = rc ? rc : bcm_board_init();
+ rc = rc ? rc : bcm_board_cli_init(NULL);
+#endif
+ rc = rc ? rc : bcmtr_init();
+ rc = rc ? rc : bcmtr_cld_cli_init();
+ rc = rc ? rc : bcmtr_cli_init();
+
+ } while(0);
+
+ return rc;
+
+ return BCM_ERR_OK;
+}
+
+/*****************************************************************************/
+/**
+ * @brief Un-initialize the mac util internal data structures
+ *
+ * @returns bcmos_errno == BCM_ERR_OK
+ *
+ * @note this routine does not seem to be used currently
+ *****************************************************************************/
+bcmos_errno mac_util_finish(void)
+{
+ flow_list_entry *p_current_entry = NULL, *p_next_entry = NULL;
+ uint32_t if_id = 0;
+
+ for (if_id=0; if_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES; if_id++)
+ {
+ /* before every db segment, NULL the current entry */
+ p_current_entry = NULL;
+ p_next_entry = NULL;
+
+ /* Free all the entries on the flows list */
+ /* get first */
+ p_current_entry = _mac_util_db_flow_get_next_w_flow_key (if_id, p_current_entry, &p_next_entry);
+ while (NULL != p_current_entry)
+ {
+ /* Remove it from the list, and free memory */
+ _mac_util_db_flow_remove (if_id, p_current_entry);
+ _mac_util_db_flow_free (if_id, p_current_entry);
+
+ /* get next */
+ p_current_entry = _mac_util_db_flow_get_next_w_flow_key (if_id, p_current_entry, &p_next_entry);
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+bcmos_errno mac_util_access_terminal_sw_version_validate(bcmolt_devid device)
+{
+ bcmolt_device_cfg cfg = {};
+ bcmolt_device_key key = {};
+ bcmos_errno rc;
+
+ BCMOLT_CFG_INIT(&cfg, device, key);
+ BCMOLT_CFG_PROP_GET(&cfg, device, host_sw_version);
+ rc = bcmolt_cfg_get(device, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Unable to get OLT SW version\n");
+ return rc;
+ }
+
+ BCM_LOG(INFO, log_id_mac_util,
+ "Actual OLT SW version %d.%d.%X (Object model revision %d)\n",
+ cfg.data.host_sw_version.major,
+ cfg.data.host_sw_version.minor,
+ cfg.data.host_sw_version.revision,
+ cfg.data.host_sw_version.model);
+
+ BCM_LOG(INFO, log_id_mac_util,
+ "BAL OLT SW version %d.%d.%X (Object model revision %d)\n",
+ BCMOLT_HOST_MAJOR_VER,
+ BCMOLT_HOST_MINOR_VER,
+ BCMOLT_HOST_REVISION_VER,
+ BCMOLT_MODEL_REVISION);
+
+ /* Check for versions mismatch */
+ if (cfg.data.host_sw_version.major != BCMOLT_HOST_MAJOR_VER ||
+ cfg.data.host_sw_version.minor != BCMOLT_HOST_MINOR_VER ||
+ cfg.data.host_sw_version.revision != BCMOLT_HOST_REVISION_VER ||
+ cfg.data.host_sw_version.model != BCMOLT_MODEL_REVISION)
+ {
+ BCM_LOG(ERROR, log_id_mac_util, INBOLD_BAD(
+ "SW versions mismatch: BAL was complied with OTL SW version %d.%d.%X (Object model revision %d), "
+ "while actual OLT SW version is %d.%d.%X (Object model revision %d)\n"),
+ BCMOLT_HOST_MAJOR_VER,
+ BCMOLT_HOST_MINOR_VER,
+ BCMOLT_HOST_REVISION_VER,
+ BCMOLT_MODEL_REVISION,
+ cfg.data.host_sw_version.major,
+ cfg.data.host_sw_version.minor,
+ cfg.data.host_sw_version.revision,
+ cfg.data.host_sw_version.model);
+ return BCM_ERR_STATE;
+ }
+ return BCM_ERR_OK;
+}
+
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util.h b/bal_release/src/core/util/mac/bal_mac_util.h
new file mode 100755
index 0000000..e0bf5b9
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util.h
@@ -0,0 +1,295 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util.h
+ *
+ * @brief Mac util interfaces header file
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @defgroup mac_util Mac Util
+ * @ingroup core
+ */
+
+#ifndef BAL_MAC_UTIL_H
+#define BAL_MAC_UTIL_H
+
+/****************************************/
+
+#include <bcmolt_host_api.h>
+#include <acc_term_fsm.h>
+#include <sub_term_fsm.h>
+#include <flow_fsm.h>
+#include <group_fsm.h>
+#include <tm_sched_fsm.h>
+#include <bal_utils_msg.h>
+
+#include <bal_common.h>
+#include <bal_mac_util.h>
+#include <rsc_mgr.h>
+#include <bal_app_common_utils.h>
+#include <bal_utils.h>
+#include <bal_worker.h>
+#include <bal_msg.h>
+#include <bcm_topo.h>
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+#include <bcmtr_debug_cli.h>
+#endif //ENABLE_LOG
+
+
+/*@{*/
+
+/** @brief none fail reason for sub term deactivation. Defined locally, since Maple SDK does not define this. */
+#define MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE BCMOLT_ACTIVATION_FAIL_REASON_NONE
+
+/**
+ * @brief The following macros define the max and min user flow Id values and the check for a valid flow Id.
+ */
+extern uint32_t mac_util_flow_id_start_val;
+#define MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL (mac_util_flow_id_start_val)
+#define MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL (MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL+BAL_ACC_TERM_MAX_FLOWS-1)
+
+#define MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL_CONFIG(_start_val) (mac_util_flow_id_start_val = (_start_val))
+
+#define MAC_UTIL_FLOW_DB_FLOW_ID_IS_VALID(_flow_id) \
+ (((_flow_id) >= MAC_UTIL_FLOW_DB_FLOW_ID_START_VAL) && \
+ ((_flow_id) <= MAC_UTIL_FLOW_DB_FLOW_ID_MAX_VAL))
+
+typedef struct mac_util_sla mac_util_sla;
+struct mac_util_sla
+{
+ uint64_t min_rate; /* min_rate (this is a uint64_t as the units are bytes per second) */
+ uint64_t max_rate; /* max_rate (this is a uint64_t as the units are bytes per second) */
+};
+
+/* flow entry structure */
+typedef struct flow_list_entry flow_list_entry;
+struct flow_list_entry
+{
+ TAILQ_ENTRY(flow_list_entry) next;
+ bcmbal_flow_key bal_flow_key; /* bal flow key */
+ uint32_t if_id; /* pon_ni id */
+ uint32_t sub_term_id; /* onu_id */
+ uint16_t svc_port_id; /* the flow related gem port id */
+ uint16_t agg_id; /* the flow related alloc-id */
+ uint16_t vlan_id;
+ bcmos_bool is_waiting_for_svc_port_active; /* indicates whether waiting for a gem port to become active */
+ bcmos_bool is_configuration_completed;
+ bal_util_flow_ind ind_sent; /* indicates whether an indication was sent to core none/success/fail */
+ mac_util_sla sla; /* it saves a converted value for the SLAs; we may retain this in mac util */
+ bal_util_oper_flow op_type; /* Operation type: FLOW_ADD or FLOW_REMOVE */
+};
+
+#define RSRC_MGR_KEEPS_FLOW_LIST_PER_GEM BCMOS_FALSE
+
+extern dev_log_id log_id_mac_util;
+extern dev_log_id log_id_mac_util_pon_if[];
+/** @def get log Id for pon interface */
+#define MAC_UTIL_GET_LOG_ID_FOR_PON_IF(_pon_if_id) (log_id_mac_util_pon_if[(_pon_if_id)])
+
+
+/** @def system default transceiver type */
+#define BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_GPON BCMBAL_TRX_TYPE_GPON_LTE_3680_M
+#define BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGPON BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC
+#define BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGS BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC
+
+
+/**
+ * @brief is valid pon interface id
+ * @todo see if it is feasible to tie it up with system mode. However
+ * keep in mind that this check would be called for every db api call.
+ */
+#define IS_VALID_PON_IF(_pon_if) (NUM_SUPPORTED_SUBSCRIBER_INTERFACES > (_pon_if))
+
+
+/* Function Prototypes for external */
+bcmos_errno mac_util_access_terminal_sw_version_validate(bcmolt_devid device);
+bcmos_errno mac_util_access_terminal_set(acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type);
+bcmos_errno mac_util_access_terminal_info_validate(const bcmbal_access_terminal_cfg *p_acc_term_req);
+
+bcmos_errno mac_util_subscriber_terminal_set(sub_term_inst *p_sub_term, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+bcmos_errno mac_util_subscriber_terminal_info_validate(const bcmbal_subscriber_terminal_cfg *p_sub_term_req);
+
+bcmos_errno mac_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+
+bcmos_errno mac_util_flow_set(flow_inst *p_flow_core, bal_util_oper_flow op_type);
+bcmos_errno mac_util_flow_info_validate(const bcmbal_flow_cfg *p_flow_req);
+
+bcmos_errno mac_util_group_set(group_inst *p_flow, bal_util_oper_group op_type, bcmos_bool send_ind);
+bcmos_errno mac_util_group_info_validate(const bcmbal_group_cfg *p_group_req);
+
+bcmos_errno mac_util_tm_sched_info_validate(const bcmbal_tm_sched_cfg *p_tm_sched_req);
+bcmos_errno mac_util_agg_port_set(tm_sched_inst *p_tm_sched, bal_util_oper_agg_port op_type);
+
+
+bcmos_errno mac_util_init(const char *maple_address);
+
+bcmos_errno mac_util_cli_init(bcmcli_entry *p_cli_dir);
+
+void mac_util_indication_cb(bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+bcmos_errno mac_util_finish(void);
+
+/* reporting functions to core */
+void mac_util_report_flow_add_success(bcmbal_flow_key flow_key, uint32_t pon_if);
+void mac_util_report_flow_add_failed(bcmbal_flow_key flow_key, uint32_t pon_if, bcmos_errno err);
+void mac_util_report_flow_remove_success(bcmbal_flow_key flow_key, uint32_t pon_if, bal_util_oper_flow op_type);
+void mac_util_report_flow_remove_failed(bcmbal_flow_key flow_key, uint32_t pon_if, bal_util_oper_flow op_type, bcmos_errno err);
+
+void mac_util_report_tm_sched_set_indication (bcmbal_tm_sched_key tm_sched_key, bcmos_errno err, bcmolt_result ind_result);
+
+/** @brief handler routine type for maple indication handlers */
+typedef bcmos_errno (mac_util_olt_ind_handler)(bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+/** @brief generic struct for maple indication object types and handlers that would be be handled in mac util */
+typedef struct mac_util_olt_ind_obj_and_handlers
+{
+ bcmolt_obj_id obj_type;
+ char obj_type_str[50];
+ mac_util_olt_ind_handler *ind_handler;
+} mac_util_ind_obj_and_handlers;
+
+
+char *_mac_util_get_obj_type_str_for_indications ( bcmolt_obj_id obj_type,
+ mac_util_ind_obj_and_handlers obj_types_and_handlers[], uint16_t num_obj_types);
+
+/* maple indication handlers */
+bcmos_errno mac_util_handle_all_olt_ind_for_gpon (bcmolt_devid device_id, bcmolt_msg *p_msg);
+bcmos_errno mac_util_handle_all_olt_ind_for_xgpon (bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+
+/* flow mgmt wrapper functions */
+flow_list_entry *_mac_util_db_flow_alloc (void);
+bcmos_errno _mac_util_db_flow_free (uint32_t pon_if, flow_list_entry *p_entry);
+
+bcmos_errno _mac_util_db_flow_add (uint32_t pon_if, flow_list_entry *p_entry);
+bcmos_errno _mac_util_db_flow_remove (uint32_t pon_if, flow_list_entry *p_entry);
+
+flow_list_entry *_mac_util_db_flow_get_w_flow_key (uint32_t pon_if, bcmbal_flow_key *p_flow_key);
+flow_list_entry *_mac_util_db_flow_get_next_w_flow_key (uint32_t pon_if, flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry);
+
+
+flow_list_entry *_mac_util_db_flow_get_next_w_sub_term_id (uint32_t pon_if, uint32_t sub_term_id,
+ flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry);
+
+
+bcmos_errno _mac_util_db_flow_count_w_gem (uint32_t pon_if, uint16_t gem_port_id, uint32_t *p_count);
+flow_list_entry *_mac_util_db_flow_get_next_w_gem (uint32_t pon_if, uint16_t gem_port_id,
+ void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry);
+
+bcmos_errno _mac_util_db_flow_count_w_alloc_id (uint32_t pon_if, uint16_t alloc_id, uint32_t *p_count);
+flow_list_entry *_mac_util_db_flow_get_next_w_alloc_id (uint32_t pon_if, uint16_t alloc_id,
+ void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry);
+
+/* interface set */
+bcmos_errno mac_util_interface_set_for_gpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+bcmos_errno mac_util_interface_set_for_xgpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+bcmos_errno mac_util_interface_set_for_loopback(acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+
+/* sub term validate */
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_gpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req);
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_xgpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req);
+
+/* sub term set */
+bcmos_errno mac_util_subscriber_terminal_set_for_gpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+bcmos_errno mac_util_subscriber_terminal_set_for_xgpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+bcmos_errno mac_util_subscriber_terminal_set_for_loopback(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+
+/* flow validates */
+bcmos_errno mac_util_validate_flow_info_for_gpon(const bcmbal_flow_cfg *p_flow_req);
+bcmos_errno mac_util_validate_flow_info_for_xgpon(const bcmbal_flow_cfg *p_flow_req);
+
+
+/* flow sets */
+bcmos_errno mac_util_flow_set_for_gpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core);
+bcmos_errno mac_util_flow_set_for_xgpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core);
+bcmos_errno mac_util_flow_set_for_loopback(bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core);
+
+/* group sets */
+bcmos_errno mac_util_group_set_for_gpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_context);
+bcmos_errno mac_util_group_set_for_xgpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_context);
+
+bcmos_errno maple_access_terminal_set_common (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+bcmos_errno maple_access_terminal_connect_common (bcmolt_devid device_id);
+bcmos_errno mac_util_init_parse_mac_ip_and_port (const char *maple_address);
+
+
+/* Report events to core */
+void mac_util_report_acc_term_event(uint16_t event);
+void mac_util_report_if_event(bcmbal_intf_id intf_id,
+ bcmbal_intf_type intf_type,
+ bcmos_errno err,
+ bcmolt_result result,
+ bcmolt_pon_state new_state);
+bcmos_errno check_send_flow_bal_ind_msg(flow_list_entry *p_flow,
+ bcmos_errno err,
+ bcmolt_result ind_result);
+
+void mac_util_report_sub_term_event(bcmbal_intf_id pon_ni,
+ bcmbal_sub_id onu_id,
+ bcmolt_serial_number *p_serial_number,
+ bal_util_oper_sub_term oper,
+ bcmos_errno err,
+ bcmolt_result result,
+ bcmolt_activation_fail_reason fail_reason,
+ bcmolt_epon_tunnel_id tunnel_id);
+
+
+
+void mac_util_report_flow_auto_ind (uint32_t pon_if,
+ bcmbal_flow_key flow_key ,bal_util_oper_flow op_type, bal_util_flow_ind ind);
+
+
+#define MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM BCMOLT_GPON_ONU_ID_ANY
+
+#define GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(_if_id, _device_id, _physical_if_id) \
+ do \
+ { \
+ rc = bcm_topo_pon_get_logical2physical(_if_id, &(_device_id), &(_physical_if_id)); \
+ if (BCM_ERR_OK != rc) \
+ { \
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(_if_id), \
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc)); \
+ return rc; \
+ } \
+ } \
+ while (0)
+
+
+/*@}*/
+#endif /* BAL_MAC_UTIL_H */
+
+
+
diff --git a/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.c b/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.c
new file mode 100644
index 0000000..e44a574
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.c
@@ -0,0 +1,1336 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_common_itu_pon.c
+ *
+ * @brief mac util interfaces definition used by Bal Core, for ITU PON flavors : GPON, XG-PON1, XGS-PON , NG-PON2
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_common_itu_pon.h>
+#include <bcm_topo.h>
+
+
+
+/**
+ * @brief get string for the indication object type
+ */
+char *mac_util_indication_get_obj_type_str(bcmolt_obj_id obj_type, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size)
+{
+ return _mac_util_get_obj_type_str_for_indications(obj_type, handlers, handlers_size);
+}
+
+
+/**
+ * @brief handle indications for any PON ITU flavor.
+ */
+bcmos_errno mac_util_handle_indication(bcmolt_devid device_id, bcmolt_msg *p_msg, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size)
+{
+ int i = 0;
+ for(i=0; i < handlers_size; i++)
+ {
+ if(p_msg->obj_type == handlers[i].obj_type)
+ {
+ if(NULL != handlers[i].ind_handler)
+ {
+ return handlers[i].ind_handler(device_id, p_msg);
+ }
+ }
+ }
+ /* log an error if unhandled */
+ return BCM_ERR_INTERNAL;
+}
+
+
+
+/**
+ * @brief checks if a gem port is configured in OLT already for the same PON If and ONU
+ *
+ * @param svc_port_id gem port
+ * @param if_id PON NI
+ * @param onu_id ONU Id
+ * @param is_config_required TRUE/FALSE
+ * @param is_wait_for_indication TRUE/FALSE
+ *
+ * @return bcmos_errno
+ *
+ * @todo with multi-thread support in future, the code from checking the maple object
+ * to the actual config will need to be atomic(i.e. using mutex). This, to avoid closely parallel threads
+ * from getting a state of gem slightly before a new config another thread would make on the same gem,
+ * before this thread could configure it. This applies to both gem and alloc id checks.
+ *
+ */
+static bcmos_errno maple_mac_check_gem_port_id_config(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id,
+ bcmos_bool *is_config_required, bcmos_bool *is_wait_for_indication)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_sub_family pon_sub_family;
+ bcmos_bool is_configured = BCMOS_FALSE, is_activated = BCMOS_FALSE;
+
+ /* assume config is not required, if there is an error */
+ *is_config_required = BCMOS_FALSE;
+ *is_wait_for_indication = BCMOS_FALSE;
+
+ pon_sub_family = bcm_topo_pon_get_pon_sub_family(if_id);
+ switch(pon_sub_family)
+ {
+ case BCM_TOPO_PON_SUB_FAMILY_GPON:
+ {
+ rc = maple_gpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
+ }
+ break;
+
+ case BCM_TOPO_PON_SUB_FAMILY_XGPON:
+ {
+ rc = maple_xgpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
+ }
+ break;
+
+ default:
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ return rc;
+ }
+ *is_config_required = !is_configured;
+ *is_wait_for_indication = !is_activated;
+
+ if(BCMOS_FALSE == *is_config_required)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s: gem port id is already configured: if_id = %d onu_id = %d svc_port_id = %d is_wait_for_indication = %s\n",
+ __FUNCTION__,
+ if_id, onu_id,svc_port_id,
+ (*is_wait_for_indication == BCMOS_TRUE ? "TRUE":"FALSE"));
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Checks if a gem port needs to be actually deconfigured.
+ * This would be used during flow remove.
+ *
+ * @param svc_port_id gem port
+ * @param if_id PON NI
+ * @param onu_id ONU Id
+ * @param is_deconfig_required TRUE/FALSE
+ * @param is_wait_for_indication TRUE/FALSE
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_check_gem_port_id_deconfig(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id,
+ bcmos_bool *is_deconfig_required, bcmos_bool *is_wait_for_indication)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t ref_count = 0;
+ bcm_topo_pon_mode pon_mode;
+ bcmos_bool is_configured = BCMOS_FALSE, is_activated = BCMOS_FALSE;
+
+ /* assume De-config not required, in case of an error */
+ *is_deconfig_required = BCMOS_FALSE;
+ *is_wait_for_indication = BCMOS_FALSE;
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ return rc;
+ }
+
+ if(!is_configured)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s error in gpon gem port state: svc_port_id = %d if_id = %d onu_id = %d, gem state: NOT_CONFIGURED\n",
+ __FUNCTION__,
+ svc_port_id, if_id, onu_id);
+
+ return BCM_ERR_INTERNAL;
+ }
+
+
+ /** First: Check if gem deconfig is required:
+ * gem deconfig is not needed if other flows are still using the same gem, or it is already being deconfigured.
+ */
+#if RSRC_MGR_KEEPS_FLOW_LIST_PER_GEM
+ /** @todo the rsrc mgr ref count will not work for now since core fsm keeps the flow with admin down,
+ * though mac util does a clear on the gem.
+ */
+ /* get the ref count for the gem from rsc mgr */
+ rc = rsc_mgr_gem_lookup(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ return BCM_ERR_PARM;
+ }
+#else
+ rc = _mac_util_db_flow_count_w_gem(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+#endif
+
+ /* if more than 1 flow is using the gem in whatever state, skip deconfig */
+ if(1 < ref_count)
+ {
+ *is_deconfig_required = BCMOS_FALSE;
+ }
+ else
+ {
+ *is_deconfig_required = BCMOS_TRUE;
+ }
+
+ /* Gem port configuration indications are available on GPON only */
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ /** Next: Check if need to wait for indication */
+ if(BCMOS_TRUE == *is_deconfig_required)
+ {
+ if(!is_activated)
+ {
+ *is_wait_for_indication = BCMOS_FALSE;
+ }
+ else
+ {
+ *is_wait_for_indication = BCMOS_TRUE;
+ }
+ }
+ else
+ {
+ *is_wait_for_indication = BCMOS_FALSE;
+
+ }
+ }
+ else
+ {
+ *is_wait_for_indication = BCMOS_FALSE;
+ }
+
+
+ if(BCMOS_FALSE == *is_deconfig_required)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "Skip gem port deconfig: is_deconfig_required = %s, is_wait_for_indication = %s, svc_port_id = %d if_id = %d onu_id = %d, [ref_count=%d, gem_is configured=%d, gem_is_activated=%d]\n",
+ (*is_deconfig_required == BCMOS_TRUE ? "TRUE":"FALSE"),
+ (*is_wait_for_indication == BCMOS_TRUE ? "TRUE":"FALSE"),
+ svc_port_id, if_id, onu_id,
+ ref_count, is_configured, is_activated);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_gem_port_id_add
+ *
+ * This routine is used for configuring at maple a specific gem port id on a given pon interface
+ * and assign it to a given onu id
+ * currently all sla properties are hard coded
+ *
+ * @param svc_port_id the gem port id
+ * @param if_id the interface id
+ * @param onu_id the onu id it will assign to
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_gem_port_id_add(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gem_port_configuration configuration = {};
+ bcm_topo_pon_mode pon_mode;
+
+ if(onu_id < MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM)
+ {
+ configuration.direction = BCMOLT_GEM_PORT_DIRECTION_BIDIRECTIONAL;
+ configuration.type = BCMOLT_GEM_PORT_TYPE_UNICAST;
+ }
+ else
+ {
+ configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
+ configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
+ }
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_gem_port_id_add(if_id, svc_port_id, onu_id, &configuration);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_gem_port_id_add(if_id, svc_port_id, onu_id, &configuration);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_gem_port_id_remove
+ *
+ * This routine is used Clear a specific gem port id config in OLT on a given pon interface.
+ *
+ * @param svc_port_id the gem port id
+ * @param if_id the interface id
+ *
+ * @return bcmos_errno
+ *
+ * @todo do we need to fill in all parameters to disable GEM or just the gem key ?
+ */
+static bcmos_errno maple_gem_port_id_remove(uint16_t svc_port_id, uint32_t if_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_gem_port_id_remove(if_id, svc_port_id);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "Failed to clear gem port configuration(%s) in OLT\n",
+ bcmos_strerror(rc));
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief checks if a alloc id is configured in OLT already for the same PON If and ONU
+ *
+ * @param agg_id alloc id
+ * @param if_id PON NI
+ * @param onu_id ONU Id
+ * @param p_alloc_id_state alloc id current state
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_check_alloc_id_state(uint16_t agg_id, uint32_t if_id, uint32_t onu_id, bcmolt_alloc_state *p_alloc_id_state)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_mac_get_alloc_id_config(if_id, onu_id, agg_id, p_alloc_id_state);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_mac_get_alloc_id_config(if_id, onu_id, agg_id, p_alloc_id_state);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ return rc;
+ }
+
+ return rc;
+}
+
+
+
+static bcmos_errno maple_mac_check_alloc_id_config(uint16_t agg_id, uint32_t if_id, uint32_t onu_id)
+{
+ bcmos_errno rc;
+ bcmolt_alloc_state alloc_id_state;
+
+
+ rc = maple_mac_check_alloc_id_state(agg_id, if_id, onu_id, &alloc_id_state);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",
+ __FUNCTION__, bcmos_strerror(rc));
+ return rc;
+ }
+ if(BCMOLT_ALLOC_STATE_NOT_CONFIGURED != alloc_id_state)
+ rc = BCM_ERR_PARM;
+ return rc;
+}
+static bcmos_errno maple_mac_check_alloc_id_active(uint16_t agg_id, uint32_t if_id, uint32_t onu_id, bcmos_bool *is_alloc_id_wait_for_ind)
+{
+ bcmos_errno rc;
+ bcmolt_alloc_state alloc_id_state;
+
+ rc = maple_mac_check_alloc_id_state(agg_id, if_id, onu_id, &alloc_id_state);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ return rc;
+ }
+ *is_alloc_id_wait_for_ind = BCMOLT_ALLOC_STATE_ACTIVE != alloc_id_state;
+ return rc;
+}
+
+/**
+ * @brief helper function to check flow with double tag and with action remove outer tag.
+ * Used for validation as well as flow config.
+ *
+ * @param p_flow_req A pointer to a flow object
+ *
+ * @return bcmos_errno
+ */
+bcmos_bool mac_util_check_flow_is_double_tag_remove_o_tag(const bcmbal_flow_cfg *p_flow_req)
+{
+ if(NULL != p_flow_req)
+ {
+ if(BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type &&
+ BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, action) &&
+ (p_flow_req->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) &&
+ (p_flow_req->data.classifier.pkt_tag_type == BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG))
+ {
+ return BCMOS_TRUE;
+ }
+ }
+
+ return BCMOS_FALSE;
+}
+
+
+/**
+ * @brief maple_mac_unicast_flow_add
+ *
+ * This routine is used to configure a flow at the internal flows list to
+ * handle incoming and outgoing relevant indications.
+ * the flow svc_port is defined using a single gem port by a base_gem_port
+ * and single pbit(=0 in case of pbit is not available)
+ * it will also configure gem port and alloc id at the device if required.
+ *
+ *
+ * @param if_id - the pon interface id
+ * @param onu_id - the onu id
+ * @param agg_id - the alloc id
+ * @param sla - the sla configuration of the alloc id
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno maple_mac_agg_port_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla sla)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+ do
+ {
+ rc = maple_mac_check_alloc_id_config(agg_id, if_id, onu_id);
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "Failed to query alloc state\n");
+ break;
+ }
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_us_alloc_id_add(if_id, onu_id, agg_id, sla);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_us_alloc_id_add(if_id, onu_id, agg_id, sla);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+ }while(0);
+ return rc;
+}
+
+/**
+ * @brief maple_mac_agg_port_remove
+ *
+ * This routine is used for De-configuring at maple a specific alloc_id on a given pon interface
+ *
+ * @param if_id - the pon interface id
+ *
+ * @param agg_id - the alloc id
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno maple_mac_agg_port_remove(uint32_t if_id, uint16_t agg_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_topo_pon_mode pon_mode;
+
+ pon_mode = bcm_topo_pon_get_pon_mode(if_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ rc = maple_gpon_us_alloc_id_remove(if_id, agg_id);
+ }
+ else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
+ {
+ rc = maple_xgpon_us_alloc_id_remove(if_id, agg_id);
+ }
+ else
+ {
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+
+ return rc;
+}
+
+bcmos_errno maple_mac_unicast_flow_add(bcmbal_flow_cfg *p_flow, uint16_t pbit, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
+ flow_list_entry **pp_mac_util_flow_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmos_bool is_gem_config_required = BCMOS_TRUE;
+ bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE , is_alloc_id_wait_for_ind = BCMOS_TRUE;
+ flow_list_entry *p_new_flow_entry = NULL;
+
+
+ *pp_mac_util_flow_entry = NULL;
+ do
+ {
+ /* Allocate & add the new flow to the flow list to follow indications/gem reuse/alloc reuse */
+ p_new_flow_entry = _mac_util_db_flow_alloc();
+ if(NULL == p_new_flow_entry)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to allocate the flow entry\n");
+ rc = BCM_ERR_NOMEM;
+ break;
+ }
+
+ memcpy(&p_new_flow_entry->bal_flow_key, &p_flow->key,
+ sizeof(bcmbal_flow_key));
+ p_new_flow_entry->if_id = p_flow->data.access_int_id;
+ p_new_flow_entry->sub_term_id = p_flow->data.sub_term_id;
+ p_new_flow_entry->svc_port_id = p_flow->data.svc_port_id;
+ if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
+ {
+ p_new_flow_entry->agg_id = p_flow->data.agg_port_id;
+ }
+ p_new_flow_entry->vlan_id = per_flow_mode_vlan_id;
+ p_new_flow_entry->is_waiting_for_svc_port_active = BCMOS_TRUE;
+ p_new_flow_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_NONE;
+ p_new_flow_entry->is_configuration_completed = BCMOS_FALSE;
+
+
+ /* save the operation type so as to report back the right indication type to core on an indication from Maple */
+ p_new_flow_entry->op_type = op_type;
+
+ /* check if gem configuration is required or it was already configured,
+ could happen in case of us flow configured after a ds flow(with the same flow_id)
+ and vise versus, or if that is a case of different flow sharing the same gem port id */
+ if(BCMOS_TRUE == is_gem_config_required)
+ {
+ rc = maple_mac_check_gem_port_id_config(p_new_flow_entry->svc_port_id,
+ p_new_flow_entry->if_id,
+ p_new_flow_entry->sub_term_id,
+ &is_gem_config_required,
+ &is_gem_wait_for_ind);
+ if(BCM_ERR_OK != rc)
+ {
+ /* free the flow entry */
+ _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ /* set wait for ind flag */
+ p_new_flow_entry->is_waiting_for_svc_port_active = is_gem_wait_for_ind;
+ }
+
+ /* if that's an us flow, check if alloc configuration is required or it was already configured */
+ if(p_new_flow_entry->bal_flow_key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ rc = maple_mac_check_alloc_id_active(p_new_flow_entry->agg_id,
+ p_new_flow_entry->if_id,
+ p_new_flow_entry->sub_term_id,
+ &is_alloc_id_wait_for_ind);
+ if(BCM_ERR_OK != rc)
+ {
+ /* free the flow entry */
+ _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+
+ /* add the new flow to the flow DB */
+ rc = _mac_util_db_flow_add(p_flow->data.access_int_id, p_new_flow_entry);
+ if(BCM_ERR_OK != rc)
+ {
+ /* free the flow entry */
+ _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
+ break;
+ }
+
+ /* configure the gem port id if required */
+ if(BCMOS_TRUE == is_gem_config_required)
+ {
+ rc = maple_gem_port_id_add(p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, p_new_flow_entry->sub_term_id);
+ if(BCM_ERR_OK != rc)
+ {
+ break;
+ }
+ }
+
+ } while(0);
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s Failed: rc = %s(%d), flow Id/Type=%d/%d, pbit=%d, if_id=%d, sub_term_id=%d, "
+ "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc,
+ p_flow->key.flow_id, p_flow->key.flow_type, pbit,
+ p_flow->data.access_int_id, p_flow->data.sub_term_id,
+ p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
+ (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW_ADD":"INVALID"));
+ }
+
+ /* set the arg to return the local flow entry to caller */
+ *pp_mac_util_flow_entry = p_new_flow_entry;
+
+ return rc;
+}
+
+
+/**
+ * @brief utility routine to correctly assign the SLAs to new tm sched owned by agg port
+ * This routine adjusts the BW values to be aligned with 8KBytes/sec boundary. It also
+ * adjusts the difference between pbr & sbr to be at least 32KBytes/sec
+ *
+ * @param p_tm_sched_req new tm sched instance
+ * @param p_agg_sla pointer to the sla configuration
+ *
+ * @note For Maple to accept the sla config:
+ * (1) the sbr and pbr values from BAL user should be in increments of 256 KBits/sec.
+ * (2) Also, the sbr should be at least 256 Kbits/sec less than the pbr.
+ * (3) sbr value can be 0 or else at least 256 Kbits/sec
+ * (4) pbr value can be 256 Kbits/sec or above
+ *
+ * @note The SLA is used for the upstream alloc_id really, even though this is being called for downstream and upstream.
+ *
+ */
+void mac_util_assign_agg_port_sla(bcmbal_tm_sched_cfg *p_tm_sched_req, bcmolt_pon_alloc_sla *p_agg_sla)
+{
+
+ BUG_ON(NULL == p_tm_sched_req);
+
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate,tm_shaping, sbr))
+ {
+ p_agg_sla->guaranteed_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.sbr);
+ /* Align the BW to 8KBytes granularity(always upward adjustment) */
+ p_agg_sla->guaranteed_bw = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->guaranteed_bw, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate, tm_shaping, pbr))
+ {
+ p_agg_sla->maximum_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.pbr);
+ /* max rate should be bigger by 32KBytes/sec than guaranteed rate */
+ if(MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID >(p_agg_sla->maximum_bw - p_agg_sla->guaranteed_bw))
+ {
+ p_agg_sla->maximum_bw = p_agg_sla->guaranteed_bw + MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID;
+ }
+ else
+ {
+ /* Else, align the BW to 8KBytes granularity(always upward adjustment) */
+ p_agg_sla->maximum_bw = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->maximum_bw, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
+ }
+ }
+ else
+ {
+ /* max rate should be bigger by 32KBytes/sec than guaranteed rate */
+ p_agg_sla->maximum_bw = p_agg_sla->guaranteed_bw + MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID;
+ }
+ }
+ else if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate, tm_shaping, pbr))
+ {
+ p_agg_sla->maximum_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.pbr);
+
+ /* Align the BW to 8KBytes granularity(always upward adjustment) */
+ p_agg_sla->maximum_bw = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->maximum_bw , MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
+ /* since only max_rate was specified, it is best effort, so set the min rate = 0 */
+ p_agg_sla->guaranteed_bw = 0;
+ }
+ else
+ {
+
+ /* Nothing is set, so assign the defaults(that suits GPON) times the SLA US rate factor(GPON=1, XG-PON1=2, XGS-PON,NG-PON2=8) */
+ p_agg_sla->guaranteed_bw = SLA_GUARANTEED_BW_DEFAULT_BYTES_PER_SEC * MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor;
+ p_agg_sla->maximum_bw = SLA_MAX_BW_DEFAULT_BYTES_PER_SEC * MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor;
+ }
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, nrt_cbr))
+ {
+ /* Align the BW to 8KBytes granularity(always upward adjustment) */
+ p_agg_sla->cbr_nrt_bw = SLA_BW_NKBYTES_ALIGNED(p_tm_sched_req->data.tcont_sla.nrt_cbr, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
+ }
+ else
+ {
+ p_agg_sla->cbr_nrt_bw = 0;
+ }
+
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, rt_cbr))
+ {
+ /* Align the BW to 8KBytes granularity(always upward adjustment) */
+ p_agg_sla->cbr_rt_bw = SLA_BW_NKBYTES_ALIGNED(p_tm_sched_req->data.tcont_sla.rt_cbr, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
+ }
+ else
+ {
+ p_agg_sla->cbr_rt_bw = 0;
+ }
+
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, extra_bw_elig))
+ {
+ p_agg_sla->additional_bw_eligibility = p_tm_sched_req->data.tcont_sla.extra_bw_elig;
+ }
+ else
+ {
+ p_agg_sla->additional_bw_eligibility = BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT;
+ }
+
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, rt_profile))
+ {
+ p_agg_sla->cbr_rt_ap_index = p_tm_sched_req->data.tcont_sla.rt_profile;
+ }
+ else
+ {
+ p_agg_sla->cbr_rt_ap_index = 0;
+ }
+
+ if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, nrt_profile))
+ {
+ p_agg_sla->cbr_nrt_ap_index = p_tm_sched_req->data.tcont_sla.nrt_profile;
+ }
+ else
+ {
+ p_agg_sla->cbr_nrt_ap_index = 0;
+ }
+
+ p_agg_sla->alloc_type = BCMOLT_ALLOC_TYPE_NSR;
+ p_agg_sla->cbr_rt_compensation = BCMOS_FALSE;
+ p_agg_sla->weight = 0;
+ p_agg_sla->priority = 0;
+
+}
+
+
+/**
+ * @brief mark_flow_config_complete
+ *
+ * This routine is used to mark all related flow entries, that the flow configuration requests to device was completed,
+ * meaning now it is ready to be checked for configuration completion indication from device, and to be indicated to core.
+ *
+ * @param p_flow_entry pointer to mac util flow instance
+ *
+ * @return void
+ */
+void mac_util_mark_flow_config_complete(flow_list_entry *p_flow_entry)
+{
+ if(NULL != p_flow_entry)
+ {
+ p_flow_entry->is_configuration_completed = BCMOS_TRUE;
+ }
+}
+
+
+/**
+ * @brief maple_mac_broadcast_flow_add
+ *
+ * This routine is used for setting required configuration for a new broadcast flow :
+ * gem port id, iwf ds flow and configure it as a miss fallback of its assigned interface.
+ * it will also create an entry for the new flow at the internal flows list to follow relevant indication
+ *
+ * @param p_flow A pointer to a flow object
+ * @param per_flow_mode_vlan_id vlan id used for GEM port mapping in per flow mode
+ * @param op_type flow "add" or "modify"
+ * @param pp_mac_util_flow_entry addr of pointer to flow entry in mac util DB
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno maple_mac_broadcast_flow_add(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
+ flow_list_entry **pp_mac_util_flow_entry)
+{
+ bcmos_errno rc = BCM_ERR_PARM;
+ flow_list_entry *p_new_flow_entry = NULL;
+ bcmolt_gpon_iwf_ds_ingress_flow_key in_key;
+ bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg;
+ bcmolt_gpon_iwf_ds_egress_flow_key egr_key;
+ bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg;
+ bcmolt_gpon_iwf_key iwf_key;
+ bcmolt_gpon_iwf_cfg get_iwf_cfg, set_iwf_cfg;
+ bcmolt_mac_table_configuration mac_table_configuration;
+ bcmos_bool is_gem_config_required = BCMOS_TRUE;
+ bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE;
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ bcm_topo_pon_mode pon_mode;
+
+ *pp_mac_util_flow_entry = NULL;
+
+ /* add the new flow to the flow list */
+ p_new_flow_entry = _mac_util_db_flow_alloc();
+ if(NULL == p_new_flow_entry)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to allocate the flow entry\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ memcpy(&p_new_flow_entry->bal_flow_key, &p_flow->key, sizeof(bcmbal_flow_key));
+ p_new_flow_entry->if_id = p_flow->data.access_int_id;
+ p_new_flow_entry->sub_term_id = p_flow->data.sub_term_id;
+ p_new_flow_entry->svc_port_id = p_flow->data.svc_port_id;
+ /* broadcast gem are active by default once they are set, no indications */
+ p_new_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
+ p_new_flow_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_NONE;
+ p_new_flow_entry->is_configuration_completed = BCMOS_FALSE;
+
+ /* make sure the broadcast gem port is not already configured / assigned to any onu on the if */
+ rc = maple_mac_check_gem_port_id_config(p_new_flow_entry->svc_port_id,
+ p_new_flow_entry->if_id,
+ p_new_flow_entry->sub_term_id,
+ &is_gem_config_required,
+ &is_gem_wait_for_ind);
+ if(BCM_ERR_OK != rc)
+ {
+ /* free the flow */
+ _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
+ return BCM_ERR_PARM;
+ }
+
+ if(BCMOS_FALSE == is_gem_config_required)
+ {
+ /* some error, can't have the broadcast flow already configured for the onu */
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Gem %d is already configured on if %d(assigned to onu_id %d)\n",
+ p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, p_new_flow_entry->sub_term_id);
+
+ /* free the flow */
+ _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
+ return BCM_ERR_PARM;
+ }
+
+ /* add the new flow to the local flows list */
+ rc = _mac_util_db_flow_add(p_flow->data.access_int_id, p_new_flow_entry);
+ if(BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ /* a broadcast gem port is 'assigned' to the special MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM onu id */
+ rc = maple_gem_port_id_add(p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM);
+ if(BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical(p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if(%s)\n", bcmos_strerror(rc));
+ return rc;
+ }
+
+ /* Inter-working(IWF) stuff is relevant for GPON only */
+ pon_mode = bcm_topo_pon_get_pon_mode(p_flow->data.access_int_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ /* configure the ingress flow as default fallback ingress flow */
+ in_key.pon_ni = physical_if_id;
+ in_key.vlan_id = per_flow_mode_vlan_id;
+ BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
+ BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_MACPLUSVID);
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_tag,
+ BCMOLT_MAPPING_TAG_METHOD_OUTER_VID);
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, vlan_action, BCMOLT_DS_VLAN_ACTION_TRANSPARENT);
+
+
+ rc = bcmolt_cfg_set(device_id, &in_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to configure ingress flow pon_ni = %d vlan_id = %d rc = %s(%d), err_text = %s\n",
+ in_key.pon_ni, in_key.vlan_id, bcmos_strerror(rc), rc, in_cfg.hdr.hdr.err_text);
+ return rc;
+ }
+
+ /* configure the egress flow as default fallback egress flow */
+ egr_key.pon_ni = physical_if_id;
+ egr_key.flow_id = p_flow->data.svc_port_id;
+
+ /* Configure DS egress handling: flow -> GEM */
+ BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
+ BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, gem_port, p_flow->data.svc_port_id);
+ BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, pbit_control, BCMOS_FALSE);
+
+ rc = bcmolt_cfg_set(device_id, &egr_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to configure egress flow pon_ni = %d, rc = %s(%d), err_text = %s\n",
+ egr_key.pon_ni, bcmos_strerror(rc), rc, egr_cfg.hdr.hdr.err_text);
+ return rc;
+ }
+
+ /* update the if miss fallback flow */
+ iwf_key.pon_ni = physical_if_id;
+ BCMOLT_CFG_INIT(&get_iwf_cfg, gpon_iwf, iwf_key);
+ BCMOLT_CFG_INIT(&set_iwf_cfg, gpon_iwf, iwf_key);
+
+ BCMOLT_CFG_PROP_GET(&get_iwf_cfg, gpon_iwf, all_properties);
+ rc = bcmolt_cfg_get(device_id, &get_iwf_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ mac_table_configuration = get_iwf_cfg.data.mac_table_configuration;
+ mac_table_configuration.miss_fallback = BCMOLT_MAC_TABLE_MISS_FALLBACK_DEFAULT_FLOW;
+ mac_table_configuration.default_flow_id = egr_key.flow_id;
+ BCMOLT_CFG_PROP_SET(&set_iwf_cfg, gpon_iwf, mac_table_configuration, mac_table_configuration);
+
+ rc = bcmolt_cfg_set(device_id, &set_iwf_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to configure iwf: pon_ni = %d, rc = %s(%d), err_text = %s\n",
+ iwf_key.pon_ni, bcmos_strerror(rc), rc, set_iwf_cfg.hdr.hdr.err_text);
+ return rc;
+ }
+ }
+
+ p_new_flow_entry->is_configuration_completed = BCMOS_TRUE;
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s Failed: rc = %s(%d), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
+ "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc,
+ p_flow->key.flow_id, p_flow->key.flow_type,
+ p_flow->data.access_int_id, p_flow->data.sub_term_id,
+ p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
+ (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW_ADD": "INVALID"));
+ }
+
+ /* set the arg to return the local flow entry to caller */
+ *pp_mac_util_flow_entry = p_new_flow_entry;
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_broadcast_flow_remove
+ *
+ * This routine is removes a broadcast flow from Maple
+ *
+ * @param p_flow A pointer to a flow object
+ * @param per_flow_mode_vlan_id vlan id for per flow mode
+ * @param op_type flow "remove" or "clear"
+ * @param p_mac_util_flow_entry mac util flow entry
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno maple_mac_broadcast_flow_remove(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
+ flow_list_entry *p_mac_util_flow_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ flow_list_entry *p_target_flow_entry = NULL;
+ bcmolt_gpon_iwf_ds_ingress_flow_key in_key;
+ bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg;
+ bcmolt_gpon_iwf_ds_egress_flow_key egr_key;
+ bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg;
+ bcmolt_gpon_iwf_key iwf_key;
+ bcmolt_gpon_iwf_cfg set_iwf_cfg;
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ bcm_topo_pon_mode pon_mode;
+
+ /* First find the flow in local database */
+ p_target_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow->data.access_int_id, &(p_flow->key));
+
+ if(NULL == p_target_flow_entry)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s: Failed to find the flow entry: flow id: %d, flow_type: %s\n",
+ __FUNCTION__,
+ p_flow->key.flow_id,
+ (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_BROADCAST ? "broadcast":"unicast/multicast"));
+
+ return BCM_ERR_NOENT;
+ }
+
+
+ /* broadcast gem are active by default once they are set, no indications */
+ p_target_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
+ p_target_flow_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_NONE;
+ p_target_flow_entry->is_configuration_completed = BCMOS_FALSE;
+
+
+
+ /* clear broadcast gem port */
+ rc = maple_gem_port_id_remove(p_target_flow_entry->svc_port_id, p_target_flow_entry->if_id);
+ if(BCM_ERR_OK != rc)
+ {
+ return rc;
+ }
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical(p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if(%s)\n", bcmos_strerror(rc));
+ return rc;
+ }
+
+ /* Inter-working(IWF) stuff is relevant for GPON only */
+ pon_mode = bcm_topo_pon_get_pon_mode(p_flow->data.access_int_id);
+ if(pon_mode == BCM_TOPO_PON_MODE_GPON)
+ {
+ /* clear the ingress flow as default fallback ingress flow */
+ in_key.pon_ni = physical_if_id;
+ in_key.vlan_id = per_flow_mode_vlan_id;
+ BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
+
+ rc = bcmolt_cfg_clear(device_id, &in_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to clear ingress flow pon_ni = %d vlan_id = %d rc = %s(%d)\n",
+ in_key.pon_ni, in_key.vlan_id, bcmos_strerror(rc), rc);
+
+ return rc;
+ }
+
+ /* clear the egress flow as default fallback egress flow */
+ egr_key.pon_ni = physical_if_id;
+ egr_key.flow_id = p_flow->data.svc_port_id;
+ /* Configure DS egress handling: flow -> GEM */
+ BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
+
+ rc = bcmolt_cfg_clear(device_id, &egr_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to clear egress flow pon_ni = %d gem port = %d rc = %s(%d)\n",
+ egr_key.pon_ni, egr_key.flow_id, bcmos_strerror(rc), rc);
+
+ return rc;
+ }
+
+ /* update the if miss fallback flow */
+ iwf_key.pon_ni = physical_if_id;
+ BCMOLT_CFG_INIT(&set_iwf_cfg, gpon_iwf, iwf_key);
+
+ rc = bcmolt_cfg_clear(device_id, &set_iwf_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to clear iwf flow pon_ni = %d rc = %s(%d)\n",
+ iwf_key.pon_ni, bcmos_strerror(rc), rc);
+
+ return rc;
+ }
+ }
+
+ /* all De-config done */
+ p_target_flow_entry->is_configuration_completed = BCMOS_TRUE;
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s Failed: rc = %s(%d), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
+ "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc,
+ p_flow->key.flow_id, p_flow->key.flow_type,
+ p_flow->data.access_int_id, p_flow->data.sub_term_id,
+ p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
+ (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW_REMOVE":(BAL_UTIL_OPER_FLOW_CLEAR == op_type ? "FLOW_CLEAR":"INVALID")));
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_unicast_flow_remove
+ *
+ * This routine is used to De-configure a flow at the internal flows list to
+ * handle incoming and outgoing relevant indications.
+ * It will also De-configure gem port and alloc id at the device if required.
+ *
+ * @param p_flow Pointer to the flow info
+ * @param op_type Flow operation type i.e. FLOW_REMOVE, FLOW_CLEAR
+ * @param p_mac_util_flow_entry Pointer to mac util flow entry
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno maple_mac_unicast_flow_remove(bcmbal_flow_cfg *p_flow, bal_util_oper_flow op_type,
+ flow_list_entry *p_mac_util_flow_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmos_bool is_gem_deconfig_required = BCMOS_TRUE;
+ bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE;
+ flow_list_entry *p_target_flow_entry = NULL;
+
+ BUG_ON(NULL == p_mac_util_flow_entry);
+
+ do
+ {
+ p_target_flow_entry = p_mac_util_flow_entry;
+ p_target_flow_entry->is_waiting_for_svc_port_active = BCMOS_TRUE;
+ p_target_flow_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_NONE;
+ p_target_flow_entry->is_configuration_completed = BCMOS_FALSE;
+ /* save the operation type so as to report back the right indication type to core on an indication from Maple */
+ p_target_flow_entry->op_type = op_type;
+
+ /* check if gem configuration is used by other flows still.
+ could happen in case of us flow configured after a ds flow(with the same flow_id)
+ and vice versa, or if that is a case of different flow sharing the same gem port id */
+ if(BCMOS_TRUE == is_gem_deconfig_required)
+ {
+ rc = maple_mac_check_gem_port_id_deconfig(p_target_flow_entry->svc_port_id,
+ p_target_flow_entry->if_id,
+ p_target_flow_entry->sub_term_id,
+ &is_gem_deconfig_required,
+ &is_gem_wait_for_ind);
+ /* set wait for ind flag */
+ p_target_flow_entry->is_waiting_for_svc_port_active = is_gem_wait_for_ind;
+
+ if(BCM_ERR_OK != rc)
+ {
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+
+ /* do not remove the flow entry from local flows list yet; wait for indication before removing */
+ /* De-configure the gem port id if required */
+ if(BCMOS_TRUE == is_gem_deconfig_required)
+ {
+ rc = maple_gem_port_id_remove(p_target_flow_entry->svc_port_id, p_target_flow_entry->if_id);
+ if(BCM_ERR_OK != rc)
+ {
+ break;
+ }
+ }
+ } while(0);
+
+ if(BCM_ERR_OK != rc)
+ {
+ if(!((BCM_ERR_NOENT == rc) &&(BAL_UTIL_OPER_FLOW_CLEAR == op_type)))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s Failed: rc = %s(%d), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
+ "svc_port_id=%d, agg_id=%d, op type=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc,
+ p_flow->key.flow_id, p_flow->key.flow_type,
+ p_flow->data.access_int_id, p_flow->data.sub_term_id,
+ p_flow->data.svc_port_id, p_flow->data.agg_port_id,
+ (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW_REMOVE":(BAL_UTIL_OPER_FLOW_CLEAR == op_type ? "FLOW_CLEAR":"INVALID")));
+ }
+ }
+
+ return rc;
+
+}
+bcmos_errno mac_util_update_flows_w_sub_term_update(uint32_t pon_if, uint32_t sub_term_id, maple_mac_check_gem_port_id check_gem_port_id_func, maple_mac_check_agg_port_id check_agg_port_id_func)
+{
+ flow_list_entry *p_current_entry = NULL;
+ flow_list_entry *p_next_entry = NULL;
+ bcmos_bool dummy;
+ bcmos_bool is_gem_activated;
+ bcmos_bool is_wait_for_gem_activated;
+ bcmolt_alloc_state alloc_id_state;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ /*find all related flows, check their state and update if needed*/
+ do
+ {
+ p_current_entry = _mac_util_db_flow_get_next_w_sub_term_id(pon_if, sub_term_id, p_current_entry, &p_next_entry);
+ if(NULL == p_current_entry)
+ break;
+
+ rc = check_gem_port_id_func(pon_if,sub_term_id, p_current_entry->svc_port_id, &dummy, &is_gem_activated);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ continue;
+ }
+
+ is_wait_for_gem_activated = !is_gem_activated;
+
+ if(p_current_entry->agg_id)
+ {
+ rc = check_agg_port_id_func(pon_if, sub_term_id, p_current_entry->agg_id, &alloc_id_state);
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ continue;
+ }
+ }
+
+ /*if something was changed.....*/
+ if(p_current_entry->is_waiting_for_svc_port_active != is_wait_for_gem_activated)
+ {
+ /*update current flow entry*/
+ p_current_entry->is_waiting_for_svc_port_active = is_wait_for_gem_activated;
+
+ /*check if a flow became up*/
+ if(p_current_entry->op_type == BAL_UTIL_OPER_FLOW_ADD
+ &&(is_wait_for_gem_activated)
+ && BAL_UTIL_FLOW_IND_SEND_FAIL != p_current_entry->ind_sent)
+ {
+ mac_util_report_flow_auto_ind(pon_if,p_current_entry->bal_flow_key,p_current_entry->op_type, BAL_UTIL_FLOW_IND_SEND_FAIL);
+ p_current_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_FAIL;
+ }
+ /*check if a flow became down*/
+ if(p_current_entry->op_type == BAL_UTIL_OPER_FLOW_ADD
+ &&(!is_wait_for_gem_activated)
+ &&(BAL_UTIL_FLOW_IND_SEND_SUCCESS != p_current_entry->ind_sent))
+ {
+ mac_util_report_flow_auto_ind(pon_if,p_current_entry->bal_flow_key,p_current_entry->op_type, BAL_UTIL_FLOW_IND_SEND_SUCCESS);
+ p_current_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_SUCCESS;
+ }
+ }
+ /* go through all flows(assigned with the given sub term) until break by
+ _mac_util_db_flow_get_next_w_sub_term_id returning NULL*/
+ }while(1);
+
+ return rc;
+}
+
+/**
+ * @brief agg_port set
+ * @param p_tm_sched_req pointer to tm_sched request structure from core
+ * @param op_type ADD, REMOVE or CLEAR
+ * @param p_tm_sched_inst pointer to the core tm sched Object instance
+ *
+ * @return errno error
+ *
+ */
+bcmos_errno maple_mac_util_agg_port_set(bcmbal_tm_sched_cfg *p_tm_sched_req, bal_util_oper_agg_port op_type, tm_sched_inst *p_tm_sched_inst)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ do
+ {
+ /* Check the operation id */
+ if((BAL_UTIL_OPER_AGG_PORT_ADD != op_type) &&
+ (BAL_UTIL_OPER_AGG_PORT_REMOVE != op_type) &&
+ (BAL_UTIL_OPER_AGG_PORT_REMOVE != op_type))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_tm_sched_req->data.owner.u.agg_port.intf_id),
+ "Unexpected mac_util agg port operation %d \n", op_type);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /* agg port Add or Modify */
+ if(BAL_UTIL_OPER_AGG_PORT_ADD == op_type)
+ {
+ bcmolt_pon_alloc_sla agg_sla;
+ mac_util_assign_agg_port_sla(p_tm_sched_req, &agg_sla);
+ ret = maple_mac_agg_port_add(p_tm_sched_req->data.owner.u.agg_port.intf_id, p_tm_sched_req->data.owner.u.agg_port.sub_term_id, p_tm_sched_req->data.owner.u.agg_port.agg_port_id, agg_sla);
+ }
+ if(BAL_UTIL_OPER_AGG_PORT_REMOVE== op_type)
+ {
+ ret = maple_mac_agg_port_remove(p_tm_sched_req->data.owner.u.agg_port.intf_id, p_tm_sched_req->data.owner.u.agg_port.agg_port_id);
+ }
+
+ }while(0);
+ return ret;
+
+}
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.h b/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.h
new file mode 100644
index 0000000..8f0f75f
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_common_itu_pon.h
@@ -0,0 +1,200 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_common_itu_pon.h
+ *
+ * @brief mac util interfaces definition used by Bal Core, for ITU PON: GPON, XG-PON1, XGS-PON
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+
+/**
+ * @brief Maple SLA bandwidth config request is aligned to 8000 Bytes/sec
+ *
+ * @note similar macros are defined in bcm_common_gpon.h embedded code.
+ */
+#define MAPLE_BW_GRANULARITY_BYTES 8000
+#define MAPLE_BW_GRANULARITY_BYTES_10G 16000
+#define MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID 32000
+#define SLA_BW_NKBYTES_ALIGNED(_rate, _us_rate_factor) \
+ (_us_rate_factor) == 8 ? \
+ ((((_rate) + MAPLE_BW_GRANULARITY_BYTES_10G-1) / MAPLE_BW_GRANULARITY_BYTES_10G) * MAPLE_BW_GRANULARITY_BYTES_10G) : \
+ ((((_rate) + MAPLE_BW_GRANULARITY_BYTES-1) / MAPLE_BW_GRANULARITY_BYTES) * MAPLE_BW_GRANULARITY_BYTES)
+
+/* The thumb-rule is GPON PON capacity (155520000 Bps) divided by the maximum number of ONUs (128), rounded by granularity constraint. */
+#define SLA_GUARANTEED_BW_DEFAULT_BYTES_PER_SEC 1208000
+/* Like the default guaranteed BW, but since we are going to configure best-effort class, additional BW must be bigger than guaranteed BW in at least 32000. */
+#define SLA_MAX_BW_DEFAULT_BYTES_PER_SEC (SLA_GUARANTEED_BW_DEFAULT_BYTES_PER_SEC + MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID)
+#define KILOBITS_PER_SEC2BYTES_PER_SEC(x) ((uint64_t)(x) * 1000 / 8)
+
+
+char *mac_util_indication_get_obj_type_str (bcmolt_obj_id obj_type, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size);
+bcmos_errno mac_util_handle_indication (bcmolt_devid device_id, bcmolt_msg *p_msg, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size);
+bcmos_bool mac_util_check_flow_is_double_tag_remove_o_tag (const bcmbal_flow_cfg *p_flow_req);
+void mac_util_assign_agg_port_sla (bcmbal_tm_sched_cfg *p_tm_sched_req, bcmolt_pon_alloc_sla *p_agg_sla);
+
+bcmos_errno maple_mac_unicast_flow_add (bcmbal_flow_cfg *p_flow, uint16_t pbit, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type, flow_list_entry **pp_mac_util_flow_entry);
+bcmos_errno maple_mac_unicast_flow_remove (bcmbal_flow_cfg *p_flow, bal_util_oper_flow op_type, flow_list_entry *p_mac_util_flow_entry);
+bcmos_errno maple_mac_broadcast_flow_add (bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
+ flow_list_entry **pp_mac_util_flow_entry);
+bcmos_errno maple_mac_broadcast_flow_remove (bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type, flow_list_entry *p_mac_util_flow_entry);
+void mac_util_mark_flow_config_complete(flow_list_entry *p_flow_entry);
+bcmos_errno maple_gpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
+ bcmos_bool *is_configured, bcmos_bool *is_activated);
+bcmos_errno maple_xgpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
+ bcmos_bool *is_configured, bcmos_bool *is_activated);
+bcmos_errno maple_gpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration);
+bcmos_errno maple_xgpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration);
+bcmos_errno maple_gpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id);
+bcmos_errno maple_xgpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id);
+bcmos_errno maple_gpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state);
+
+bcmos_errno maple_xgpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state);
+
+
+bcmos_errno maple_gpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla);
+bcmos_errno maple_xgpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla);
+bcmos_errno maple_gpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id);
+bcmos_errno maple_xgpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id);
+
+bcmos_errno maple_mac_agg_port_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla sla);
+bcmos_errno maple_mac_agg_port_remove(uint32_t if_id, uint16_t agg_id);
+
+
+
+/* functions to register for specific auto indications from maple */
+bcmos_errno _mac_util_register_for_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg,
+ mac_util_ind_obj_and_handlers obj_types_and_handlers[], uint16_t num_obj_types, bcmolt_devid device_id);
+bcmos_errno mac_util_register_for_device_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id);
+bcmos_errno mac_util_register_for_gpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id);
+bcmos_errno mac_util_register_for_xgpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id);
+
+
+/** @brief generic struct for object set/validate handlers based on mac protocols */
+typedef bcmos_errno (*mac_util_bal_group_validate_handler) (const bcmbal_group_cfg *p_group_req);
+typedef bcmos_errno (*mac_util_bal_group_set_handler) (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_context);
+typedef bcmos_errno (*mac_util_bal_flow_validate_handler) (const bcmbal_flow_cfg *p_flow_req);
+typedef bcmos_errno (*mac_util_bal_flow_set_handler) (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core);
+typedef bcmos_errno (*mac_util_bal_sub_term_validate_handler) (const bcmbal_subscriber_terminal_cfg *p_sub_term_req);
+typedef bcmos_errno (*mac_util_bal_sub_term_set_handler) (sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+typedef bcmos_errno (*mac_util_bal_if_validate_handler) (acc_term_inst *p_acc_term, bal_util_oper_if op_type);
+typedef bcmos_errno (*mac_util_bal_if_set_handler) (acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+typedef bcmos_errno (*mac_util_bal_acc_term_set_handler) (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+typedef bcmos_errno (*mac_util_bal_acc_term_post_indication_set_handler) (bcmolt_devid device_id);
+
+
+/**
+ * Structure for handler routines for different pon modes and loopback mode
+ */
+typedef struct
+{
+ mac_util_bal_if_validate_handler if_validate;
+ mac_util_bal_if_set_handler if_set;
+
+ mac_util_bal_sub_term_validate_handler sub_term_validate;
+ mac_util_bal_sub_term_set_handler sub_term_set;
+
+ mac_util_bal_flow_validate_handler flow_validate;
+ mac_util_bal_flow_set_handler flow_set;
+
+ mac_util_bal_group_validate_handler group_validate;
+ mac_util_bal_group_set_handler group_set;
+
+ uint32_t sla_us_rate_factor;
+} mac_util_handlers_per_pon_mode_t;
+
+
+typedef bcmos_errno (* maple_mac_check_gem_port_id)(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
+ bcmos_bool *is_configured, bcmos_bool *is_activated);
+
+typedef bcmos_errno (* maple_mac_check_agg_port_id)(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state);
+
+
+
+/** access terminal set */
+bcmos_errno mac_util_access_terminal_set_for_gpon_16 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+bcmos_errno mac_util_access_terminal_set_for_gpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+bcmos_errno mac_util_access_terminal_set_for_xgpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+bcmos_errno mac_util_access_terminal_set_for_xgs (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+bcmos_errno mac_util_access_terminal_set_for_10G_itu_pon (bcmolt_device_cfg dev_cfg, bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_post_indication_set_for_gpon(bcmolt_devid device_id);
+bcmos_errno mac_util_access_terminal_post_indication_set_for_xgpon_xgs(bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_loopback (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id);
+
+bcmos_errno mac_util_update_flows_w_sub_term_update(uint32_t pon_if, uint32_t sub_term_id, maple_mac_check_gem_port_id check_gem_port_id_func, maple_mac_check_agg_port_id check_agg_port_id_func);
+bcmos_errno maple_mac_util_agg_port_set(bcmbal_tm_sched_cfg *p_tm_sched_req, bal_util_oper_agg_port op_type, tm_sched_inst *p_tm_sched_inst);
+
+
+
+/**
+ * Structure for handler routines for diffrent system modes and loopback mode
+ */
+typedef struct
+{
+ mac_util_bal_acc_term_set_handler acc_term_set;
+ mac_util_bal_acc_term_post_indication_set_handler acc_term_post_indication_set;
+} mac_util_bal_req_handlers_for_system_mode_t;
+#define MAC_UTIL_PMDB(pon) mac_util_bal_req_handlers_for_pon_mode[bcm_topo_pon_get_pon_mode((pon))]
+
+typedef struct
+{
+ bcmolt_iwf_mode iwf_mode;
+} mac_util_topo_pon_context;
+
+
+
+typedef struct
+{
+ bcmolt_system_mode system_mode;
+ bcmos_bool is_connected;
+} mac_util_device_context;
+
+typedef struct
+{
+ mac_util_device_context devices[BCM_TOPO_MAX_NUM_OF_DEVS];
+ bcmos_bool fail_reported; /*more that one device may fail to connect, we would like to send the fail event to core only once*/
+} mac_util_acc_term_connectivity;
+
+mac_util_acc_term_connectivity acc_term_connectivity;
+
+extern mac_util_handlers_per_pon_mode_t mac_util_bal_req_handlers_for_pon_mode[];
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_db_apis.c b/bal_release/src/core/util/mac/bal_mac_util_db_apis.c
new file mode 100644
index 0000000..2a84cd0
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_db_apis.c
@@ -0,0 +1,545 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_db_apis.c
+ *
+ * @brief This file has the wrapper functions and the calls to database API functions.
+ * These wrapper functions are called by mac util code for DB operations.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+
+
+/**
+ * @brief flow DB macros
+ * */
+/** @brief max number of flow types stored in the DB.
+ * @details for now upstream & downstream unicast flows only are stored in the flow DB
+ * */
+#define MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES 2
+
+/** @brief check if flow type key is valid */
+#define MAC_UTIL_FLOW_DB_FLOW_TYPE_IS_VALID(_flow_type) \
+ ((_flow_type) >= BCMBAL_FLOW_TYPE_UPSTREAM && \
+ (_flow_type) <= MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES) \
+
+
+/**
+ * @brief maps {flow Id, flow_type} Key pair to an {Index, sub-Index} pair to access a flow entry in the Array DB.
+ * */
+#define MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX(_flow_id, _flow_type, _index, _sub_index) \
+ do \
+ { \
+ (_index) = (_sub_index) = 0; \
+ if(MAC_UTIL_FLOW_DB_FLOW_ID_IS_VALID(_flow_id)) \
+ { \
+ if(MAC_UTIL_FLOW_DB_FLOW_TYPE_IS_VALID(_flow_type)) \
+ { \
+ (_index) = (_flow_id) - mac_util_flow_id_start_val+1; \
+ (_sub_index) = (_flow_type) - 1; \
+ } \
+ } \
+ } while (0);
+
+
+/** @brief lookup an entry from the Array based on flow Id & type key pair */
+#define MAC_UTIL_FLOW_DB_ENTRY_GET(_flow_id, _flow_type, _flow_entry) \
+ do \
+ { \
+ (_flow_entry) = NULL; \
+ uint32_t _index, _sub_index; \
+ MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX((_flow_id), (_flow_type), (_index), (_sub_index)); \
+ if (!_index) \
+ break; \
+ _flow_entry = mac_util_db_flows_list[_index][_sub_index]; \
+ } while (0);
+
+
+/** @brief Get First non-NULL flow entry from the Array */
+#define MAC_UTIL_FLOW_DB_ENTRY_GET_FIRST(_p_first) \
+ do \
+ { \
+ int _i, _j; \
+ for (_i=1; _i<=BAL_ACC_TERM_MAX_FLOWS; _i++) \
+ { \
+ for (_j=0; _j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES; _j++) \
+ { \
+ (_p_first) = mac_util_db_flows_list[_i][_j]; \
+ if (_p_first) \
+ break; \
+ } \
+ if (_p_first) \
+ break; \
+ } \
+ } while (0)
+
+
+/** @brief Get Next non-NULL flow entry from the Array */
+#define MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(_p_curr, _pp_next) \
+ do \
+ { \
+ uint32_t _i, _j, _curr_i, _curr_j; \
+ *(_pp_next) = NULL; \
+ if (_p_curr) \
+ { \
+ MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX(_p_curr->bal_flow_key.flow_id, _p_curr->bal_flow_key.flow_type, _curr_i, _curr_j);\
+ for (_i = (_curr_j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES-1 ?_curr_i : _curr_i+1); \
+ _i<=BAL_ACC_TERM_MAX_FLOWS; \
+ _i++) \
+ { \
+ for (_j= (_curr_j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES-1 ? _curr_j+1 : 0); \
+ _j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES; \
+ _j++) \
+ { \
+ *(_pp_next) = mac_util_db_flows_list[_i][_j]; \
+ if (*(_pp_next)) \
+ break; \
+ } \
+ if (*(_pp_next)) \
+ break; \
+ } \
+ } \
+ else \
+ break; \
+ } while (0)
+
+
+/** @brief Set a flow entry in the Array */
+#define MAC_UTIL_FLOW_DB_ENTRY_SET(_flow_id, _flow_type, _flow_entry, _rc) \
+ do \
+ { \
+ uint32_t _index, _sub_index; \
+ MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX((_flow_id), (_flow_type), (_index), (_sub_index)); \
+ if (!_index) \
+ { \
+ (_rc) = BCM_ERR_NULL; \
+ break; \
+ } \
+ mac_util_db_flows_list[_index][_sub_index] = (_flow_entry); \
+ } while (0);
+
+
+/**
+ * @brief flow Id starting value that can used by SDN User application.
+ * @details By default the starting flow Id is assumed to be 1.
+ */
+uint32_t mac_util_flow_id_start_val = 1;
+
+/**
+ * @brief flow DB Array
+ * @details This Array is for upstream & downstream flows and can store BAL_ACC_TERM_MAX_FLOWS flows.
+ * This array is indexed by BAL flow Id.
+ *
+ * @note First entry starts at index 1; (0 is not used).
+ *
+ * @note Upstream & Downstream flow types of a pair may use the same Flow Id.Hence there is a sub-array
+ * of each of Flow Id entry. The sub array has upstream flow entry in index 0 and downstream at index 1.
+ * Hence, a flow entry is accessible by the key pair {flowId, flowtype}.
+ * */
+static flow_list_entry *mac_util_db_flows_list[BAL_ACC_TERM_MAX_FLOWS + 1][MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES];
+
+
+/*****************************************************************************/
+/** Flow DB wrapper Functions */
+
+/** @todo in future with a new DB data structure, these wrapper functions would
+ * be migrated to call those DB apis.
+ */
+/*****************************************************************************/
+
+/**
+ * @brief Allocate a new flow
+ *
+ * @return flow_list_entry pointer to a new flow entry
+ */
+flow_list_entry *_mac_util_db_flow_alloc (void)
+{
+ flow_list_entry *p_flow = NULL;
+
+ p_flow = bcmos_calloc(sizeof(flow_list_entry));
+ /* bcmos_calloc already initializes the memory to 0 */
+
+ return p_flow;
+}
+
+/**
+ * @brief Free a flow (free the memory or return it to free pool)
+ *
+ * @param pon_if pon interface id
+ * @param p_entry pointer to a flow entry
+ *
+ * @returns bcmos_errno bcm errno
+ *
+ * @note it checks if the flow being freed is already removed from flow DB
+ */
+bcmos_errno _mac_util_db_flow_free (uint32_t pon_if, flow_list_entry *p_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ return BCM_ERR_PARM;
+ }
+
+ if (NULL == p_entry)
+ {
+ return BCM_ERR_PARM;
+ }
+
+ /* free the memory */
+ bcmos_free(p_entry);
+
+ return rc;
+}
+
+/**
+ * @brief Add an already allocated flow to flow DB
+ *
+ * @param pon_if pon interface id
+ * @param p_entry pointer to a new flow entry
+ *
+ * @returns bcmos_errno bcm errno
+ *
+ * @todo in proper DB, it should check if the entry is already in the list or not
+ */
+bcmos_errno _mac_util_db_flow_add (uint32_t pon_if, flow_list_entry *p_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ return BCM_ERR_PARM;
+
+ if (!p_entry)
+ return BCM_ERR_PARM;
+
+ MAC_UTIL_FLOW_DB_ENTRY_SET(p_entry->bal_flow_key.flow_id, p_entry->bal_flow_key.flow_type, p_entry, rc);
+
+ return rc;
+}
+
+/**
+ * @brief Remove a flow entry from flow DB
+ *
+ * @param pon_if pon interface id
+ * @param p_entry pointer to a flow entry
+ *
+ * @returns bcmos_errno bcm errno
+ *
+ * @todo this API will be ported to different DB when we have one
+ */
+bcmos_errno _mac_util_db_flow_remove (uint32_t pon_if, flow_list_entry *p_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ return BCM_ERR_PARM;
+
+ if (!p_entry)
+ return BCM_ERR_PARM;
+
+ MAC_UTIL_FLOW_DB_ENTRY_SET(p_entry->bal_flow_key.flow_id, p_entry->bal_flow_key.flow_type, NULL, rc);
+
+ return rc;
+}
+
+/**
+ * @brief Lookup a flow based on a flow id and pon if
+ *
+ * @param pon_if pon interface id
+ * @param p_flow_key pointer to flow key
+ *
+ * @returns flow_list_entry pointer a flow entry in list
+ */
+flow_list_entry *_mac_util_db_flow_get_w_flow_key (uint32_t pon_if, bcmbal_flow_key *p_flow_key)
+{
+ flow_list_entry *p_flow = NULL;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ return NULL;
+ }
+
+ MAC_UTIL_FLOW_DB_ENTRY_GET(p_flow_key->flow_id, p_flow_key->flow_type, p_flow);
+
+ return p_flow;
+}
+
+/**
+ * @brief get next flow based on flow id and pon_if
+ *
+ * @param pon_if pon interface id
+ * @param p_curr_entry pointer to current flow entry
+ * @param pp_next_entry double pointer to next flow entry
+ *
+ * @returns flow_list_entry pointer to next flow entry in DB
+ */
+flow_list_entry *_mac_util_db_flow_get_next_w_flow_key (uint32_t pon_if, flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry)
+{
+ flow_list_entry *p_tmp_entry = p_curr_entry;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return NULL;
+ }
+
+ /** @note this while loop is to continue to iterate through the DB until an entry with matching pon If is found */
+ while (1)
+ {
+ if (NULL == p_tmp_entry)
+ {
+ /* get first flow */
+ MAC_UTIL_FLOW_DB_ENTRY_GET_FIRST(p_tmp_entry);
+ if (p_tmp_entry)
+ {
+ MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(p_tmp_entry, pp_next_entry);
+
+ if (p_tmp_entry && (pon_if == p_tmp_entry->if_id))
+ return p_tmp_entry;
+ }
+ else
+ break; /* at the end of list */
+ }
+ else
+ {
+ if (NULL != *pp_next_entry)
+ {
+ p_tmp_entry = *pp_next_entry;
+ MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(p_tmp_entry, pp_next_entry);
+
+ if (pon_if == p_tmp_entry->if_id)
+ return p_tmp_entry;
+ }
+ else
+ break; /* at the end of list */
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * @brief get next flow based on sub terminal id
+ *
+ * @param pon_if pon interface id
+ * @param sub_term_id sub term id as the key
+ * @param p_curr_entry pointer to current flow entry
+ * @param pp_next_entry double pointer to next flow entry
+ *
+ * @returns flow_list_entry pointer to next flow entry in DB
+ *
+ */
+flow_list_entry *_mac_util_db_flow_get_next_w_sub_term_id (uint32_t pon_if, uint32_t sub_term_id,
+ flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry)
+{
+ flow_list_entry *p_tmp_entry = NULL;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return NULL;
+ }
+
+ p_tmp_entry = _mac_util_db_flow_get_next_w_flow_key (pon_if, p_curr_entry, pp_next_entry);
+
+ while (NULL != p_tmp_entry)
+ {
+ if (sub_term_id == p_tmp_entry->sub_term_id)
+ {
+ /* found sub_term match */
+ return p_tmp_entry;
+ }
+ /** @note passing tmp entry here because this is a getnext loop internal to this routine */
+ p_tmp_entry = _mac_util_db_flow_get_next_w_flow_key (pon_if, p_tmp_entry, pp_next_entry);
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief count of flows using a gem port and pon_if
+ *
+ * @param pon_if pon interface id
+ * @param gem_port_id gem port id as the key
+ * @param p_count pointer to U32 to save count of flows using the same gem port
+ *
+ * @returns bcmos_errno bcm errno
+ *
+ */
+bcmos_errno _mac_util_db_flow_count_w_gem (uint32_t pon_if, uint16_t gem_port_id, uint32_t *p_count)
+{
+ uint32_t count = 0;
+ flow_list_entry *p_tmp_entry = NULL;
+ void *p_rsc_mgr_curr_entry = NULL;
+ void *p_rsc_mgr_next_entry = NULL;
+
+ BUG_ON(NULL == p_count);
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return BCM_ERR_PARM;
+ }
+
+ p_tmp_entry = _mac_util_db_flow_get_next_w_gem (pon_if, gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ while (NULL != p_tmp_entry)
+ {
+ count++;
+ p_tmp_entry = _mac_util_db_flow_get_next_w_gem (pon_if, gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ }
+
+ *p_count = count;
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief get next flow based on gem and pon if
+ *
+ * @param pon_if pon interface id
+ * @param gem_port_id gem port id as the key
+ * @param **pp_rsc_mgr_curr_entry double pointer to current entry in Rsrc Mgr Database
+ * @param **pp_rsc_mgr_next_entry double pointer to next entry in Rsrc Mgr Database
+ *
+ * @returns flow_list_entry pointer to next flow entry in DB
+ *
+ * @note this queries resource mgr DB
+ */
+flow_list_entry *_mac_util_db_flow_get_next_w_gem (uint32_t pon_if, uint16_t gem_port_id,
+ void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry)
+{
+ flow_inst *p_core_flow_entry = NULL;
+ flow_list_entry *p_flow_entry = NULL;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return NULL;
+ }
+
+ p_core_flow_entry = rsc_mgr_gem_get_next_user_data (pon_if, gem_port_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
+
+ while (NULL != p_core_flow_entry)
+ {
+ p_flow_entry = _mac_util_db_flow_get_w_flow_key(pon_if, &p_core_flow_entry->current_flow_info.key);
+ if (p_flow_entry)
+ {
+ /* found gem match */
+ return p_flow_entry;
+ }
+ p_core_flow_entry = rsc_mgr_gem_get_next_user_data (pon_if, gem_port_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief count of flows using an alloc id and pon if
+ *
+ * @param pon_if pon interface id
+ * @param alloc_id alloc id as the key
+ * @param p_count pointer to U32 that save the count of flows using the same alloc id
+ *
+ * @returns bcmos_errno bcm errno
+ */
+bcmos_errno _mac_util_db_flow_count_w_alloc_id (uint32_t pon_if, uint16_t alloc_id, uint32_t *p_count)
+{
+ uint32_t count = 0;
+ flow_list_entry *p_tmp_entry = NULL;
+ void *p_rsc_mgr_curr_entry = NULL;
+ void *p_rsc_mgr_next_entry = NULL;
+
+ BUG_ON( NULL == p_count);
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return BCM_ERR_PARM;
+ }
+
+ p_tmp_entry = _mac_util_db_flow_get_next_w_alloc_id (pon_if, alloc_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ while (NULL != p_tmp_entry)
+ {
+ count++;
+ p_tmp_entry = _mac_util_db_flow_get_next_w_alloc_id (pon_if, alloc_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ }
+
+ *p_count = count;
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief get next flow based on upstream alloc id and pon if
+ *
+ * @param pon_if pon interface id
+ * @param alloc_id alloc id as the key
+ * @param **pp_rsc_mgr_curr_entry double pointer to current entry in Rsrc Mgr Database
+ * @param **pp_rsc_mgr_next_entry double pointer to next entry in Rsrc Mgr Database
+ *
+ * @returns flow_list_entry pointer to next flow entry in DB
+ *
+ * @note this queries resource mgr DB
+ */
+flow_list_entry *_mac_util_db_flow_get_next_w_alloc_id (uint32_t pon_if, uint16_t alloc_id,
+ void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry)
+{
+ flow_inst *p_core_flow_entry = NULL;
+ flow_list_entry *p_flow_entry = NULL;
+
+ if (!IS_VALID_PON_IF(pon_if))
+ {
+ BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
+ return NULL;
+ }
+
+ p_core_flow_entry = rsc_mgr_alloc_id_get_next_user_data(pon_if, alloc_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
+
+ while (NULL != p_core_flow_entry)
+ {
+ p_flow_entry = _mac_util_db_flow_get_w_flow_key(pon_if, &p_core_flow_entry->current_flow_info.key);
+ if (p_flow_entry)
+ {
+ /* found alloc id match */
+ return p_flow_entry;
+ }
+ p_core_flow_entry = rsc_mgr_alloc_id_get_next_user_data(pon_if, alloc_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
+ }
+
+ return NULL;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_epon.c b/bal_release/src/core/util/mac/bal_mac_util_epon.c
new file mode 100644
index 0000000..cae8d26
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_epon.c
@@ -0,0 +1,1067 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_epon.c
+ *
+ * @brief mac util interfaces definition used by Bal Core for EPON
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_epon.h>
+
+#if BAL_EPON_EXCLUDE
+#include <bcmolt_user_appl_epon_oam.h>
+#include <bal_oam_util.h>
+#include <bcmolt_eon.h>
+
+static bcmos_errno mac_util_indication_handle_for_epon_link (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_epon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+
+/** @brief array stores the list of EPON related auto indications from Maple to subscribe */
+static mac_util_ind_obj_and_handlers mac_util_epon_ind_handlers[] =
+{
+ {BCMOLT_OBJ_ID_EPON_LINK, "BCMOLT_OBJ_ID_EPON_LINK", mac_util_indication_handle_for_epon_link},
+ {BCMOLT_OBJ_ID_EPON_NI, "BCMOLT_OBJ_ID_EPON_NI", mac_util_indication_handle_for_epon_ni}
+};
+
+
+/* epon onu entry structure */
+typedef enum
+{
+ OAM_PROVISION_STATE_IDLE = 0, /**< idle - did not start yet */
+ OAM_PROVISION_STATE_STARTED, /**< started - waiting to configure traffic cb to send bal core flow up indication */
+ OAM_PROVISION_STATE_COMPLETED, /**< completed successfully */
+ OAM_PROVISION_STATE_FAIL/**< failed to complete oam provision */
+} oam_provision_state;
+
+#define MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC 16
+typedef struct epon_onu_list_entry epon_onu_list_entry;
+struct epon_onu_list_entry
+{
+ TAILQ_ENTRY(epon_onu_list_entry) next;
+ bcmbal_subscriber_terminal_key bal_onu_key; /* bal onu key */
+ bcmos_mac_address mac_address;
+ oam_provision_state oam_provision_state;
+ uint8_t waiting_flows_num;
+ bcmbal_flow_key flow_keys[MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC];
+ uint32_t tunnel_id;
+};
+
+
+static TAILQ_HEAD(epon_onu_list_head_t, epon_onu_list_entry) epon_onu_list;
+
+
+/** @todo needs to be ported to the topology stub function */
+static bcmolt_devid maple_device_from_interface_get(uint16_t access_int_id)
+{
+ /* For now, all interfaces map to device 0 */
+ return (bcmolt_devid)0;
+
+}
+
+
+static void epon_onu_list_add(epon_onu_list_entry *epon_onu_entry);
+static epon_onu_list_entry *epon_onu_list_find_by_mac(const bcmos_mac_address *mac_address);
+static epon_onu_list_entry *epon_onu_list_find_by_key(bcmbal_subscriber_terminal_key *key);
+static void epon_onu_list_remove_by_key(bcmbal_subscriber_terminal_key *key);
+
+static void mac_util_configure_traffic_cb(void *context,
+ bcmolt_devid device_id,
+ bcmolt_epon_ni epon_ni,
+ const bcmos_mac_address *mac_address,
+ bcmos_errno result);
+
+static void mac_util_unconfigure_traffic_cb(void *context,
+ bcmolt_devid device_id,
+ bcmolt_epon_ni epon_ni,
+ const bcmos_mac_address *mac_address,
+ bcmos_errno result);
+
+
+#define _mac_addr_fmt_str "<%02x:%02x:%02x:%02x:%02x:%02x>"
+#define _mac_addr_data(mac) \
+ (mac).u8[0], \
+ (mac).u8[1], \
+ (mac).u8[2], \
+ (mac).u8[3], \
+ (mac).u8[4], \
+ (mac).u8[5]
+
+
+static void mac_util_oam_negotiation_cb(void *context, bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac_address, bcmos_errno result)
+{
+
+ epon_onu_list_entry *p_onu_entry = context;
+ uint32_t logical_pon;
+ bcmos_errno rc;
+
+ do
+ {
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, epon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, epon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
+ "device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
+ device_id, epon_ni, _mac_addr_data(*mac_address), result == BCM_ERR_OK ? "success" : "fail");
+
+
+ mac_util_report_sub_term_event(logical_pon,
+ p_onu_entry->bal_onu_key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ result,
+ result == BCM_ERR_OK ? BCMOLT_RESULT_SUCCESS : BCMOLT_RESULT_FAIL,
+ BCMOLT_ACTIVATION_FAIL_REASON_NONE,
+ result == BCM_ERR_OK ? p_onu_entry->tunnel_id : BCMBAL_INVALID_TUNNEL_ID);
+
+ }
+ while(0);
+
+}
+
+/**
+ * @brief get string for the indication object type for epon
+ */
+static char *mac_util_indication_get_obj_type_str_for_epon (bcmolt_obj_id obj_type)
+{
+ return _mac_util_get_obj_type_str_for_indications (obj_type, mac_util_epon_ind_handlers, BCM_SIZEOFARRAY(mac_util_epon_ind_handlers));
+}
+
+/**
+ * @brief all the maple indication handlers for epon
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ */
+bcmos_errno mac_util_handle_all_olt_ind_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ int i = 0;
+
+ BCM_LOG(DEBUG, log_id_mac_util,
+ "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
+ p_msg->obj_type, mac_util_indication_get_obj_type_str_for_epon(p_msg->obj_type),
+ p_msg->group, p_msg->subgroup);
+
+ for (i=0; i < BCM_SIZEOFARRAY(mac_util_epon_ind_handlers); i++)
+ {
+ if (p_msg->obj_type == mac_util_epon_ind_handlers[i].obj_type)
+ {
+ return mac_util_epon_ind_handlers[i].ind_handler (device_id, p_msg);
+ }
+ }
+
+ /* log an error if unhandled */
+ return BCM_ERR_INTERNAL;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for EPON Link
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_epon_link (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+
+ do
+ {
+ if (BCMOLT_EPON_LINK_AUTO_ID_MPCP_DISCOVERED == p_msg->subgroup)
+ {
+ epon_onu_list_entry *p_onu_entry;
+ bcmolt_epon_link_mpcp_discovered * p_ind = (bcmolt_epon_link_mpcp_discovered*)p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.epon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.epon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "llid indication received obj=%d group=%d subgroup=%d err=%d; "
+ "link_status = %s (%d), llid = (0x%04x) tunnel_id = (0x%08x)\n",
+ p_msg->obj_type, p_msg->group, p_msg->subgroup, p_msg->err,
+ p_ind->data.link_info.link_status==BCMOLT_EPON_LINK_STATUS_DISCOVERED ? "Discovered" : "other",
+ p_ind->data.link_info.link_status,
+ p_ind->data.link_info.llid,
+ p_ind->data.link_info.tunnel_id);
+
+
+
+ if(NULL == (p_onu_entry = epon_onu_list_find_by_mac(&(p_ind->key.mac_address))))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to find epon onu related to received frame captured\n");
+ rc = BCM_ERR_INTERNAL;
+ }
+ else
+ {
+
+ p_onu_entry->tunnel_id = p_ind->data.link_info.tunnel_id;
+ bal_oam_start_oam_negotiation(device_id,
+ p_ind->key.epon_ni,
+ &p_ind->key.mac_address,
+ mac_util_oam_negotiation_cb,
+ p_onu_entry);
+ }
+ }
+ }
+ while(0);
+
+ return rc;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for EPON NI
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_epon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+ do
+ {
+
+ if (BCMOLT_EPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_epon_ni_state_change_completed * p_ind = (bcmolt_epon_ni_state_change_completed *)p_msg;
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.epon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.epon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
+ BCMOLT_EPON_NI_EN_STATE_ENABLED == p_ind->data.new_state ? "up" : "down");
+
+ mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
+ BCMOLT_RESULT_SUCCESS, p_ind->data.new_state);
+ }
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_epon_ni_key *p_pon_key = &(((bcmolt_epon_ni_state_change_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->epon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->epon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj Epon_NI group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+
+
+
+ }
+ while(0);
+ return rc;
+}
+
+
+/**
+ * @brief Maple auto indication register for specific EPON based indications
+ *
+ * @param p_rx_cfg handler config structure
+ * @param device_id specific device id (for multiple devices support)
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_register_for_epon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
+{
+ return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_epon_ind_handlers, BCM_SIZEOFARRAY(mac_util_epon_ind_handlers), device_id);
+}
+#endif /* BAL_EPON_EXCLUDE */
+
+static bcmos_errno mac_util_epon_access_terminal_set(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id,
+ bcmolt_system_mode system_mode,
+ bcmolt_nni_speed nni_speed)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_device_key key = {};
+ bcmolt_device_nni_speed nni_speed_cfg;
+ bcmolt_device_cfg dev_cfg;
+
+ rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ BCMOLT_CFG_INIT(&dev_cfg, device, key);
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, system_mode);
+
+ nni_speed_cfg.first_half = nni_speed;
+ nni_speed_cfg.second_half = nni_speed;
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);
+
+ /** @todo with multiple devices the mechanism to configure acces term will change */
+ rc = bcmolt_cfg_set(device_id, &dev_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ return maple_access_terminal_connect_common(device_id);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_tdma(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA,
+ BCMOLT_NNI_SPEED_GBPS_12P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_tdma(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA,
+ BCMOLT_NNI_SPEED_GBPS_12P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_16_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__16_X,
+ BCMOLT_NNI_SPEED_GBPS_2P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__8_X,
+ BCMOLT_NNI_SPEED_GBPS_2P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__4_X,
+ BCMOLT_NNI_SPEED_GBPS_2P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__8_X_10_G,
+ BCMOLT_NNI_SPEED_GBPS_12P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__4_X_10_G,
+ BCMOLT_NNI_SPEED_GBPS_12P5);
+}
+
+bcmos_errno mac_util_access_terminal_set_for_epon_2_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id)
+{
+ return mac_util_epon_access_terminal_set(
+ p_acc_term,
+ op_type,
+ device_id,
+ BCMOLT_SYSTEM_MODE_EPON__2_X_10_G,
+ BCMOLT_NNI_SPEED_GBPS_12P5);
+}
+
+/**
+ * @brief Command Set setup routine for interface up to mac application for EPON
+ *
+ * This routine is called by if_fsm in the BAL core to initialize the command
+ * set to up the interface of the mac application. The cmdset actually
+ * consists of two commands, one is to send the if up request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param op_type Operation type on access terminal/interface instance
+ *
+ * @return bcmos_errno
+ *
+ */
+bcmos_errno mac_util_interface_set_for_epon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical(intf_key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ return rc;
+ }
+
+ bcmolt_epon_ni_key key;
+ bcmolt_epon_ni_cfg cfg;
+ bcmolt_epon_ni_set_epon_ni_en_state oper;
+
+ key.epon_ni = physical_if_id;
+
+ BCMOLT_CFG_INIT(&cfg, epon_ni, key);
+
+ if (BAL_UTIL_OPER_IF_UP == op_type)
+ {
+ BCMOLT_CFG_PROP_SET(&cfg, epon_ni, registration_behavior, BCMOLT_REGISTRATION_BEHAVIOR_NOTIFY_UNKNOWN);
+
+ bcmolt_cfg_set(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to %s (set) pon interface (%d) - %s, err_text=%s\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
+ rc, bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ return rc;
+ }
+ }
+
+ BCMOLT_OPER_INIT(&oper, epon_ni, set_epon_ni_en_state, key);
+ BCMOLT_OPER_PROP_SET(&oper, epon_ni, set_epon_ni_en_state, new_state,
+ (BAL_UTIL_OPER_IF_UP == op_type ?
+ BCMOLT_EPON_NI_EN_STATE_ENABLED : BCMOLT_EPON_NI_EN_STATE_DISABLED));
+
+ rc = bcmolt_oper_submit(device_id, &oper.hdr);
+
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to %s (submit) pon interface (%d) - %s, err_text=%s\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
+ rc, bcmos_strerror(rc), oper.hdr.hdr.err_text);
+ }
+ else
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Submitted INTERFACE-%s operation for IF %d\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN", intf_key.intf_id);
+ }
+
+ return rc;
+}
+/*---------------------------------------------------------------------------------------------*/
+
+
+
+
+
+#if BAL_EPON_EXCLUDE
+/**
+ * @brief mac_util_validate_subscriber_terminal_info_for_epon
+ *
+ * This routine is used to validate all input attributes required for a sub term setting
+ * received from core for EPON
+ *
+ * @param p_sub_term_req A pointer to a subscriber terminal object
+ *
+ * @return bcmos_errno
+ */
+/*****************************************************************************/
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_epon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
+{
+ if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, mac_address))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "mac_address is a mandatory parameter for an epon subscriber terminal, and it is not set\n");
+ return BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief Command Set setup routine for subscriber terminal connect to mac application for EPON
+ *
+ * This routine is called by sub_term_fsm in the BAL core to initialize the command
+ * set to connect the subscriber terminal of the mac application. The cmdset actually
+ * consists of two commands, one is to send the sub_term request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_sub_term_inst A pointer to a subscriber terminal instance
+ * @param op_type Type of operation being performed on the subscriber terminal instance
+ * @param is_post_discovery This parameter is ignored for epon
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_subscriber_terminal_set_for_epon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
+
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "IN : %s pon_id = %d onu_id= %d "
+ "omci_gem_port = %d\n",
+ __FUNCTION__,
+ p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id, p_sub_term_req->data.svc_port_id);
+
+ if ((BAL_UTIL_OPER_SUB_TERM_ADD != op_type)
+ && (BAL_UTIL_OPER_SUB_TERM_REMOVE != op_type)
+ && (BAL_UTIL_OPER_SUB_TERM_CLEAR != op_type))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Unsupported operation %d for sub_term %u\n",
+ op_type, p_sub_term_req->key.sub_term_id);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ do
+ {
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ epon_onu_list_entry * p_new_epon_onu_entry;
+ bcmolt_epon_ni_key key;
+ bcmolt_epon_ni_add_link oper;
+
+ key.epon_ni = physical_if_id;
+ BCMOLT_OPER_INIT(&oper, epon_ni, add_link, key);
+
+ if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
+ {
+
+ BCMOLT_OPER_PROP_SET(&oper, epon_ni, add_link, mac_address, p_sub_term_req->data.mac_address);
+ BCMOLT_OPER_PROP_SET(&oper, epon_ni, add_link, rate, BCMOLT_EPON_LINK_RATE_TEN_TEN);
+ rc = bcmolt_oper_submit(device_id, &oper.hdr);
+
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to register epon onu epon_ni = %d mac : "_mac_addr_fmt_str" rc = %d (%s), err_text=%s\n",
+ key.epon_ni, _mac_addr_data(p_sub_term_req->data.mac_address), rc, bcmos_strerror(rc),
+ oper.hdr.hdr.err_text);
+ break;
+ }
+ /* add the new epon onu to the epon onu list to follow indications and oam sending */
+ p_new_epon_onu_entry = bcmos_calloc(sizeof(epon_onu_list_entry));
+ if (NULL == p_new_epon_onu_entry)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to allocate the epon onu entry\n");
+ rc = BCM_ERR_NOMEM;
+ break;
+ }
+
+ memcpy(&p_new_epon_onu_entry->bal_onu_key, &p_sub_term_req->key,
+ sizeof(bcmbal_subscriber_terminal_key));
+ p_new_epon_onu_entry->mac_address = p_sub_term_req->data.mac_address;
+ p_new_epon_onu_entry->oam_provision_state = OAM_PROVISION_STATE_IDLE;
+ p_new_epon_onu_entry->waiting_flows_num = 0;
+
+ epon_onu_list_add(p_new_epon_onu_entry);
+ }
+ else
+ {
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ BCM_ERR_OK, BCMOLT_RESULT_SUCCESS,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+
+ epon_onu_list_remove_by_key(&p_sub_term_req->key);
+
+ }
+ } while (0);
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "OUT : going out of %s rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+
+
+ return rc;
+}
+
+
+
+
+
+static bcmos_errno maple_us_sla_configure_epon(bcmbal_flow_cfg *flow_entry, bcmos_mac_address *mac)
+{
+ bcmolt_epon_link_key epon_link_key;
+ bcmolt_epon_link_cfg epon_link_cfg;
+ bcmolt_upstream_bandwidth_distribution us_bw_dist = {};
+
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (flow_entry->data.access_int_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(flow_entry->data.access_int_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ }
+ else
+ {
+
+ epon_link_key.epon_ni = physical_if_id;
+ epon_link_key.mac_address = *mac;
+ BCMOLT_CFG_INIT(&epon_link_cfg, epon_link, epon_link_key);
+
+ us_bw_dist.polling_interval_us = BCMOLT_POLLING_INTERVAL_AUTOMATIC;
+ if (BCMBAL_ATTRIBUTE_PROP_IS_SET(&flow_entry->data.sla, sla, min_rate))
+ {
+ us_bw_dist.min_schedulershaper.bandwidth_Kbps = flow_entry->data.sla.min_rate;
+ }
+ if (BCMBAL_ATTRIBUTE_PROP_IS_SET(&flow_entry->data.sla, sla, max_rate))
+ {
+ us_bw_dist.max_schedulershaper.bandwidth_Kbps = flow_entry->data.sla.max_rate;
+ }
+ else
+ {
+ us_bw_dist.max_schedulershaper.bandwidth_Kbps = 10000000;
+ }
+ us_bw_dist.max_schedulershaper.priority = 7;
+
+ BCMOLT_CFG_PROP_SET(&epon_link_cfg, epon_link, upstream_bandwidth, us_bw_dist);
+ return bcmolt_cfg_set(device_id, &epon_link_cfg.hdr);
+ }
+
+ return rc;
+}
+
+
+
+
+
+
+/**
+ * @brief flow set for EPON
+ *
+ * @param p_flow_req pointer to flow request structure from core
+ * @param op_type ADD, REMOVE or CLEAR
+ * @param p_flow_core local DB flow context passed as a cookie
+ *
+ * @return errno error
+ */
+bcmos_errno mac_util_flow_set_for_epon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ epon_onu_list_entry *p_onu_entry;
+ bcmos_mac_address mac;
+ bcmbal_subscriber_terminal_key key;
+
+
+ key.intf_id = p_flow_req->data.access_int_id;
+ key.sub_term_id = p_flow_req->data.sub_term_id;
+
+ if(NULL != (p_onu_entry = epon_onu_list_find_by_key(&key)))
+ {
+ mac = p_onu_entry->mac_address;
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "failed to configure flow, "
+ "subscriber terminal if=%d sub-term id = %d was not found - no such device\n",
+ p_flow_req->data.access_int_id, p_flow_req->data.sub_term_id);
+
+ return BCM_ERR_NOENT;
+ }
+
+
+
+ if (BAL_UTIL_OPER_FLOW_ADD == op_type)
+ {
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id), "add, context is %p\n", p_flow_context);
+
+ switch (p_onu_entry->oam_provision_state)
+ {
+ case OAM_PROVISION_STATE_IDLE:
+ {
+ p_onu_entry->flow_keys[p_onu_entry->waiting_flows_num++] = p_flow_req->key;
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "add p_onu_entry-> %p, waiting flows: %d context is %p\n",
+ p_onu_entry, p_onu_entry->waiting_flows_num, p_flow_context);
+
+ rc = maple_us_sla_configure_epon(p_flow_req, &mac);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "Unable to configure EPON US SLA (%s)\n", bcmos_strerror(rc));
+
+ break;
+ }
+
+ p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_STARTED;
+
+ bal_oam_configure_traffic(maple_device_from_interface_get(p_flow_req->data.access_int_id),
+ p_flow_req->data.access_int_id,
+ &mac,
+ BCMOS_TRUE,
+ mac_util_configure_traffic_cb, p_flow_context);
+ }
+ break;
+
+
+ case OAM_PROVISION_STATE_STARTED:
+ {
+ if (p_onu_entry->waiting_flows_num < MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC)
+ {
+ p_onu_entry->flow_keys[p_onu_entry->waiting_flows_num++] = p_flow_req->key;
+ }
+ else
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "failed to configure flow for that mac, "
+ "too many flows already waiting for oam configuration\n");
+ rc = BCM_ERR_INSUFFICIENT_LIST_MEM;
+ }
+ }
+ break;
+
+
+ case OAM_PROVISION_STATE_COMPLETED:
+ {
+ mac_util_report_flow_add_success(p_flow_req->key, p_flow_req->data.access_int_id);
+ }
+ break;
+
+
+ case OAM_PROVISION_STATE_FAIL:
+ default:
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "failed to configure oam traffic for that mac,\n"); /* currently no failure indications */
+ }
+ break;
+ }
+ }
+ else /* REMOVE or CLEAR FLOW */
+ {
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "delete p_onu_entry-> %p, waiting flows: %d, provisioned state is %d, context is %p\n",
+ p_onu_entry,
+ p_onu_entry->waiting_flows_num,
+ p_onu_entry->oam_provision_state,
+ p_flow_context);
+
+ switch (p_onu_entry->oam_provision_state)
+ {
+ case OAM_PROVISION_STATE_IDLE:
+ {
+ mac_util_report_flow_remove_success(p_flow_req->key, p_flow_req->data.access_int_id, op_type);
+ }
+ break;
+
+ case OAM_PROVISION_STATE_COMPLETED:
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "calling bal_oam_configure_traffic w/ \"Disable\" state\n");
+
+ bal_oam_configure_traffic(maple_device_from_interface_get(p_flow_req->data.access_int_id),
+ p_flow_req->data.access_int_id,
+ &mac,
+ BCMOS_FALSE,
+ mac_util_unconfigure_traffic_cb,
+ p_flow_context);
+ }
+ break;
+
+ case OAM_PROVISION_STATE_FAIL:
+ case OAM_PROVISION_STATE_STARTED:
+ default:
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
+ "failed to unconfigure oam traffic for that mac,\n"); /* currently no failure indications */
+ }
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static void mac_util_configure_traffic_cb(void *context,
+ bcmolt_devid device_id,
+ bcmolt_epon_ni epon_ni,
+ const bcmos_mac_address *mac_address,
+ bcmos_errno result)
+{
+ epon_onu_list_entry *p_onu_entry;
+ int i;
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
+ "configure device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
+ device_id, epon_ni, _mac_addr_data(*mac_address), result == BCM_ERR_OK ? "success" : "fail");
+
+
+ if(NULL == (p_onu_entry = epon_onu_list_find_by_mac(mac_address)))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
+ "FAIL - received configure traffic cb for mac that was not configured " _mac_addr_fmt_str "\n",
+ _mac_addr_data(*mac_address));
+ return;
+ }
+
+ if (OAM_PROVISION_STATE_STARTED != p_onu_entry->oam_provision_state)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
+ "FAIL - received configure traffic cb for mac that is in the wrong state (%d)\n",
+ p_onu_entry->oam_provision_state);
+ return;
+ }
+
+ if (result == BCM_ERR_OK)
+ {
+ p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_COMPLETED;
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni), "Moved ONU to OAM COMPLETED state\n");
+
+ for (i=0; i<p_onu_entry->waiting_flows_num; i++)
+ {
+ mac_util_report_flow_add_success(p_onu_entry->flow_keys[i], epon_ni);
+ }
+ }
+ else
+ {
+ p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_FAIL;
+ }
+
+ p_onu_entry->waiting_flows_num = 0; /* currently we dont send fail indication */
+}
+
+/** EPON specific traffic unconfigure; Not used for GPON mode */
+static void mac_util_unconfigure_traffic_cb(void *context,
+ bcmolt_devid device_id,
+ bcmolt_epon_ni epon_ni,
+ const bcmos_mac_address *mac_address,
+ bcmos_errno result)
+{
+ flow_inst *p_flow_core = (flow_inst *)(context);
+ epon_onu_list_entry *p_onu_entry;
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
+ "unconfigure device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
+ device_id,
+ epon_ni,
+ _mac_addr_data(*mac_address),
+ result == BCM_ERR_OK ? "success" : "fail");
+
+
+ /** @todo need to pass on the actual op type (REMOVE or CLEAR) */
+ mac_util_report_flow_remove_success(p_flow_core->current_flow_info.key, epon_ni, BAL_UTIL_OPER_FLOW_REMOVE);
+
+ if(NULL != (p_onu_entry = epon_onu_list_find_by_mac(mac_address)))
+ {
+ p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_IDLE;
+ }
+}
+
+
+
+/**
+ * @brief used for epon oam message handling
+ *
+ * @param device_id bcm dev id
+ * @param p_msg oam msg pointer
+ */
+void bal_proxy_rx_cb_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmolt_proxy_rx *proxy_rx = (bcmolt_proxy_rx *)p_msg;
+
+ bcmolt_user_appl_eon_process_rx(device_id, proxy_rx);
+ bcmolt_user_appl_epon_oam_handle_rx(device_id, proxy_rx, bal_oam_proxy_rx_cb);
+
+ /** @note the free of p_msg is done in caller function */
+}
+
+
+/**
+ * @brief init for epon oam and eon
+ *
+ */
+static void mac_util_init_oam_for_epon (void)
+{
+ bcmolt_user_appl_epon_oam_init();
+ bcmolt_user_appl_eon_init();
+}
+
+
+
+
+static void epon_onu_list_add(epon_onu_list_entry *epon_onu_entry)
+{
+ TAILQ_INSERT_HEAD(&epon_onu_list, epon_onu_entry, next);
+ return;
+}
+
+static void epon_onu_list_remove_by_key(bcmbal_subscriber_terminal_key *key)
+{
+ epon_onu_list_entry *p_onu_entry = NULL;
+
+ if(NULL != (p_onu_entry = epon_onu_list_find_by_key(key)))
+ {
+ TAILQ_REMOVE(&epon_onu_list, p_onu_entry, next);
+ bcmos_free(p_onu_entry);
+ }
+
+ return;
+}
+
+static epon_onu_list_entry *epon_onu_list_find_by_mac(const bcmos_mac_address *mac_address)
+{
+ epon_onu_list_entry *p_onu_entry = NULL;
+ epon_onu_list_entry *current_onu_entry;
+
+ TAILQ_FOREACH(current_onu_entry, &epon_onu_list, next)
+ {
+ if (memcmp(¤t_onu_entry->mac_address, mac_address, sizeof(bcmos_mac_address))==0)
+ {
+ p_onu_entry = current_onu_entry;
+ break;
+ }
+ }
+
+ return p_onu_entry;
+}
+
+static epon_onu_list_entry *epon_onu_list_find_by_key(bcmbal_subscriber_terminal_key *key)
+{
+ epon_onu_list_entry *p_onu_entry = NULL;
+ epon_onu_list_entry *current_onu_entry;
+
+ TAILQ_FOREACH(current_onu_entry, &epon_onu_list, next)
+ {
+ if ((current_onu_entry->bal_onu_key.intf_id == key->intf_id) &&
+ (current_onu_entry->bal_onu_key.sub_term_id == key->sub_term_id))
+ {
+ p_onu_entry = current_onu_entry;
+ break;
+ }
+ }
+
+ return p_onu_entry;
+}
+#endif /* BAL_EPON_EXCLUDE */
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_epon.h b/bal_release/src/core/util/mac/bal_mac_util_epon.h
new file mode 100644
index 0000000..68da0df
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_epon.h
@@ -0,0 +1,109 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_epon.h
+ *
+ * @brief mac util interfaces definition used by Bal Core, for EPON
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+
+/* Temporarily exclude some code to get this module compiling again - we should get rid of this ASAP */
+#define BAL_EPON_EXCLUDE 0
+
+#if BAL_EPON_EXCLUDE
+bcmos_errno mac_util_handle_all_olt_ind_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+bcmos_errno mac_util_register_for_epon_auto_indications(struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id);
+#endif /* BAL_EPON_EXCLUDE */
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_tdma(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_tdma(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_16_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_1g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_8_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_4_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_access_terminal_set_for_epon_2_10g(
+ acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term op_type,
+ bcmolt_devid device_id);
+
+bcmos_errno mac_util_interface_set_for_epon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type);
+
+#if BAL_EPON_EXCLUDE
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_epon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req);
+
+bcmos_errno mac_util_subscriber_terminal_set_for_epon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery);
+
+bcmos_errno mac_util_flow_set_for_epon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core);
+
+void bal_proxy_rx_cb_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg);
+#endif /* BAL_EPON_EXCLUDE */
+
+/*@}*/
+
diff --git a/bal_release/src/core/util/mac/bal_mac_util_gpon.c b/bal_release/src/core/util/mac/bal_mac_util_gpon.c
new file mode 100644
index 0000000..b08efd6
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_gpon.c
@@ -0,0 +1,1961 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_gpon.c
+ *
+ * @brief mac util interfaces definition used by Bal Core, for GPON
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_common_itu_pon.h>
+
+static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+/** @brief array stores the list of GPON related auto indications from Maple to subscribe */
+static mac_util_ind_obj_and_handlers mac_util_gpon_ind_handlers[] =
+{
+ {BCMOLT_OBJ_ID_GPON_NI, "BCMOLT_OBJ_ID_GPON_NI", mac_util_indication_handle_for_gpon_ni},
+ {BCMOLT_OBJ_ID_GPON_ONU, "BCMOLT_OBJ_ID_GPON_ONU", mac_util_indication_handle_for_gpon_onu},
+ {BCMOLT_OBJ_ID_GPON_ALLOC, "BCMOLT_OBJ_ID_GPON_ALLOC", mac_util_indication_handle_for_gpon_alloc_id},
+ {BCMOLT_OBJ_ID_GPON_GEM_PORT, "BCMOLT_OBJ_ID_GPON_GEM_PORT", mac_util_indication_handle_for_gpon_gem_port}
+};
+
+
+/**
+ * @brief Map bal GPON transceiver type to bcm68620 transceiver type
+ */
+static bcmolt_trx_type mac_gpon_bal_trx_type2bcm68620_trx_type(bcmbal_trx_type bal_trx_type, bcmbal_intf_id intf_id)
+{
+ bcmolt_trx_type trx_type = BCMOLT_TRX_TYPE__NUM_OF;
+
+ switch (bal_trx_type)
+ {
+ case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
+ trx_type = BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013;
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
+ trx_type = BCMOLT_TRX_TYPE_SOG_4321_PSGB;
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
+ trx_type = BCMOLT_TRX_TYPE_LTE_3680_M;
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
+ trx_type = BCMOLT_TRX_TYPE_SOURCE_PHOTONICS;
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
+ trx_type = BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS;
+ break;
+ default:
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_id), "Invalid trx_type %d\n", bal_trx_type);
+ }
+ return trx_type;
+}
+
+
+
+
+/**
+ * @brief all the maple indication handlers for gpon
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ */
+bcmos_errno mac_util_handle_all_olt_ind_for_gpon (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ BCM_LOG(DEBUG, log_id_mac_util,
+ "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
+ p_msg->obj_type, mac_util_indication_get_obj_type_str(p_msg->obj_type, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers)),
+ p_msg->group, p_msg->subgroup);
+
+ return mac_util_handle_indication(device_id, p_msg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers));
+}
+
+/**
+ * @brief Handler function for Maple auto indications for GPON NI
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+
+ do
+ {
+
+ /* PON activation */
+ if (BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_gpon_ni_state_change_completed * p_ind = (bcmolt_gpon_ni_state_change_completed*)p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
+ BCMOLT_PON_STATE_ACTIVE_WORKING == p_ind->data.new_state ? "up" : "down");
+
+ /* if we got something from MAC HW, then it has to be PON interface */
+ mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
+ p_ind->data.result, p_ind->data.new_state);
+
+ }
+ else if(BCMOLT_GPON_NI_AUTO_CFG_ID_ONU_DISCOVERED == p_msg->subgroup)
+ {
+ bcmolt_gpon_ni_onu_discovered *p_ind =
+ (bcmolt_gpon_ni_onu_discovered *)p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Pon if %d (ONUID:%d) found ONU serial number "
+ "%c%c%c%c%d%d%d%d%d%d%d%d\n",
+ logical_pon,
+ p_ind->data.onu_id,
+ p_ind->data.serial_number.vendor_id[0],
+ p_ind->data.serial_number.vendor_id[1],
+ p_ind->data.serial_number.vendor_id[2],
+ p_ind->data.serial_number.vendor_id[3],
+ p_ind->data.serial_number.vendor_specific[0]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[0] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[1]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[1] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[2]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[2] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[3]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[3] & 0x0f
+ );
+
+ bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->data.onu_id,
+ &p_ind->data.serial_number,
+ BAL_UTIL_OPER_SUB_TERM_DISCOVERY,
+ p_msg->err, BCMOLT_RESULT_SUCCESS,
+ BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_gpon_ni_key *p_pon_key = &(((bcmolt_gpon_ni_state_change_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj Gpon_NI group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+
+ }
+ while(0);
+ return rc;
+}
+
+
+
+/**
+ * @brief Handler function for Maple auto indications for GPON ONU
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_gpon_onu_key *p_gpon_onu_key = &(((bcmolt_gpon_onu_onu_activation_completed*)p_msg)->key);
+
+ do
+ {
+ if (BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_ACTIVATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_gpon_onu_onu_activation_completed *p_ind = (bcmolt_gpon_onu_onu_activation_completed*) p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_ind->key.pon_ni),
+ "sub_term %d (PON%d) activation indication (%s)\n",
+ p_ind->key.onu_id,
+ p_ind->key.pon_ni,
+ bcmos_strerror(p_msg->err));
+
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->key.onu_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ p_msg->err, p_ind->data.status,
+ p_ind->data.fail_reason, BCMBAL_INVALID_TUNNEL_ID);
+
+ }
+ else if(BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_DEACTIVATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_gpon_onu_onu_deactivation_completed *p_ind = (bcmolt_gpon_onu_onu_deactivation_completed*) p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "sub_term %d (PON%d) deactivation indication (%s)\n",
+ p_ind->key.onu_id,
+ logical_pon,
+ bcmos_strerror(p_msg->err));
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->key.onu_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ p_msg->err, p_ind->data.status,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+ else
+ {
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_gpon_onu_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_gpon_onu_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj GPON_ONU group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ break;
+ }
+
+ rc = mac_util_update_flows_w_sub_term_update(logical_pon, p_gpon_onu_key->onu_id, maple_gpon_mac_check_gem_port_id, maple_gpon_mac_get_alloc_id_config);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to update related flows pon_id = %d onu_id = %d (%s)\n", logical_pon, p_gpon_onu_key->onu_id, bcmos_strerror(rc));
+ break;
+ }
+
+ }
+ while(0);
+ return rc;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for GPON Alloc Id
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+ tm_sched_inst* p_tm_sched_inst = NULL;
+ do
+ {
+ if (BCMOLT_GPON_ALLOC_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_gpon_alloc_configuration_completed *p_ind = (bcmolt_gpon_alloc_configuration_completed*) p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ /* Find tn_mode inst owned by that alloc_id and ni */
+ p_tm_sched_inst = tm_sched_find_agg_port_node(logical_pon, p_ind->key.alloc_id);
+ if (NULL == p_tm_sched_inst )
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to find tm sched owned by that agg port (intf %d id %d)\n", logical_pon,p_ind->key.alloc_id);
+ rc = BCM_ERR_NOENT;
+ break;
+ }
+ /*the tm owned by that alloc found, update it with the ind*/
+ mac_util_report_tm_sched_set_indication(p_tm_sched_inst->req_tm_sched_info.key ,p_msg->err, p_ind->data.status);
+ }
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_gpon_alloc_key *p_pon_key = &(((bcmolt_gpon_alloc_configuration_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj GPON_ALLOC group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+ }while (0);
+ return rc;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for GPON GEM Port
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+ flow_list_entry *p_current_entry = NULL;
+ void *p_rsc_mgr_curr_entry = NULL;
+ void *p_rsc_mgr_next_entry = NULL;
+
+ do
+ {
+
+ if (BCMOLT_GPON_GEM_PORT_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_gpon_gem_port_configuration_completed *p_ind =
+ (bcmolt_gpon_gem_port_configuration_completed *) p_msg;
+
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ /* Find all entries in flows list matching the gem port id and pon ni */
+ /* use safe walk here because an entry can be removed from list during the walk */
+ /* get first */
+ p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ while (NULL != p_current_entry)
+ {
+ /** @note For now this assumes that there is only one op type (add or remove) ,
+ * that all the flows in an onu are waiting for. We can not have flows waiting on same
+ * gem for multiple op types, because Maple does not allow multiple configs with
+ * different op types at the same time.
+ */
+ /* update gem port complete configuration indication received */
+ p_current_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
+ /* check if should send flow configuration indication complete to bal core */
+ rc = check_send_flow_bal_ind_msg(p_current_entry, p_msg->err, p_ind->data.status);
+
+ /* any DB cleanup for error should be triggered by Core fsm
+ * (mac util should not cleanup on its own)
+ * */
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to send flow configured ind: Error %s, gem port id = %d, pon ni = %d\n",
+ bcmos_strerror(rc), p_ind->key.gem_port_id, logical_pon);
+ /* don't break, but continue to check if more flows use the same gem port id */
+ }
+
+ /* get next */
+ p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
+ }
+ }
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_gpon_gem_port_key *p_pon_key = &(((bcmolt_gpon_gem_port_configuration_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj GPON_GEM_PORT group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+
+ }
+ while(0);
+ return rc;
+}
+
+/**
+ * @brief Maple auto indication register for specific GPON based indications
+ *
+ * @param p_rx_cfg handler config structure
+ * @param device_id specific device id (for multiple devices support)
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_register_for_gpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
+{
+ return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers), device_id);
+}
+
+/*****************************************************************************/
+/**
+ * @brief Map iwf_mode to bcmolt_iwf_mode
+ *
+ * @param bal_iwf_mode BAL iwfmode
+ * @return bcm68620 iwf mode
+ */
+static bcmolt_iwf_mode bal_iwf_mode2iwf_mode(bcmbal_iwf_mode bal_iwf_mode)
+{
+ bcmolt_iwf_mode iwf_mode = BCMOLT_IWF_MODE__NUM_OF;
+ switch (bal_iwf_mode)
+ {
+ case BCMBAL_IWF_MODE_DIRECT_MAPPING:
+ iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
+ break;
+ case BCMBAL_IWF_MODE_PER_FLOW:
+ iwf_mode = BCMOLT_IWF_MODE_PER_FLOW_MODE;
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_mac_util, "Invalid iwf_mode %d\n", bal_iwf_mode);
+ }
+ return iwf_mode;
+}
+
+static bcmos_errno mac_util_access_terminal_set_for_gpon (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_system_mode system_mode, bcmolt_devid device_id)
+{
+ bcmolt_device_key key = {};
+ bcmolt_device_nni_speed nni_speed_cfg;
+ bcmolt_device_cfg dev_cfg;
+ bcmolt_iwf_mode iwf_mode;
+ uint32_t logical_pon;
+
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&(p_acc_term->api_req_acc_term_obj_info), access_terminal, iwf_mode))
+ {
+ iwf_mode = bal_iwf_mode2iwf_mode(p_acc_term->api_req_acc_term_obj_info.data.iwf_mode);
+ }
+ else
+ {
+ iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
+ }
+
+ BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
+ {
+ mac_util_topo_pon_context *topo_context, *old_topo_context;
+
+ old_topo_context = bcm_topo_pon_get_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
+ if (old_topo_context)
+ bcmos_free(old_topo_context);
+
+ topo_context = bcmos_calloc(sizeof(*topo_context));
+ topo_context->iwf_mode = iwf_mode;
+ bcm_topo_pon_set_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL, topo_context);
+ }
+
+ BCMOLT_CFG_INIT(&dev_cfg, device, key);
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, acc_term_connectivity.devices[device_id].system_mode);
+
+#ifdef QAX_SWITCH
+ /* until speed is configurable through topology settings hardcode it based on switch type */
+ BCM_LOG(INFO, log_id_mac_util, "nni speed is: 10G\n");
+ nni_speed_cfg.first_half = BCMOLT_NNI_SPEED_GBPS_10;
+ nni_speed_cfg.second_half = BCMOLT_NNI_SPEED_GBPS_10;
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);
+#endif
+
+ return bcmolt_cfg_set(device_id, &dev_cfg.hdr);
+}
+
+/**
+ * @brief access terminal set for gpon_16
+ */
+bcmos_errno mac_util_access_terminal_set_for_gpon_16 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+ rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+ rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__16_X, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+ return maple_access_terminal_connect_common(device_id);
+
+}
+
+/**
+ * @brief access terminal set for gpon_8
+ */
+bcmos_errno mac_util_access_terminal_set_for_gpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+
+ rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+ rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__8_X, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+ return maple_access_terminal_connect_common(device_id);
+}
+
+/**
+ * @brief post access terminal up configurations on Maple
+ */
+bcmos_errno mac_util_access_terminal_post_indication_set_for_gpon(bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_devid dummy;
+ uint32_t physical_if_id;
+ uint32_t logical_pon = BCM_TOPO_PON_INVALID;
+ bcmolt_gpon_ni_key ni_key = {};
+ bcmolt_gpon_ni_cfg ni_cfg = {};
+ bcmolt_gpon_sn_acquisition sn_acquisition_cfg = {};
+ bcmolt_gpon_ni_auto_cfg gpon_ni_auto_cfg = {}; /* main auto cfg api struct */
+
+ /* configure one time settings for all the interfaces on this device */
+ BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
+ {
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (logical_pon, &dummy, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ ni_key.pon_ni = physical_if_id;
+
+
+ /* Set the SN acquisition mode to enable */
+ BCMOLT_CFG_INIT(&ni_cfg, gpon_ni, ni_key);
+
+ sn_acquisition_cfg.control = BCMOLT_CONTROL_STATE_ENABLE;
+ sn_acquisition_cfg.interval = 5000;
+ sn_acquisition_cfg.onu_post_discovery_mode = BCMOLT_ONU_POST_DISCOVERY_MODE_NONE;
+
+ BCMOLT_CFG_PROP_SET(&ni_cfg, gpon_ni, sn_acquisition, sn_acquisition_cfg);
+
+ rc = bcmolt_cfg_set(device_id, &ni_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to set sn acquisition configuration (%s), err_text=%s)\n",
+ bcmos_strerror(rc), ni_cfg.hdr.hdr.err_text);
+ break;
+ }
+
+
+ /* turn off the auto indication messages for gpon_ni.serial_number_acquisition_cycle_start */
+ BCMOLT_AUTO_CFG_INIT(&gpon_ni_auto_cfg, gpon_ni, ni_key);
+ BCMOLT_AUTO_CFG_PROP_SET(&gpon_ni_auto_cfg, gpon_ni, serial_number_acquisition_cycle_start, BCMOS_FALSE);
+ rc = bcmolt_auto_cfg_set(device_id, &gpon_ni_auto_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "bcmolt_auto_cfg_set for gpon_ni.serial_number_acquisition_cycle_start, Failed (%s), err_text=%s)\n",
+ bcmos_strerror(rc), gpon_ni_auto_cfg.hdr.hdr.err_text);
+
+ /* ignore any error, just continue anyway */
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * @brief Command Set setup routine for interface up to mac application for GPON
+ *
+ * This routine is called by if_fsm in the BAL core to initialize the command
+ * set to up the interface of the mac application. The cmdset actually
+ * consists of two commands, one is to send the if up request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param op_type Operation type on access terminal/interface instance
+ *
+ * @return bcmos_errno
+ *
+ */
+bcmos_errno mac_util_interface_set_for_gpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_interface_cfg *p_interface_req = &(p_interface_inst->api_req_int_obj_info);
+ bcmbal_interface_key intf_key = p_interface_req->key;
+ mac_util_topo_pon_context *topo_context;
+
+ do
+ {
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (intf_key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+
+ bcmolt_gpon_ni_set_pon_state oper_ni;
+ bcmolt_gpon_ni_key ni_key = { .pon_ni = physical_if_id };
+ bcmolt_gpon_trx_cfg cfg = {};
+ bcmolt_gpon_trx_key trx_key = { .pon_ni = physical_if_id };
+ bcmolt_trx_type trx_type;
+ bcmolt_gpon_iwf_key iwf_key = { .pon_ni = physical_if_id };
+ bcmolt_gpon_iwf_cfg iwf_cfg = {};
+ bcmolt_mac_table_configuration mac_table_configuration = {};
+
+ if (BAL_UTIL_OPER_IF_UP == op_type)
+ {
+
+ /* set the pon_ni transceiver configuration */
+ BCMOLT_CFG_INIT(&cfg, gpon_trx, trx_key);
+
+ /* If the user didn't specify a transceiver, then use the default */
+ if (BCMOS_TRUE != BCMBAL_CFG_PROP_IS_SET(p_interface_req, interface, transceiver_type))
+ {
+ /* The user didn't choose a transceiver type, so override it here
+ * with the default value for GPON
+ */
+ BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_GPON);
+ }
+
+ /* Set the (default or chosen) transceiver configuration into the MAC device */
+ trx_type = mac_gpon_bal_trx_type2bcm68620_trx_type(p_interface_req->data.transceiver_type, intf_key.intf_id);
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_trx, transceiver_type, trx_type);
+
+ rc = bcmolt_cfg_set(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to set trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ break;
+ }
+
+
+ /* Configure pon_ni interworking and mac table configuration based on the system global interworking mode
+ *
+ * We only have to change the mode if the user has chosen per-flow, because direct mode is the default
+ * iwf mode in MAPLE
+ */
+ topo_context = bcm_topo_pon_get_context(intf_key.intf_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
+ if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
+ {
+ /* set the iwf configuration */
+ BCMOLT_CFG_INIT(&iwf_cfg, gpon_iwf, iwf_key);
+ BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, iwf_mode, BCMOLT_IWF_MODE_PER_FLOW_MODE);
+ /* set the mac table configuration */
+ mac_table_configuration.aging_time = 10000;
+ mac_table_configuration.automatic_mac_move = BCMOLT_CONTROL_STATE_DISABLE;
+ mac_table_configuration.automatic_static_mode = BCMOLT_CONTROL_STATE_DISABLE;
+ mac_table_configuration.default_flow_id = 0;
+ mac_table_configuration.learning_mode = BCMOLT_MAC_TABLE_LEARNING_MODE_NORMAL;
+ mac_table_configuration.miss_fallback = BCMOLT_MAC_TABLE_MISS_FALLBACK_DROP;
+ mac_table_configuration.automatic_mac_learning = BCMOLT_CONTROL_STATE_ENABLE;
+ mac_table_configuration.automatic_mac_aging = BCMOLT_CONTROL_STATE_ENABLE;
+ BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, mac_table_configuration, mac_table_configuration);
+
+ rc = bcmolt_cfg_set(device_id, &iwf_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to set iwf / mac table configuration (%s), err_text=%s)\n",
+ bcmos_strerror(rc), iwf_cfg.hdr.hdr.err_text);
+ break;
+ }
+ }
+ }
+
+
+ /* invoke the pon_ni state change to the requested state */
+ BCMOLT_OPER_INIT(&oper_ni, gpon_ni, set_pon_state, ni_key);
+ BCMOLT_OPER_PROP_SET(&oper_ni, gpon_ni, set_pon_state, pon_state,
+ (BAL_UTIL_OPER_IF_UP == op_type) ?
+ BCMOLT_PON_OPERATION_ACTIVE_WORKING : BCMOLT_PON_OPERATION_INACTIVE);
+ rc = bcmolt_oper_submit(device_id, &oper_ni.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to %s (submit) pon interface (%s), err_text=%s\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
+ bcmos_strerror(rc), oper_ni.hdr.hdr.err_text);
+ }
+
+ } while (0);
+
+ if (BCM_ERR_OK == rc)
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Submitted INTERFACE-%s operation for IF %d\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN",
+ intf_key.intf_id);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_ds_iwf_cfg
+ *
+ * This routine is used to configure the relevant downstream ingress and egress iwf at the device
+ *
+ * @param p_flow Pointer to the flow info
+ * @param per_flow_mode_vlan_id vlan id for GEM port mapping in per flow mode
+ * @param is_pbit_enabled Flag indicating whether or not to resolve pbits to GEM IDs
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_ds_iwf_cfg(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bcmos_bool is_pbit_enabled)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
+ bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
+ bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
+ bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+
+ do
+ {
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ /* configure the new ds ingress flow */
+ in_key.pon_ni = physical_if_id;
+ in_key.vlan_id = per_flow_mode_vlan_id;
+ BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
+ if (BCMOS_TRUE == p_flow->data.resolve_mac)
+ {
+ /* mapping method */
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
+ BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_MACPLUSVID);
+ }
+ else
+ {
+ /* mapping method */
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
+ BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_VID);
+ }
+
+ /* mapping tag */
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_tag,
+ BCMOLT_MAPPING_TAG_METHOD_OUTER_VID);
+ BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, vlan_action, BCMOLT_DS_VLAN_ACTION_TRANSPARENT);
+
+ rc = bcmolt_cfg_set(device_id, &in_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to configure ingress flow pon_ni = %d vlan_id = %d rc = %s (%d), err_text=%s\n",
+ in_key.pon_ni,
+ in_key.vlan_id,
+ bcmos_strerror(rc),
+ rc,
+ in_cfg.hdr.hdr.err_text);
+ break;
+ }
+
+
+ /* configure the new ds egress flow */
+ egr_key.pon_ni = physical_if_id;
+ egr_key.flow_id = p_flow->data.svc_port_id;
+
+ /* Configure DS egress handling: flow -> GEM */
+ BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
+ BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, gem_port, p_flow->data.svc_port_id);
+ BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, pbit_control, is_pbit_enabled);
+
+ rc = bcmolt_cfg_set(device_id, &egr_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to configure egress flow pon_ni = %d flow_id = %d rc = %s (%d), err_text=%s\n",
+ egr_key.pon_ni,
+ egr_key.flow_id,
+ bcmos_strerror(rc),
+ rc,
+ egr_cfg.hdr.hdr.err_text);
+ }
+
+ } while (0);
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "going out of %s rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_ds_iwf_cfg_remove
+ *
+ * This routine is used to remove configuration from Maple of the relevant downstream ingress and egress iwf
+ *
+ * @param p_flow Pointer to the flow info
+ * @param per_flow_mode_vlan_id vlan id for per flow mode
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_ds_iwf_cfg_remove(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
+ bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
+ bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
+ bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ do
+ {
+ /* config clear ds ingress flow */
+ rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ in_key.pon_ni = physical_if_id;
+ in_key.vlan_id = per_flow_mode_vlan_id;
+ BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
+
+ rc = bcmolt_cfg_clear(device_id, &in_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to Clear ingress flow pon_ni = %d vlan_id = %d rc = %s (%d)\n",
+ in_key.pon_ni,
+ in_key.vlan_id,
+ bcmos_strerror(rc),
+ rc);
+ break;
+ }
+
+
+ /* config clear ds egress flow */
+ egr_key.pon_ni = physical_if_id;
+ egr_key.flow_id = p_flow->data.svc_port_id;
+
+ /* Configure DS egress handling: flow -> GEM */
+ BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
+
+ rc = bcmolt_cfg_clear(device_id, &egr_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to Clear egress flow pon_ni = %d flow_id = %d rc = %s (%d)\n",
+ egr_key.pon_ni,
+ egr_key.flow_id,
+ bcmos_strerror(rc),
+ rc);
+ }
+
+ } while (0);
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s: config clear: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_us_iwf_cfg
+ *
+ * This routine is used to configure the relevant upstream iwf at the device
+ *
+ * @param p_flow A pointer to a flow object
+ *
+ * @param pbit A pbit value being configured for the specified flow
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_us_iwf_cfg(bcmbal_flow_cfg *p_flow, uint8_t pbit)
+{
+ bcmos_errno rc = BCM_ERR_PARM;
+ bcmolt_gpon_iwf_us_flow_key us_key = {};
+ bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ }
+ else
+ {
+ /* configure the related iwf us flow */
+ us_key.pon_ni = physical_if_id;
+ us_key.gem_port_id = p_flow->data.svc_port_id;
+ BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);
+ BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, flow_id, p_flow->data.svc_port_id);
+ if (BCMOS_TRUE == p_flow->data.resolve_mac)
+ {
+ BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_TRUE);
+ }
+ else
+ {
+ BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_FALSE);
+ }
+ BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, vlan_action, BCMOLT_US_VLAN_ACTION_TRANSPARENT);
+
+ rc = bcmolt_cfg_set(device_id, &us_cfg.hdr);
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s FAILED, rc = %s (%d), err_text = %s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc, us_cfg.hdr.hdr.err_text);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief maple_mac_us_iwf_cfg_remove
+ *
+ * This routine is used to remove configuration from Maple of the relevant upstream iwf
+ *
+ * @param p_flow A pointer to a flow object
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno maple_mac_us_iwf_cfg_remove(bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno rc = BCM_ERR_PARM;
+ bcmolt_gpon_iwf_us_flow_key us_key = {};
+ bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ /* configure the related iwf us flow */
+ rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ return rc;
+ }
+
+ us_key.pon_ni = physical_if_id;
+ us_key.gem_port_id = p_flow->data.svc_port_id;
+ BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);
+
+ rc = bcmolt_cfg_clear(device_id, &us_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
+ "%s FAILED, rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief mac_util_validate_subscriber_terminal_info_for_gpon
+ *
+ * This routine is used to validate all input attributes required for a sub term setting
+ * received from core for GPON
+ *
+ * @param p_sub_term_req A pointer to a subscriber terminal object
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_gpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
+{
+ if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET (p_sub_term_req, subscriber_terminal, serial_number))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Serial number is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
+ return BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+
+ if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, password))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Password is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
+ return BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief Command Set setup routine for subscriber terminal connect to mac application for GPON
+ *
+ * This routine is called by sub_term_fsm in the BAL core to initialize the command
+ * set to connect the subscriber terminal of the mac application. The cmdset actually
+ * consists of two commands, one is to send the sub_term request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_sub_term_inst A pointer to a subscriber terminal instance
+ * @param op_type Type of operation being performed on the subscriber terminal instance
+ * @param is_post_discovery Used for ADD, indicates if this is a request after a ONU discovery
+ *
+ * @return bcmos_errno
+ *
+ * @note we configure Maple for ONU in 2 stages:
+ * \li Stage 1: do cfg_set with the serial num, password, omci port, as part of first sub_term_set from Core
+ * \li Stage 2: set the ONU state to ACTIVE using oper_submit, as part of second sub_term_set from Core (after
+ * receiving a Discovery indication)
+ */
+bcmos_errno mac_util_subscriber_terminal_set_for_gpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
+
+ do
+ {
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ bcmolt_gpon_onu_cfg cfg = {};
+ bcmolt_gpon_onu_cfg onu_cfg_get = {};
+ bcmolt_gpon_onu_set_onu_state oper = {};
+ bcmolt_gpon_onu_key key = {};
+ bcmolt_onu_operation new_onu_state;
+ bcmolt_gpon_onu_auto_cfg gpon_onu_auto_cfg = {}; /* main auto cfg api struct */
+
+ /* set the onu key - set it to the physical if id */
+ key.pon_ni = physical_if_id;
+ key.onu_id = p_sub_term_req->key.sub_term_id;
+
+ /* set the onu key */
+ BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
+
+ /* invoke onu state change operation to the new state */
+ BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
+
+ if(BAL_UTIL_OPER_SUB_TERM_CLEAR == op_type)
+ {
+ /* Delete the configuration of the ONU */
+ rc = bcmolt_cfg_clear(device_id, &cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to clear onu configuration(%s)\n",
+ bcmos_strerror(rc));
+ }
+
+ /* No indication from Maple will result from the clear operation
+ * so fake it here
+ */
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_CLEAR,
+ rc, rc,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+
+ /* No further processing is required for the CLEAR operation */
+ break;
+
+
+ }
+ else if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
+ {
+ /* first do a get, to see if onu is in active state already */
+ BCMOLT_CFG_INIT(&onu_cfg_get, gpon_onu, key);
+ BCMOLT_CFG_PROP_GET(&onu_cfg_get, gpon_onu, onu_state);
+ rc = bcmolt_cfg_get(device_id, &onu_cfg_get.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to get onu configuration(%s), err_text=%s, ... continue to configure\n",
+ bcmos_strerror(rc), onu_cfg_get.hdr.hdr.err_text);
+
+ /* don't break, but continue with the set anyways */
+ }
+ else
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s: ONU state = %d, [pon_ni=%d, onu_id=%d], BEFORE doing cfg_set on Maple\n",
+ __FUNCTION__, onu_cfg_get.data.onu_state, onu_cfg_get.key.pon_ni, onu_cfg_get.key.onu_id);
+ }
+
+
+ if ((BCM_ERR_OK == rc) && (BCMOLT_ONU_STATE_ACTIVE == onu_cfg_get.data.onu_state))
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s: ONU already in active state during ADD. Skipping further config\n",
+ __FUNCTION__);
+
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ rc, rc,
+ BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ break;
+ }
+
+
+ /* set the sn & password only if it being configured for the first time */
+ if (BCMOS_FALSE == is_post_discovery)
+ {
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, serial_number,
+ *((bcmolt_serial_number *)&p_sub_term_req->data.serial_number));
+
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, password,
+ *((bcmolt_arr_u8_10 *)&p_sub_term_req->data.password));
+
+ /* set the onu configuration */
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, auto_password_learning, BCMOS_TRUE);
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, us_fec, BCMOS_FALSE);
+
+ /* set the onu management channel port */
+ BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, omci_port_id, p_sub_term_req->data.svc_port_id);
+
+
+ rc = bcmolt_cfg_set(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to set onu configuration(%s), err_text=%s\n",
+ bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ break;
+ }
+
+ /**
+ * @note If this is first time set for ADD, then skip setting the ONU state for now.
+ * Wait until ONU Discovery is received.
+ */
+ break;
+ }
+
+
+ /* turn off the auto indication messages for gpon_onu.rei */
+ BCMOLT_AUTO_CFG_INIT(&gpon_onu_auto_cfg, gpon_onu, key);
+ BCMOLT_AUTO_CFG_PROP_SET(&gpon_onu_auto_cfg, gpon_onu, rei, BCMOS_FALSE);
+ rc = bcmolt_auto_cfg_set(device_id, &gpon_onu_auto_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "bcmolt_auto_cfg_set for gpon_onu.rei Failed (%s), err_text=%s)\n",
+ bcmos_strerror(rc), gpon_onu_auto_cfg.hdr.hdr.err_text);
+
+ /* This is not fatal, so just continue anyway */
+ }
+
+ /*
+ * Set the new onu state for the ADD operation
+ */
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Setting ONU state to active\n");
+
+ new_onu_state = BCMOLT_ONU_OPERATION_ACTIVE;
+ }
+ else if (BAL_UTIL_OPER_SUB_TERM_REMOVE == op_type)
+ {
+ /* If the ONU is not present, then it will never respond to the deactivate command
+ * with an indication, so just allow the FSM to continue as if it did.
+ */
+ if(BCMBAL_STATUS_NOT_PRESENT != p_sub_term_inst->current_sub_term_info.data.oper_status)
+ {
+ /*
+ * Set the new onu state for the REMOVE operation
+ */
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Setting ONU state to IN-active\n");
+
+ new_onu_state = BCMOLT_ONU_OPERATION_INACTIVE;
+ }
+ }
+ else /* This should never happen */
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Bad request from core\n");
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Do oper_submit to set the ONU state */
+ BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, new_onu_state);
+ rc = bcmolt_oper_submit(device_id, &oper.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "bcmolt_oper_submit Failed for onu state Failed (%s), err_text=%s\n",
+ bcmos_strerror(rc), &(oper.hdr.hdr.err_text[0]));
+ }
+
+
+ /* If the ONU is not present, then it will never respond to the deactivate command
+ * with an indication, so just allow the FSM to continue as if it did.
+ */
+ if((BCMOLT_ONU_OPERATION_INACTIVE == new_onu_state) &&
+ (BCMBAL_STATUS_NOT_PRESENT == p_sub_term_inst->current_sub_term_info.data.oper_status))
+ {
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ rc, rc,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+
+ } while (0);
+
+
+
+ if (rc == BCM_ERR_STATE)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s failed to set state, possibly because interface is not configured yet, pon fiber disconnect, or onu disconnect: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+ else if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s Failed: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief validate_flow_info for gpon
+ *
+ * This routine is used to validate all input attributes required for a flow
+ * setting received from core for GPON
+ *
+ * @param p_flow_req A pointer to a flow object
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_validate_flow_info_for_gpon (const bcmbal_flow_cfg *p_flow_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ mac_util_topo_pon_context *topo_context;
+
+ topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
+ if ((BCM_ERR_OK == rc) && (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode))
+ {
+ if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
+ {
+ /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
+ the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
+ tag vid for GEM decision. Sep-28-2015 IL
+ */
+ if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
+ {
+ if (BCMOS_TRUE != BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "classifier i_vid id is a mandatory downstream parameter for double tagged action, "
+ "and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "o_vid id is a mandatory parameter for a flow classifier, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+
+ if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, agg_port_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "agg port id is a mandatory parameter for an US flow, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief flow set for GPON
+ *
+ * @param p_flow_req pointer to flow request structure from core
+ * @param op_type ADD, REMOVE or CLEAR
+ * @param p_flow_core local DB flow context passed as a cookie
+ *
+ * @return errno error
+ */
+bcmos_errno mac_util_flow_set_for_gpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmos_bool is_pbit_enabled = BCMOS_FALSE;
+ uint16_t per_flow_mode_vlan_id = 0; /* hold the value of the vlan tag to use in per-flow mode */
+ uint8_t pbits_val = 0;
+ mac_util_topo_pon_context *topo_context;
+ flow_list_entry *p_mac_util_flow_entry = NULL;
+
+ topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
+ if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
+ {
+ per_flow_mode_vlan_id = 0; /* set to default */
+
+ if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
+ {
+ /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
+ the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
+ tag vid for GEM decision. Sep-28-2015 IL
+ */
+ if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
+ {
+ if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
+ {
+ per_flow_mode_vlan_id = p_flow_req->data.classifier.i_vid;
+ }
+ //else should not happen here really, since this was validated in a previous step
+ }
+ else
+ {
+ per_flow_mode_vlan_id = p_flow_req->data.classifier.o_vid;
+ }
+ }
+ //else should not happen here really, since this was validated in a previous step
+ }
+
+
+ /* Check the operation id */
+ if ((BAL_UTIL_OPER_FLOW_ADD != op_type) &&
+ (BAL_UTIL_OPER_FLOW_REMOVE != op_type) &&
+ (BAL_UTIL_OPER_FLOW_CLEAR != op_type))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unexpected mac_util flow operation %d \n", op_type);
+ return BCM_ERR_PARM;
+ }
+
+ /* flow Add or Modify */
+ if (BAL_UTIL_OPER_FLOW_ADD == op_type)
+ {
+ switch (p_flow_req->key.flow_type)
+ {
+ /* unicast flows */
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ {
+ if (p_flow_req->data.classifier.o_pbits)
+ {
+ /* o_pbits can only take one p-bit value */
+ pbits_val = p_flow_req->data.classifier.o_pbits;
+ is_pbit_enabled = BCMOS_TRUE;
+ }
+ else
+ {
+ pbits_val = 0;
+ is_pbit_enabled = BCMOS_FALSE;
+ }
+
+ /* create a gem port id and relevant flow for a single pbit, or with no pbit */
+ /* pass on the op type also to specify if it is FLOW_ADD OR FLOW_MODIFY */
+ rc = maple_mac_unicast_flow_add(p_flow_req, pbits_val, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
+ if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
+ {
+ break;
+ }
+
+
+ /* configure iwf flows in case of per flow interworking mode */
+ if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
+ {
+ if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type)
+ {
+ rc = maple_mac_ds_iwf_cfg(p_flow_req, per_flow_mode_vlan_id, is_pbit_enabled);
+ }
+ else
+ /* FLOW_TYPE_UPSTREAM */
+ {
+ rc = maple_mac_us_iwf_cfg(p_flow_req, pbits_val);
+ }
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Failed to add iwf flows in per flow mode (%s))\n",
+ bcmos_strerror(rc));
+ break;
+ }
+ }
+
+ /* mark flow configuration to device completed */
+ mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
+ }
+ break;
+
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ {
+ rc = maple_mac_broadcast_flow_add(p_flow_req, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
+ if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
+ {
+ break;
+ }
+
+ }
+ break;
+
+ default:
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow type %d\n",
+ p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) ||
+ (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ /* find the flow */
+ p_mac_util_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow_req->data.access_int_id, &(p_flow_req->key));
+ if (NULL == p_mac_util_flow_entry)
+ {
+ rc = BCM_ERR_NOENT;
+ if (BAL_UTIL_OPER_FLOW_CLEAR != op_type)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "%s: NULL mac util flow entry to remove: flow id: %d, flow_type: %s\n",
+ __FUNCTION__,
+ p_flow_req->key.flow_id,
+ (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "up":"down"));
+ }
+
+ goto exit;
+ }
+
+ switch (p_flow_req->key.flow_type)
+ {
+ /* unicast flows */
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ {
+ /* First De-configure IWF flows in case of per flow interworking mode */
+ if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
+ {
+ if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type)
+ {
+ rc = maple_mac_ds_iwf_cfg_remove(p_flow_req, per_flow_mode_vlan_id);
+ }
+ else
+ {
+ rc = maple_mac_us_iwf_cfg_remove(p_flow_req);
+ }
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Failed to remove iwf flows in per flow mode (%s))\n",
+ bcmos_strerror(rc));
+ break;
+ }
+ }
+
+
+ /** Then remove unicast GEM/Alloc Id from Maple and flow entry from local database */
+ rc = maple_mac_unicast_flow_remove(p_flow_req, op_type, p_mac_util_flow_entry);
+ if (BCM_ERR_OK != rc)
+ {
+ break;
+ }
+
+ /* mark flow De-configuration to device completed */
+ mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
+ }
+ break;
+
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ {
+ rc = maple_mac_broadcast_flow_remove(p_flow_req, per_flow_mode_vlan_id, op_type, p_mac_util_flow_entry);
+ }
+ break;
+
+ default:
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow type %d\n",
+ p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+
+ }
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow op type %d for flow id/type = %d/%d\n",
+ op_type, p_flow_req->key.flow_id, p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ }
+
+exit:
+ if (BCM_ERR_OK == rc)
+ {
+ /*
+ * Check flow entry flags to see if an indication to Core should be triggered immediately:
+ * (Special handling for flow configuration, for the case no device configuration is needed,
+ * and/or no indication from device is expected - could be the case of a single/multiple
+ * gem ports used for us and ds, and us was already configured.
+ * - send the flow ind immediately
+ */
+ check_send_flow_bal_ind_msg(p_mac_util_flow_entry, BCM_ERR_OK, BCMOLT_RESULT_SUCCESS);
+ }
+ else
+ {
+ if ((BCM_ERR_NOENT == rc) && (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ /*
+ * For flow CLEAR, and if no flow entry is found, then fake an indication success to Core,
+ * for it to execute the flow state machine.
+ * The reasons for flow entry not found could be because the flow was already admin-ed Down.
+ * Admin-down of a flow causes mac util to clear flow config and flow instance from itself
+ * and the maple HW. However, Core FSM still keeps it's flow instance during admin down state.
+ */
+ mac_util_report_flow_remove_success (p_flow_req->key, p_flow_req->data.access_int_id, op_type);
+ rc = BCM_ERR_OK;
+ }
+ }
+ //else if there was an error during config, just return a failure; no need to send back indication for that.
+
+
+ return rc;
+}
+
+bcmos_errno maple_gpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
+ bcmos_bool *is_configured, bcmos_bool *is_activated)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_gem_port_key gem_key = {};
+ bcmolt_gpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the gem port object key */
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
+ BCMOLT_CFG_PROP_GET(&gem_cfg, gpon_gem_port, all_properties);
+
+ rc = bcmolt_cfg_get(device_id, &gem_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED in bcmolt_cfg_get: svc_port_id = %d if_id = %d onu_id = %d\n",
+ __FUNCTION__,
+ svc_port_id, if_id, onu_id);
+
+ return rc;
+ }
+
+
+ /* may be configured; does gem belong to same onu ? */
+ if (BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state && onu_id != gem_cfg.data.onu_id)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED, onu id mismatch: svc_port_id = %d if_id = %d is already assigned to onu_id = %d (not to onu id %d) \n",
+ __FUNCTION__,
+ svc_port_id, if_id, gem_cfg.data.onu_id, onu_id);
+
+ return BCM_ERR_PARM;
+ }
+ *is_configured = BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state;
+ *is_activated = BCMOLT_GPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state;
+
+ return rc;
+}
+
+
+bcmos_errno maple_gpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_gem_port_key gem_key = {};
+ bcmolt_gpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the gem port object key */
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
+
+ /* set the gem port configuration */
+ if (onu_id < MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM)
+ {
+ BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, onu_id, onu_id);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, upstream_destination_queue,
+ BCMOLT_US_GEM_PORT_DESTINATION_DATA);
+ }
+ BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, downstream_encryption_mode,
+ BCMOLT_CONTROL_STATE_DISABLE);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, configuration, *configuration);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, control, BCMOLT_CONTROL_STATE_ENABLE);
+
+ rc = bcmolt_cfg_set(device_id, &gem_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED: rc=%s (%d), svc_port_id = %d dev_id = %d if_id = %d onu_id = %d, err_text=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc, svc_port_id, device_id, if_id, onu_id, gem_cfg.hdr.hdr.err_text);
+ }
+
+ return rc;
+}
+
+
+bcmos_errno maple_gpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_gem_port_key gem_key = {};
+ bcmolt_gpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
+ rc = bcmolt_cfg_clear(device_id, &gem_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s id=%d, gem=%d, failed with error %s\n",__FUNCTION__, if_id, svc_port_id, bcmos_strerror(rc));
+ }
+
+
+ return rc;
+}
+
+
+bcmos_errno maple_gpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_alloc_key alloc_key = {};
+ bcmolt_gpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
+ BCMOLT_CFG_PROP_GET(&alloc_cfg, gpon_alloc, all_properties);
+
+ rc = bcmolt_cfg_get(device_id, &alloc_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s: FAILED in bcmolt_cfg_get rc = %s, agg_id = %d if_id = %d\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), agg_id, if_id);
+
+ return rc;
+ }
+
+ /* may be configured; does alloc id belong to the expected onu ? */
+ if (alloc_cfg.data.state != BCMOLT_ALLOC_STATE_NOT_CONFIGURED
+ && alloc_cfg.data.onu_id != onu_id)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED, onu id mismatch: agg_id = %d if_id = %d is set to onu %d NOT to onu_id = %d\n",
+ __FUNCTION__,
+ agg_id, if_id, alloc_cfg.data.onu_id, onu_id);
+
+ return BCM_ERR_PARM;
+ }
+
+ *alloc_id_state = alloc_cfg.data.state;
+
+ return BCM_ERR_OK;
+}
+
+
+bcmos_errno maple_gpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_alloc_key alloc_key = {};
+ bcmolt_gpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
+ BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, sla, agg_sla);
+ /* set the alloc-id - onu assignment */
+ BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, onu_id, onu_id);
+
+ rc = bcmolt_cfg_set(device_id, &alloc_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s: rc = %s, agg_id = %d if_id = %d, err_text = %s \n",
+ __FUNCTION__,
+ bcmos_strerror(rc), agg_id, if_id, alloc_cfg.hdr.hdr.err_text);
+ }
+ return rc;
+
+}
+
+
+bcmos_errno maple_gpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_gpon_alloc_key alloc_key = {};
+ bcmolt_gpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
+
+ rc = bcmolt_cfg_clear(device_id, &alloc_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+
+ return rc;
+}
+
+/**
+ * @brief group set for gpon
+ * @param p_group_req pointer to group request structure from core
+ * @param op_type ADD, REMOVE or SET
+ * @param p_group_inst pointer to the Core Group Object instance
+ *
+ * @return errno error
+ *
+ * @todo shift this out to mac specific files
+ */
+bcmos_errno mac_util_group_set_for_gpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_inst)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint16_t svc_port_id;
+ uint32_t if_id, i, ref_count;
+ bcmolt_gem_port_configuration configuration = {0};
+
+ /* Check the operation id */
+ if ((BAL_UTIL_OPER_GROUP_ADD != op_type) &&
+ (BAL_UTIL_OPER_GROUP_REMOVE != op_type) &&
+ (BAL_UTIL_OPER_GROUP_SET != op_type))
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Unexpected mac_util gpon group operation %d \n", op_type);
+ return BCM_ERR_PARM;
+ }
+
+ configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
+ configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
+
+ /* for group SET operation, first remove the old multicast GEM */
+ if (BAL_UTIL_OPER_GROUP_SET == op_type)
+ {
+ bcmbal_group_cfg *p_group_rem_req;
+ /* use the Core DB for existing members - store in current_flow_info */
+ p_group_rem_req = &p_group_inst->current_group_info;
+ for(i=0; i< p_group_rem_req->data.members.len; i++)
+ {
+ if_id = p_group_rem_req->data.members.val[i].intf_id;
+ svc_port_id = p_group_rem_req->data.members.val[i].svc_port_id;
+ /* svc_port_id can be 0 (not assigned) when group had no owner, no need to remove */
+ if(svc_port_id)
+ {
+ rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util gpon group get reference count on interface %d (gem %d) failed \n", if_id, svc_port_id);
+ return rc;
+ }
+ /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
+ The core will ask Resource Manger to decrease the counter if everything is good */
+ if ( ref_count == 1)
+ {
+ rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util gpon group set operation SET on remove interface %d (gem %d) failed \n", if_id, svc_port_id);
+ return rc;
+ }
+ }
+ else if ( ref_count == 0)
+ {
+ BCM_LOG(WARNING, log_id_mac_util,
+ "mac_util gpon group set operation SET on interface %d (gem %d) remove with 0 reference counter \n", if_id, svc_port_id);
+ }
+ }
+ }
+ }
+
+ /* walk through every member interface */
+ for(i=0; i< p_group_req->data.members.len; i++)
+ {
+ if_id = p_group_req->data.members.val[i].intf_id;
+ svc_port_id = p_group_req->data.members.val[i].svc_port_id;
+ /* group Add */
+ if (BAL_UTIL_OPER_GROUP_ADD == op_type || BAL_UTIL_OPER_GROUP_SET == op_type)
+ {
+ rc = maple_gpon_gem_port_id_add(if_id, svc_port_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM, &configuration);
+ }
+ else if (BAL_UTIL_OPER_GROUP_REMOVE == op_type)
+ {
+ rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util gpon group operation REM on interface %d (gem %d) failed \n", if_id, svc_port_id);
+ break;
+ }
+ /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
+ The core will ask Resource Manger to decrease the counter if everything is good */
+ if ( ref_count == 1)
+ {
+ rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
+ }
+ else if ( ref_count == 0)
+ {
+ BCM_LOG(WARNING, log_id_mac_util,
+ "mac_util gpon group operation REM on interface %d (gem %d) with 0 reference count \n", if_id, svc_port_id);
+ }
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util gpon group set of operation %d on interface %d (gem %d) failed \n", op_type, if_id, svc_port_id);
+ break;
+ }
+ }
+
+
+ return rc;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_loopback.c b/bal_release/src/core/util/mac/bal_mac_util_loopback.c
new file mode 100644
index 0000000..e94c282
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_loopback.c
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_loopback.c
+ *
+ * @brief mac util handling for MAC in loopback mode
+ *
+ * The loopback mode is handled like a mac protocol, with loopback specific handling
+ * done as sub-routine calls from the top level handler functions.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_common_itu_pon.h>
+#include <bal_worker.h>
+
+
+/**
+ * @brief access terminal set for loopback
+ */
+bcmos_errno mac_util_access_terminal_set_for_loopback (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmos_usleep(1000000);
+ mac_util_report_acc_term_event(BCMOLT_DEVICE_AUTO_ID_CONNECTION_COMPLETE);
+
+ return rc;
+}
+
+
+/**
+ * @brief set interface for loopback mode
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param op_type Operation type on access terminal/interface instance
+ *
+ * @return bcmos_errno
+ *
+ */
+bcmos_errno mac_util_interface_set_for_loopback(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
+ bcmbal_interface_cfg *p_interface_req = &(p_interface_inst->api_req_int_obj_info);
+
+ p_interface_req = &(p_interface_inst->api_req_int_obj_info);
+
+ /* If the user didn't specify a transceiver, then use the default */
+ if (BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_interface_req, interface, transceiver_type))
+ {
+ BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_GPON);
+ }
+
+ mac_util_report_if_event(intf_key.intf_id,
+ intf_key.intf_type,
+ BCM_ERR_OK, BCMOLT_RESULT_SUCCESS,
+ ((BAL_UTIL_OPER_IF_UP == op_type) ? BCMOLT_PON_STATE_ACTIVE_WORKING : BCMOLT_PON_STATE_INACTIVE));
+
+
+ return rc;
+}
+
+
+/**
+ * @brief Set subscriber terminal for loopback mode
+ *
+ * @param p_sub_term_inst A pointer to a subscriber terminal instance
+ * @param op_type Type of operation being performed on the subscriber terminal instance
+ * @param is_post_discovery Used for ADD, indicates if this request is after a ONU Discovery
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_subscriber_terminal_set_for_loopback(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
+
+
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ (BAL_UTIL_OPER_SUB_TERM_ADD == op_type ? BAL_UTIL_OPER_SUB_TERM_ADD : BAL_UTIL_OPER_SUB_TERM_REMOVE),
+ BCM_ERR_OK, BCMOLT_RESULT_SUCCESS,
+ (BAL_UTIL_OPER_SUB_TERM_ADD == op_type ? BCMOLT_ACTIVATION_FAIL_REASON_NONE : BCMOLT_RESULT_SUCCESS), BCMBAL_INVALID_TUNNEL_ID);
+
+ return rc;
+}
+
+
+/**
+ * @brief set flow for loopback mode
+ */
+bcmos_errno mac_util_flow_set_for_loopback(bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (BAL_UTIL_OPER_FLOW_ADD == op_type)
+ {
+ mac_util_report_flow_add_success(p_flow_req->key, p_flow_req->data.access_int_id);
+ }
+ else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) || (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ mac_util_report_flow_remove_success(p_flow_req->key, p_flow_req->data.access_int_id, op_type);
+ }
+ else
+ {
+ rc = BCM_ERR_INVALID_OP;
+ }
+
+
+ return rc;
+}
+
+
+
+/*@}*/
diff --git a/bal_release/src/core/util/mac/bal_mac_util_xgpon.c b/bal_release/src/core/util/mac/bal_mac_util_xgpon.c
new file mode 100644
index 0000000..a49b3d7
--- /dev/null
+++ b/bal_release/src/core/util/mac/bal_mac_util_xgpon.c
@@ -0,0 +1,1493 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_mac_util_xgpon.c
+ *
+ * @brief mac util interfaces definition used by Bal Core, for xgpon
+ *
+ * This file expose the APIs to the core to configure the mac
+ * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
+ *
+ * @addtogroup mac_util
+ */
+
+/*@{*/
+
+#include <bal_mac_util.h>
+#include <bal_mac_util_common_itu_pon.h>
+
+
+static bcmos_errno mac_util_indication_handle_for_xgpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_xgpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg);
+static bcmos_errno mac_util_indication_handle_for_xgpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg);
+
+/* On XG-PON1 there is no indication such as GEM port configuration completed.
+ * GEM configuration at the ONU is taken care of completely by OMCI without any PLOAM sent from the OLT
+ * */
+
+/**
+ * @brief array stores the list of xgpon (XG-PON1) related auto indications from Maple to subscribe
+ */
+static mac_util_ind_obj_and_handlers mac_util_xgpon_ind_handlers[] =
+{
+ {BCMOLT_OBJ_ID_XGPON_NI, "BCMOLT_OBJ_ID_XGPON_NI", mac_util_indication_handle_for_xgpon_ni},
+ {BCMOLT_OBJ_ID_XGPON_ONU, "BCMOLT_OBJ_ID_XGPON_ONU", mac_util_indication_handle_for_xgpon_onu},
+ {BCMOLT_OBJ_ID_XGPON_ALLOC, "BCMOLT_OBJ_ID_XGPON_ALLOC", mac_util_indication_handle_for_xgpon_alloc_id},
+};
+
+/**
+ * @brief Map bal XGPON transceiver type to bcm68620 transceiver type
+ */
+static bcmolt_xgpon_trx_type mac_xgpon_bal_trx_type2bcm68620_trx_type(bcmbal_trx_type bal_trx_type)
+{
+ bcmolt_xgpon_trx_type trx_type = BCMOLT_XGPON_TRX_TYPE__NUM_OF;
+
+ if (BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC == bal_trx_type)
+ {
+ trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC;
+ }
+ else if (BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC == bal_trx_type)
+ {
+ trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC;
+ }
+ else if (BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC == bal_trx_type)
+ {
+ trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC;
+ }
+ else
+ {
+ trx_type = BCMOLT_XGPON_TRX_TYPE_USER_DEFINED;
+ }
+
+ return trx_type;
+}
+
+/**
+ * @brief all the maple indication handlers for xgpon
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ */
+bcmos_errno mac_util_handle_all_olt_ind_for_xgpon (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ BCM_LOG(DEBUG, log_id_mac_util,
+ "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
+ p_msg->obj_type, mac_util_indication_get_obj_type_str(p_msg->obj_type, mac_util_xgpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_xgpon_ind_handlers)),
+ p_msg->group, p_msg->subgroup);
+
+ return mac_util_handle_indication(device_id, p_msg, mac_util_xgpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_xgpon_ind_handlers));
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for xgpon (XG-PON1) NI
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_xgpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+
+ do
+ {
+
+ /* PON activation */
+ if (BCMOLT_XGPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_xgpon_ni_state_change_completed * p_ind = (bcmolt_xgpon_ni_state_change_completed*)p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
+ BCMOLT_PON_STATE_ACTIVE_WORKING == p_ind->data.new_state ? "up" : "down");
+
+ mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
+ p_ind->data.result, p_ind->data.new_state);
+
+ }
+ else if(BCMOLT_XGPON_NI_AUTO_CFG_ID_ONU_DISCOVERED == p_msg->subgroup)
+ {
+ bcmolt_xgpon_ni_onu_discovered *p_ind =
+ (bcmolt_xgpon_ni_onu_discovered *)p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Pon if %d found ONU serial number "
+ "%c%c%c%c%d%d%d%d%d%d%d%d\n",
+ logical_pon,
+ p_ind->data.serial_number.vendor_id[0],
+ p_ind->data.serial_number.vendor_id[1],
+ p_ind->data.serial_number.vendor_id[2],
+ p_ind->data.serial_number.vendor_id[3],
+ p_ind->data.serial_number.vendor_specific[0]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[0] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[1]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[1] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[2]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[2] & 0x0f,
+ p_ind->data.serial_number.vendor_specific[3]>>4 & 0x0f,
+ p_ind->data.serial_number.vendor_specific[3] & 0x0f
+ );
+
+ /* if we got something from MAC HW, then it has to be PON interface */
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->data.onu_id,
+ &p_ind->data.serial_number,
+ BAL_UTIL_OPER_SUB_TERM_DISCOVERY,
+ p_msg->err, BCM_ERR_OK,
+ BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_xgpon_ni_key *p_pon_key = &(((bcmolt_xgpon_ni_state_change_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj XGPON_NI group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+ }
+ while(0);
+
+ return rc;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for xgpon (XG-PON1) ONU
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_xgpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_xgpon_onu_key *p_xgpon_onu_key = &(((bcmolt_xgpon_onu_onu_activation_completed*)p_msg)->key);
+ do
+ {
+ if (BCMOLT_XGPON_ONU_AUTO_CFG_ID_ONU_ACTIVATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_xgpon_onu_onu_activation_completed *p_ind = (bcmolt_xgpon_onu_onu_activation_completed*) p_msg;
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "sub_term %d (PON%d) activation indication (%s)\n",
+ p_ind->key.onu_id,
+ logical_pon,
+ bcmos_strerror(p_msg->err));
+
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->key.onu_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ p_msg->err, p_ind->data.status,
+ p_ind->data.fail_reason, BCMBAL_INVALID_TUNNEL_ID);
+
+ }
+ else if(BCMOLT_XGPON_ONU_AUTO_CFG_ID_ONU_DEACTIVATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_xgpon_onu_onu_deactivation_completed *p_ind = (bcmolt_xgpon_onu_onu_deactivation_completed*) p_msg;
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "sub_term %d (PON%d) deactivation indication (%s)\n",
+ p_ind->key.onu_id,
+ p_ind->key.pon_ni,
+ bcmos_strerror(p_msg->err));
+
+ mac_util_report_sub_term_event(logical_pon,
+ p_ind->key.onu_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ p_msg->err, p_ind->data.status,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+ else
+ {
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_xgpon_onu_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_xgpon_onu_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj XGPON_ONU group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ break;
+ }
+
+ rc = mac_util_update_flows_w_sub_term_update(logical_pon, p_xgpon_onu_key->onu_id, maple_xgpon_mac_check_gem_port_id, maple_xgpon_mac_get_alloc_id_config);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to update related flows pon_id = %d onu_id = %d (%s)\n", logical_pon, p_xgpon_onu_key->onu_id, bcmos_strerror(rc));
+ break;
+ }
+
+ }while(0);
+
+ return rc;
+}
+
+
+/**
+ * @brief Handler function for Maple auto indications for xgpon (XG-PON1) Alloc Id
+ *
+ * @param device_id the maple device id generating the current indication
+ * @param p_msg pointer to the maple indication message
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno mac_util_indication_handle_for_xgpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t logical_pon;
+ tm_sched_inst* p_tm_sched_inst = NULL;
+ do
+ {
+ if (BCMOLT_XGPON_ALLOC_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
+ {
+ bcmolt_xgpon_alloc_configuration_completed *p_ind = (bcmolt_xgpon_alloc_configuration_completed*) p_msg;
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
+
+ break;
+ }
+
+ /* Find tn_mode inst owned by that alloc_id and ni */
+ p_tm_sched_inst = tm_sched_find_agg_port_node(logical_pon, p_ind->key.alloc_id);
+ if (NULL == p_tm_sched_inst )
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to find tm sched owned by that agg port (intf %d id %d)\n", logical_pon,p_ind->key.alloc_id);
+ rc = BCM_ERR_NOENT;
+ break;
+
+ }
+
+ /*the tm owned by that alloc found, update it with the ind*/
+ mac_util_report_tm_sched_set_indication(p_tm_sched_inst->req_tm_sched_info.key ,p_msg->err, p_ind->data.status);
+
+ }
+ else
+ {
+ /* just get the pon key by typecasting to a dummy structure */
+ bcmolt_xgpon_alloc_key *p_pon_key = &(((bcmolt_xgpon_alloc_configuration_completed*)p_msg)->key);
+
+ rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
+ break;
+ }
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Unhandled message indication for obj XGPON_ALLOC group %d "
+ "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
+ }
+
+ }
+ while (0);
+ return rc;
+}
+
+
+/**
+ * @brief Maple auto indication register for specific xgpon (XG-PON1) based indications
+ *
+ * @param p_rx_cfg handler config structure
+ * @param device_id specific device id (for multiple devices support)
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_register_for_xgpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
+{
+ return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_xgpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_xgpon_ind_handlers),device_id);
+}
+
+
+/**
+ * @brief common access terminal set for 10G pon if
+ */
+
+bcmos_errno mac_util_access_terminal_set_for_10G_itu_pon (bcmolt_device_cfg dev_cfg, bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+ bcmolt_device_nni_speed nni_speed_cfg;
+
+#ifdef QAX_SWITCH
+ /* until speed is configurable through topology settings hardcode it based on switch type */
+ BCM_LOG(INFO, log_id_mac_util, "nni speed is: 10G\n");
+ nni_speed_cfg.first_half = BCMOLT_NNI_SPEED_GBPS_10;
+ nni_speed_cfg.second_half = BCMOLT_NNI_SPEED_GBPS_10;
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);
+#endif
+
+ rc = bcmolt_cfg_set(device_id, &dev_cfg.hdr);
+
+ return rc;
+}
+
+
+/**
+ * @brief access terminal set for xgpon1_8
+ */
+bcmos_errno mac_util_access_terminal_set_for_xgpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+ bcmolt_device_key key = {};
+ bcmolt_device_cfg dev_cfg;
+
+ rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ BCMOLT_CFG_INIT(&dev_cfg, device, key);
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, BCMOLT_SYSTEM_MODE_XGPON_1__8_X);
+
+ rc = mac_util_access_terminal_set_for_10G_itu_pon(dev_cfg,device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ return maple_access_terminal_connect_common(device_id);
+}
+
+
+/**
+ * @brief access terminal set for xgs_2_10
+ */
+bcmos_errno mac_util_access_terminal_set_for_xgs (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
+{
+ bcmos_errno rc;
+ bcmolt_device_key key = {};
+ bcmolt_device_cfg dev_cfg;
+
+ rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ BCMOLT_CFG_INIT(&dev_cfg, device, key);
+ BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X_10_G);
+
+ rc = mac_util_access_terminal_set_for_10G_itu_pon(dev_cfg, device_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ return maple_access_terminal_connect_common(device_id);
+}
+
+
+/**
+ * @brief post access terminal up configurations on Maple
+ */
+bcmos_errno mac_util_access_terminal_post_indication_set_for_xgpon_xgs(bcmolt_devid device_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_devid dummy;
+ uint32_t physical_if_id;
+ uint32_t logical_pon = BCM_TOPO_PON_INVALID;
+ bcmolt_xgpon_ni_key ni_key = {};
+ bcmolt_xgpon_ni_cfg ni_cfg = {};
+ bcmolt_automatic_onu_deactivation automatic_onu_deactivation = {};
+ bcmolt_xgpon_sn_acquisition sn_acquisition_cfg = {};
+ bcmolt_xgpon_ni_auto_cfg xgpon_ni_auto_cfg = {}; /* main auto cfg api struct */
+
+ /* configure one time settings for all the interfaces on this device */
+ BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
+ {
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (logical_pon, &dummy, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ ni_key.pon_ni = physical_if_id;
+
+ /* Set the SN acquisition mode to enable */
+ BCMOLT_CFG_INIT(&ni_cfg, xgpon_ni, ni_key);
+
+ sn_acquisition_cfg.control = BCMOLT_CONTROL_STATE_ENABLE;
+ sn_acquisition_cfg.interval = 5000;
+ sn_acquisition_cfg.onu_post_discovery_mode = BCMOLT_ONU_POST_DISCOVERY_MODE_NONE;
+ sn_acquisition_cfg.burst_profile = 0; /* Ranging burst profile - No FEC */
+ BCMOLT_CFG_PROP_SET(&ni_cfg, xgpon_ni, sn_acquisition, sn_acquisition_cfg);
+
+ /* Unlike GPON, the default behavior on Maple for XG-PON1 is not to deactivate the ONU in the below cases
+ * so here we specifically configure the Maple to behave on XG-PON1 as it does on GPON */
+ automatic_onu_deactivation.ack_timeout = BCMOS_TRUE;
+ automatic_onu_deactivation.loki = BCMOS_TRUE;
+ automatic_onu_deactivation.los = BCMOS_TRUE;
+ automatic_onu_deactivation.onu_alarms = BCMOS_TRUE;
+ automatic_onu_deactivation.sfi = BCMOS_TRUE;
+ automatic_onu_deactivation.tiwi = BCMOS_TRUE;
+ BCMOLT_CFG_PROP_SET(&ni_cfg, xgpon_ni, automatic_onu_deactivation, automatic_onu_deactivation);
+
+ rc = bcmolt_cfg_set(device_id, &ni_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "Failed to set sn acquisition and automatic onu deactivation configuration (%s),"
+ " device_id=%d, ni_key.pon_ni=%d, err_text=%s)\n",
+ bcmos_strerror(rc), device_id, ni_key.pon_ni, ni_cfg.hdr.hdr.err_text);
+ break;
+ }
+
+
+ /* turn off the auto indication messages for xgpon_ni.serial_number_acquisition_cycle_start */
+ BCMOLT_AUTO_CFG_INIT(&xgpon_ni_auto_cfg, xgpon_ni, ni_key);
+ BCMOLT_AUTO_CFG_PROP_SET(&xgpon_ni_auto_cfg, xgpon_ni, serial_number_acquisition_cycle_start, BCMOS_FALSE);
+ rc = bcmolt_auto_cfg_set(device_id, &xgpon_ni_auto_cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
+ "bcmolt_auto_cfg_set for xgpon_ni.serial_number_acquisition_cycle_start, Failed (%s), err_text=%s)\n",
+ bcmos_strerror(rc), xgpon_ni_auto_cfg.hdr.hdr.err_text);
+
+ /* ignore any error, just continue anyway */
+ }
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Command Set setup routine for interface up to mac application for xgpon (XG-PON1)
+ *
+ * This routine is called by if_fsm in the BAL core to initialize the command
+ * set to up the interface of the mac application. The cmdset actually
+ * consists of two commands, one is to send the if up request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param op_type Operation type on access terminal/interface instance
+ *
+ * @return bcmos_errno
+ *
+ */
+bcmos_errno mac_util_interface_set_for_xgpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_interface_cfg *p_interface_req = &(p_interface_inst->api_req_int_obj_info);
+ bcmbal_interface_key intf_key = p_interface_req->key;
+
+ do
+ {
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (intf_key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ bcmolt_xgpon_ni_set_pon_state oper_ni;
+ bcmolt_xgpon_ni_key ni_key = { .pon_ni = physical_if_id };
+ bcmolt_xgpon_trx_cfg cfg = {};
+ bcmolt_xgpon_trx_key trx_key = { .pon_ni = physical_if_id };
+ bcmolt_xgpon_trx_type trx_type;
+
+ if (BAL_UTIL_OPER_IF_UP == op_type)
+ {
+
+ /* set the pon_ni transceiver configuration */
+ BCMOLT_CFG_INIT(&cfg, xgpon_trx, trx_key);
+
+ /* Get the current default burst profiles */
+ rc = bcmolt_cfg_get(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to get trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ break;
+ }
+
+ /* If the user didn't specify a transceiver, then use the default */
+ if (BCMOS_TRUE != BCMBAL_CFG_PROP_IS_SET(p_interface_req, interface, transceiver_type))
+ {
+ if(BCM_TOPO_PON_MODE_XGPON == bcm_topo_pon_get_pon_mode(intf_key.intf_id))
+ {
+ /* The user didn't choose a transceiver type, so override it here
+ * with the default value for XGPON
+ */
+ BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGPON);
+ }
+ else if (BCM_TOPO_PON_MODE_XGS == bcm_topo_pon_get_pon_mode(intf_key.intf_id))
+ {
+ /* The user didn't choose a transceiver type, so override it here
+ * with the default value for XGS
+ */
+ BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGS);
+ }
+ }
+
+ /* Set the (default or chosen) transceiver configuration into the MAC device */
+
+ trx_type = mac_xgpon_bal_trx_type2bcm68620_trx_type(p_interface_req->data.transceiver_type);
+
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_trx, transceiver_type, trx_type);
+
+ rc = bcmolt_cfg_set(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to set trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ break;
+ }
+
+ /* No need to Configure pon_ni Inter-working on XG-PON1 as
+ * direct mode is the only option available on this system mode
+ */
+ }
+
+
+ /* invoke the pon_ni state change to the requested state */
+ BCMOLT_OPER_INIT(&oper_ni, xgpon_ni, set_pon_state, ni_key);
+ BCMOLT_OPER_PROP_SET(&oper_ni, xgpon_ni, set_pon_state, pon_state,
+ (BAL_UTIL_OPER_IF_UP == op_type) ?
+ BCMOLT_PON_OPERATION_ACTIVE_WORKING : BCMOLT_PON_OPERATION_INACTIVE);
+
+ rc = bcmolt_oper_submit(device_id, &oper_ni.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Failed to %s (submit) pon interface (%s), err_text=%s\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
+ bcmos_strerror(rc), oper_ni.hdr.hdr.err_text);
+ }
+
+ } while (0);
+
+ if (BCM_ERR_OK == rc)
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
+ "Submitted INTERFACE-%s operation for IF %d\n",
+ (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN",
+ intf_key.intf_id);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief mac_util_validate_subscriber_terminal_info_for_xgpon (XG-PON1)
+ *
+ * This routine is used to validate all input attributes required for a sub term setting
+ * received from core for GPON
+ *
+ * @param p_sub_term_req A pointer to a subscriber terminal object
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_validate_subscriber_terminal_info_for_xgpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
+{
+ if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET (p_sub_term_req, subscriber_terminal, serial_number))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Serial number is a mandatory parameter for a xgpon subscriber terminal, and it is not set\n");
+ return BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+
+ if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, registration_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Registration id is a mandatory parameter for a xgpon subscriber terminal, and it is not set\n");
+ return BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief Command Set setup routine for subscriber terminal connect to mac application for xgpon (XG-PON1)
+ *
+ * This routine is called by sub_term_fsm in the BAL core to initialize the command
+ * set to connect the subscriber terminal of the mac application. The cmdset actually
+ * consists of two commands, one is to send the sub_term request message to the mac
+ * App and handle the relevant response, the other is to handle the indication message
+ * from the mac APP when the operation is completed.
+ *
+ * @param p_sub_term_inst A pointer to a subscriber terminal instance
+ * @param op_type Type of operation being performed on the subscriber terminal instance
+ * @param is_post_discovery Used for ADD, indicates if this is a request after a ONU discovery
+ *
+ * @return bcmos_errno
+ *
+ * @note we configure Maple for ONU in 2 stages:
+ * \li Stage 1: do cfg_set with the serial num, password, omci port, as part of first sub_term_set from Core
+ * \li Stage 2: set the ONU state to ACTIVE using oper_submit, as part of second sub_term_set from Core (after
+ * receiving a Discovery indication)
+ */
+bcmos_errno mac_util_subscriber_terminal_set_for_xgpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
+
+ do
+ {
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+ /* get physical interface from logical interface */
+ rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
+ break;
+ }
+
+ bcmolt_xgpon_onu_cfg cfg = {};
+ bcmolt_xgpon_onu_cfg onu_cfg_get = {};
+ bcmolt_xgpon_onu_set_onu_state oper = {};
+ bcmolt_xgpon_onu_key key = {};
+ bcmolt_onu_operation new_onu_state;
+
+ /* set the onu key - set it to the physical if id */
+ key.pon_ni = physical_if_id;
+ key.onu_id = p_sub_term_req->key.sub_term_id;
+
+ /* set the onu key */
+ BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
+
+ /* invoke onu state change operation to the new state */
+ BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key);
+
+ if(BAL_UTIL_OPER_SUB_TERM_CLEAR == op_type)
+ {
+ /* Delete the configuration of the ONU */
+ rc = bcmolt_cfg_clear(device_id, &cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to clear onu configuration(%s)\n",
+ bcmos_strerror(rc));
+ }
+
+ /* No indication from Maple will result from the clear operation
+ * so fake it here
+ */
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_CLEAR,
+ rc, rc,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+
+ /* No further processing is required for the CLEAR operation */
+ break;
+
+
+ }
+ else if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
+ {
+ /* first do a get, to see if onu is in active state already */
+ BCMOLT_CFG_INIT(&onu_cfg_get, xgpon_onu, key);
+ BCMOLT_CFG_PROP_GET(&onu_cfg_get, xgpon_onu, onu_state);
+ rc = bcmolt_cfg_get(device_id, &onu_cfg_get.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to get onu configuration(%s), err_text=%s, ... continue to configure\n",
+ bcmos_strerror(rc), onu_cfg_get.hdr.hdr.err_text);
+
+ /* don't break, but continue with the set anyways */
+ }
+ else
+ {
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s: ONU state = %d, [pon_ni=%d, onu_id=%d], BEFORE doing cfg_set on Maple\n",
+ __FUNCTION__, onu_cfg_get.data.onu_state, onu_cfg_get.key.pon_ni, onu_cfg_get.key.onu_id);
+ }
+
+
+ if ((BCM_ERR_OK == rc) && (BCMOLT_ONU_STATE_ACTIVE == onu_cfg_get.data.onu_state))
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s: ONU already in active state during ADD. Skipping further config\n",
+ __FUNCTION__);
+
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_ADD,
+ rc, rc,
+ BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ break;
+ }
+
+
+ /* set the SN & Registration ID only if it being configured for the first time */
+ if (BCMOS_FALSE == is_post_discovery)
+ {
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, serial_number,
+ *((bcmolt_serial_number *)&p_sub_term_req->data.serial_number));
+
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id,
+ *((bcmolt_arr_u8_36 *)&p_sub_term_req->data.registration_id));
+
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id_auto_learning, BCMOS_TRUE);
+
+ /* Ranging burst profile - No FEC */
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_burst_profile, 0);
+
+ /* Data burst profile - No FEC */
+ BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, data_burst_profile, 1);
+
+
+ /* XG-PON1 - No need to set US FEC - it is part of the burst profile */
+ /* XG-PON1 - No need to set ONU management channel port as it is identical to the ONU ID*/
+
+ rc = bcmolt_cfg_set(device_id, &cfg.hdr);
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Failed to set onu configuration(%s), err_text=%s\n",
+ bcmos_strerror(rc), cfg.hdr.hdr.err_text);
+ break;
+ }
+
+ /**
+ * @note If this is first time set for ADD, then skip setting the ONU state for now.
+ * Wait until ONU Discovery is received.
+ */
+ break;
+ }
+
+ /*
+ * Set the new onu state for the ADD operation
+ */
+ BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Setting ONU state to active\n");
+
+ new_onu_state = BCMOLT_ONU_OPERATION_ACTIVE;
+ }
+ else if (BAL_UTIL_OPER_SUB_TERM_REMOVE == op_type)
+ {
+ /* If the ONU is not present, then it will never respond to the deactivate command
+ * with an indication, so just allow the FSM to continue as if it did.
+ */
+ if(BCMBAL_STATUS_NOT_PRESENT != p_sub_term_inst->current_sub_term_info.data.oper_status)
+ {
+ /*
+ * Set the new onu state for the REMOVE operation
+ */
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "Setting ONU state to IN-active\n");
+
+ new_onu_state = BCMOLT_ONU_OPERATION_INACTIVE;
+ }
+ }
+ else /* This should never happen */
+ {
+ BCM_LOG(ERROR, log_id_mac_util, "Bad request from core\n");
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Do oper_submit to set the ONU state */
+ BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, new_onu_state);
+ rc = bcmolt_oper_submit(device_id, &oper.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "bcmolt_oper_submit Failed for onu state Failed (%s), err_text=%s\n",
+ bcmos_strerror(rc), &(oper.hdr.hdr.err_text[0]));
+ }
+
+
+ /* If the ONU is not present, then it will never respond to the deactivate command
+ * with an indication, so just allow the FSM to continue as if it did.
+ */
+ if((BCMOLT_ONU_OPERATION_INACTIVE == new_onu_state) &&
+ (BCMBAL_STATUS_NOT_PRESENT == p_sub_term_inst->current_sub_term_info.data.oper_status))
+ {
+ mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
+ p_sub_term_req->key.sub_term_id,
+ (bcmolt_serial_number *)NULL,
+ BAL_UTIL_OPER_SUB_TERM_REMOVE,
+ rc, rc,
+ MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
+ }
+
+ } while (0);
+
+
+
+ if (rc == BCM_ERR_STATE)
+ {
+ BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s failed to set state, possibly because interface is not configured yet, pon fiber disconnect, or onu disconnect: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+ else if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
+ "%s Failed: rc = %s (%d)\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief validate_flow_info for xgpon (XG-PON1)
+ *
+ * This routine is used to validate all input attributes required for a flow
+ * setting received from core for XG-PON1
+ *
+ * @param p_flow_req A pointer to a flow object
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno mac_util_validate_flow_info_for_xgpon (const bcmbal_flow_cfg *p_flow_req)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, agg_port_id))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "agg port id is a mandatory parameter for an US flow, and it is not set\n");
+ rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
+ }
+
+ }
+
+ return rc;
+}
+/* As there is no indication on gem port configuration completion, for xgpon
+ we will have to initiate querying it right after configuring it and retrieve the gem port state.
+ we can not assume it is activated (for example if the onu is not present)
+*/
+static bcmos_errno maple_mac_xgpon_update_svc_port_ind_flag (bcmbal_flow_cfg *p_flow_req, flow_list_entry *p_mac_util_flow_entry)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_gem_port_key gem_key = {};
+ bcmolt_xgpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(p_flow_req->data.access_int_id, device_id, physical_if_id);
+
+ /* set the gem port object key */
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = p_flow_req->data.svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, xgpon_gem_port, gem_key);
+ BCMOLT_CFG_PROP_GET(&gem_cfg, xgpon_gem_port, all_properties);
+
+ rc = bcmolt_cfg_get(device_id, &gem_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "%s FAILED to gem xgpon_gem_port configuration : device_id = %d if_id = %d gem_port_id = %d \n",
+ __FUNCTION__,
+ device_id, p_flow_req->data.access_int_id, p_flow_req->data.svc_port_id);
+
+ return rc;
+ }
+
+ if ( BCMOLT_XGPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state)
+ {
+ p_mac_util_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
+ }
+ return rc;
+}
+
+/**
+ * @brief flow set for xgpon (XG-PON1)
+ * @param p_flow_req pointer to flow request structure from core
+ * @param op_type ADD, REMOVE or CLEAR
+ * @param p_flow_core core FSM DB flow context passed as a cookie
+ *
+ * @return errno error
+ *
+ * @todo shift this out to mac specific files
+ */
+bcmos_errno mac_util_flow_set_for_xgpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint16_t per_flow_mode_vlan_id = 0; /* hold the value of the vlan tag to use in per-flow mode */
+ uint8_t pbits_val = 0;
+ flow_list_entry *p_mac_util_flow_entry = NULL;
+
+ /* Check the operation id */
+ if ((BAL_UTIL_OPER_FLOW_ADD != op_type) &&
+ (BAL_UTIL_OPER_FLOW_REMOVE != op_type) &&
+ (BAL_UTIL_OPER_FLOW_CLEAR != op_type))
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unexpected mac_util flow operation %d \n", op_type);
+ return BCM_ERR_PARM;
+ }
+
+ /* flow Add or Modify */
+ if (BAL_UTIL_OPER_FLOW_ADD == op_type)
+ {
+ switch (p_flow_req->key.flow_type)
+ {
+ /* unicast flows */
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ {
+ if (p_flow_req->data.classifier.o_pbits)
+ {
+ /* o_pbits can only take one p-bit value */
+ pbits_val = p_flow_req->data.classifier.o_pbits;
+ }
+ else
+ {
+ pbits_val = 0;
+ }
+
+ /* create a gem port id and relevant flow for a single pbit, or with no pbit */
+ /* pass on the op type also to specify if it is FLOW_ADD OR FLOW_MODIFY */
+ rc = maple_mac_unicast_flow_add(p_flow_req, pbits_val, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
+ if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
+ {
+ break;
+ }
+
+ /* mark flow configuration to device completed */
+ mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
+ rc = maple_mac_xgpon_update_svc_port_ind_flag (p_flow_req, p_mac_util_flow_entry);
+
+ }
+ break;
+
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ {
+ rc = maple_mac_broadcast_flow_add(p_flow_req, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
+ }
+ break;
+
+ default:
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow type %d\n",
+ p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) ||
+ (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ /* find the flow */
+ p_mac_util_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow_req->data.access_int_id, &(p_flow_req->key));
+ if (NULL == p_mac_util_flow_entry)
+ {
+ rc = BCM_ERR_NOENT;
+ if (BAL_UTIL_OPER_FLOW_CLEAR != op_type)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "%s: NULL mac util flow entry to remove: flow id: %d, flow_type: %s\n",
+ __FUNCTION__,
+ p_flow_req->key.flow_id,
+ (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "up":"down"));
+ }
+
+ goto exit;
+ }
+
+ switch (p_flow_req->key.flow_type)
+ {
+ /* unicast flows */
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ {
+ /** Remove unicast GEM/Alloc Id from Maple and flow entry from local database */
+ rc = maple_mac_unicast_flow_remove(p_flow_req, op_type, p_mac_util_flow_entry);
+ if (BCM_ERR_OK != rc)
+ {
+ break;
+ }
+
+ /* mark flow De-configuration to device completed */
+ mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
+ }
+ break;
+
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ {
+ rc = maple_mac_broadcast_flow_remove(p_flow_req, per_flow_mode_vlan_id, op_type, p_mac_util_flow_entry);
+ }
+ break;
+
+ default:
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow type %d\n",
+ p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+
+ } /* Flow Remove */
+ else
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
+ "Unknown flow op type %d for flow id/type = %d/%d\n",
+ op_type, p_flow_req->key.flow_id, p_flow_req->key.flow_type);
+ rc = BCM_ERR_PARM;
+ }
+
+exit:
+ if (BCM_ERR_OK == rc)
+ {
+ /*
+ * Check flow entry flags to see if an indication to Core should be triggered immediately:
+ * (Special handling for flow configuration, for the case no device configuration is needed,
+ * and/or no indication from device is expected - could be the case of a single/multiple
+ * gem ports used for us and ds, and us was already configured.
+ * - send the flow ind immediately
+ */
+ check_send_flow_bal_ind_msg(p_mac_util_flow_entry, BCM_ERR_OK, BCMOLT_RESULT_SUCCESS);
+ }
+ else
+ {
+ if ((BCM_ERR_NOENT == rc) && (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
+ {
+ /*
+ * For flow CLEAR, and if no flow entry is found, then fake an indication success to Core,
+ * for it to execute the flow state machine.
+ * The reasons for flow entry not found could be because the flow was already admin-ed Down.
+ * Admin-down of a flow causes mac util to clear flow config and flow instance from itself
+ * and the maple HW. However, Core FSM still keeps it's flow instance during admin down state.
+ */
+ mac_util_report_flow_remove_success (p_flow_req->key, p_flow_req->data.access_int_id, op_type);
+ rc = BCM_ERR_OK;
+ }
+ }
+ //else if there was an error during config, just return a failure; no need to send back indication for that.
+
+
+ return rc;
+}
+
+bcmos_errno maple_xgpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
+ bcmos_bool *is_configured, bcmos_bool *is_activated)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_gem_port_key gem_key = {};
+ bcmolt_xgpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the gem port object key */
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, xgpon_gem_port, gem_key);
+ BCMOLT_CFG_PROP_GET(&gem_cfg, xgpon_gem_port, all_properties);
+
+ rc = bcmolt_cfg_get(device_id, &gem_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED to gem xgpon_gem_port configuration : device_id = %d if_id = %d gem_port_id = %d \n",
+ __FUNCTION__,
+ device_id, if_id, svc_port_id);
+ return rc;
+ }
+
+ /* may be configured; does gem belong to same onu ? */
+ if (BCMOLT_XGPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state && onu_id != gem_cfg.data.onu_id)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED, onu id mismatch: svc_port_id = %d if_id = %d is already assigned to onu_id = %d (not to onu id %d) \n",
+ __FUNCTION__,
+ svc_port_id, if_id, gem_cfg.data.onu_id, onu_id);
+ return BCM_ERR_PARM;
+ }
+ *is_configured = BCMOLT_XGPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state;
+ *is_activated = BCMOLT_XGPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state;
+
+ return rc;
+}
+
+
+bcmos_errno maple_xgpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_gem_port_key gem_key = {};
+ bcmolt_xgpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the gem port object key */
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, xgpon_gem_port, gem_key);
+
+ /* set the gem port configuration */
+ if (onu_id < BCMOLT_XGPON_ONU_ID_ANY)
+ {
+ BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, onu_id, onu_id);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, upstream_destination_queue,
+ BCMOLT_US_GEM_PORT_DESTINATION_DATA);
+ }
+ BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, encryption_mode,
+ BCMOLT_CONTROL_STATE_DISABLE);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, configuration, *configuration);
+ BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, control, BCMOLT_CONTROL_STATE_ENABLE);
+
+ rc = bcmolt_cfg_set(device_id, &gem_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED: rc=%s (%d), svc_port_id = %d if_id = %d onu_id = %d, err_text=%s\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), rc, svc_port_id, if_id, onu_id, gem_cfg.hdr.hdr.err_text);
+ }
+
+ return rc;
+}
+
+
+bcmos_errno maple_xgpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_gem_port_key gem_key = {};
+ bcmolt_xgpon_gem_port_cfg gem_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ gem_key.pon_ni = physical_if_id;
+ gem_key.gem_port_id = svc_port_id;
+ BCMOLT_CFG_INIT(&gem_cfg, xgpon_gem_port, gem_key);
+ rc = bcmolt_cfg_clear(device_id, &gem_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+
+ return rc;
+}
+
+
+bcmos_errno maple_xgpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state)
+
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_alloc_key alloc_key = {};
+ bcmolt_xgpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, xgpon_alloc, alloc_key);
+ BCMOLT_CFG_PROP_GET(&alloc_cfg, xgpon_alloc, all_properties);
+
+ rc = bcmolt_cfg_get(device_id, &alloc_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s: FAILED in bcmolt_cfg_get rc = %s, agg_id = %d if_id = %d\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), agg_id, if_id);
+
+ return rc;
+ }
+
+ /* may be configured; does alloc id belong to the expected onu ? */
+ if (alloc_cfg.data.state != BCMOLT_ALLOC_STATE_NOT_CONFIGURED
+ && alloc_cfg.data.onu_id != onu_id)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s FAILED, onu id mismatch: agg_id = %d if_id = %d is set to onu %d NOT to onu_id = %d\n",
+ __FUNCTION__,
+ agg_id, if_id, alloc_cfg.data.onu_id, onu_id);
+
+ return BCM_ERR_PARM;
+ }
+ *alloc_id_state = alloc_cfg.data.state;
+
+ return BCM_ERR_OK;
+}
+
+
+bcmos_errno maple_xgpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_alloc_key alloc_key = {};
+ bcmolt_xgpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, xgpon_alloc, alloc_key);
+
+ BCMOLT_CFG_PROP_SET(&alloc_cfg, xgpon_alloc, sla, agg_sla);
+ /* set the alloc-id - onu assignment */
+ BCMOLT_CFG_PROP_SET(&alloc_cfg, xgpon_alloc, onu_id, onu_id);
+
+ rc = bcmolt_cfg_set(device_id, &alloc_cfg.hdr);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "%s: rc = %s, agg_id = %d if_id = %d, sla = {g bw: %d, max bw: %d, cb_nrt_bw: %d, cb_rt_bw: %d}\n",
+ __FUNCTION__,
+ bcmos_strerror(rc), agg_id, if_id,
+ agg_sla.guaranteed_bw, agg_sla.maximum_bw, agg_sla.cbr_nrt_bw, agg_sla.cbr_rt_bw);
+
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
+ "err_text = %s\n",
+ alloc_cfg.hdr.hdr.err_text);
+ }
+ return rc;
+}
+
+
+bcmos_errno maple_xgpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_xgpon_alloc_key alloc_key = {};
+ bcmolt_xgpon_alloc_cfg alloc_cfg = {};
+ bcmolt_devid device_id;
+ uint32_t physical_if_id;
+
+ GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
+
+ /* set the alloc-id key */
+ alloc_key.pon_ni = physical_if_id;
+ alloc_key.alloc_id = agg_id;
+ BCMOLT_CFG_INIT(&alloc_cfg, xgpon_alloc, alloc_key);
+
+ rc = bcmolt_cfg_clear(device_id, &alloc_cfg.hdr);
+ if (BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
+ }
+ return rc;
+}
+
+/**
+ * @brief group set for xgpon (XG-PON1)
+ * @param p_group_req pointer to group request structure from core
+ * @param op_type ADD, REMOVE or SET
+ * @param p_group_inst pointer to the Core Group Object instance
+ *
+ * @return errno error
+ *
+ * @todo shift this out to mac specific files
+ */
+bcmos_errno mac_util_group_set_for_xgpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_inst)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ uint16_t svc_port_id;
+ uint32_t if_id, i, ref_count;
+ bcmolt_gem_port_configuration configuration = {0};
+
+ /* Check the operation id */
+ if ((BAL_UTIL_OPER_GROUP_ADD != op_type) &&
+ (BAL_UTIL_OPER_GROUP_REMOVE != op_type) &&
+ (BAL_UTIL_OPER_GROUP_SET != op_type))
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "Unexpected mac_util xgpon group operation %d \n", op_type);
+ return BCM_ERR_PARM;
+ }
+
+ configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
+ configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
+
+ /* for group SET operation, first remove the old multicast GEM */
+ if (BAL_UTIL_OPER_GROUP_SET == op_type)
+ {
+ bcmbal_group_cfg *p_group_rem_req;
+ /* use the Core DB for existing members - store in current_flow_info */
+ p_group_rem_req = &p_group_inst->current_group_info;
+ for(i=0; i< p_group_rem_req->data.members.len; i++)
+ {
+ if_id = p_group_rem_req->data.members.val[i].intf_id;
+ svc_port_id = p_group_rem_req->data.members.val[i].svc_port_id;
+ /* svc_port_id may be 0 in the current info when the group had no owner.
+ skip the remove if that is the case */
+ if(svc_port_id)
+ {
+ rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util xgpon group get reference count on interface %d (gem %d) failed \n", if_id, svc_port_id);
+ return rc;
+ }
+ /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
+ The core will ask Resource Manger to decrease the counter if everything is good */
+ if ( ref_count == 1)
+ {
+ rc = maple_xgpon_gem_port_id_remove(if_id, svc_port_id);
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util xgpon group set operation SET on remove interface %d (gem %d) failed \n", if_id, svc_port_id);
+ return rc;
+ }
+ }
+ else if ( ref_count == 0)
+ {
+ BCM_LOG(WARNING, log_id_mac_util,
+ "mac_util xgpon group operation SET on interface %d (gem %d) remove with 0 reference count \n", if_id, svc_port_id);
+ }
+ }
+ }
+ }
+
+ /* walk through every member interface */
+ for(i=0; i< p_group_req->data.members.len; i++)
+ {
+ if_id = p_group_req->data.members.val[i].intf_id;
+ svc_port_id = p_group_req->data.members.val[i].svc_port_id;
+ /* group Add */
+ if (BAL_UTIL_OPER_GROUP_ADD == op_type || BAL_UTIL_OPER_GROUP_SET == op_type)
+ {
+ rc = maple_xgpon_gem_port_id_add(if_id, svc_port_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM, &configuration);
+ }
+ else if (BAL_UTIL_OPER_GROUP_REMOVE == op_type)
+ {
+ rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util xgpon group REM get reference count on interface %d (gem %d) failed \n", if_id, svc_port_id);
+ break;
+ }
+ /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
+ The core will ask Resource Manger to decrease the counter if everything is good */
+ if ( ref_count == 1)
+ {
+ rc = maple_xgpon_gem_port_id_remove(if_id, svc_port_id);
+ }
+ else if ( ref_count == 0)
+ {
+ BCM_LOG(WARNING, log_id_mac_util,
+ "mac_util xgpon group operation REM on interface %d (gem %d) remove with 0 reference count \n", if_id, svc_port_id);
+ }
+ }
+
+ if(BCM_ERR_OK != rc)
+ {
+ BCM_LOG(ERROR, log_id_mac_util,
+ "mac_util xgpon group set of operation %d on interface %d (gem %d) failed \n", op_type, if_id, svc_port_id);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+/*@}*/
diff --git a/bal_release/src/core/util/oam/Makefile b/bal_release/src/core/util/oam/Makefile
new file mode 100644
index 0000000..e87d3a4
--- /dev/null
+++ b/bal_release/src/core/util/oam/Makefile
@@ -0,0 +1,40 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL core CLI application
+#
+MOD_NAME = bal_oam_util
+MOD_TYPE = lib
+MOD_DEPS = maple_sdk bcm_user_appl_epon_oam bcm_user_appl_eon
+
+srcs = bal_oam_util.c
+
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../main
+
diff --git a/bal_release/src/core/util/oam/bal_oam_util.c b/bal_release/src/core/util/oam/bal_oam_util.c
new file mode 100644
index 0000000..fe051f9
--- /dev/null
+++ b/bal_release/src/core/util/oam/bal_oam_util.c
@@ -0,0 +1,459 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_oam_util.c
+ *
+ * @brief OAM util interfaces definition used by Bal Core
+ *
+ * This file expose the APIs to the core to configure ONU via EPON OAM
+ *
+ * @addtogroup oam_util
+ */
+
+/*@{*/
+
+#include "bal_oam_util.h"
+#include <bcmolt_user_appl_epon_oam.h>
+#include <bcmolt_eon.h>
+#include <bcmolt_eon_log.h>
+#include <bcmolt_epon_oam_types.h>
+
+#define BAL_OAM_TIMEOUT_US 1000000 /* 1 second */
+
+typedef enum
+{
+ BAL_OAM_STATE_IDLE,
+ BAL_OAM_STATE_SET_OAM_RATE,
+ BAL_OAM_STATE_CLEAR_INGRESS_RULES_NETWORK_PON,
+ BAL_OAM_STATE_CLEAR_INGRESS_RULES_USER_PORT,
+ BAL_OAM_STATE_SET_BASIC_QUEUE_CONFIG,
+ BAL_OAM_STATE_ADD_INGRESS_RULES_NETWORK_PON,
+ BAL_OAM_STATE_ADD_INGRESS_RULES_USER_PORT,
+ BAL_OAM_STATE_SET_REPORT_THRESHOLDS,
+ BAL_OAM_STATE_ENABLE_USER_TRAFFIC,
+ BAL_OAM_STATE_DISABLE_USER_TRAFFIC,
+ BAL_OAM_STATE__NUM_OF,
+} bal_oam_state;
+
+typedef enum
+{
+ BAL_OAM_EVENT_ACK,
+ BAL_OAM_EVENT_TIMEOUT,
+ BAL_OAM_EVENT__NUM_OF,
+} bal_oam_event;
+
+typedef struct bal_oam_context
+{
+ TAILQ_ENTRY(bal_oam_context) next;
+ bal_oam_cb cb;
+ void *context;
+ bcmolt_devid device_id;
+ bcmolt_epon_ni epon_ni;
+ bcmos_mac_address mac;
+ bcmos_timer timer;
+ bal_oam_state state;
+} bal_oam_context;
+
+typedef struct
+{
+ bcmos_msg m;
+ bcmolt_devid device_id;
+ bcmolt_epon_ni epon_ni;
+ bcmos_mac_address mac;
+} bal_oam_timeout_msg;
+
+typedef bcmos_errno (*bal_oam_sm_cb)(bal_oam_context *context);
+
+static TAILQ_HEAD(, bal_oam_context) bal_oam_contexts = TAILQ_HEAD_INITIALIZER(bal_oam_contexts);
+
+static bal_oam_context *bal_oam_get_context(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac)
+{
+ bal_oam_context *iter;
+
+ TAILQ_FOREACH(iter, &bal_oam_contexts, next)
+ {
+ if (device_id == iter->device_id && epon_ni == iter->epon_ni && !memcmp(mac, &iter->mac, sizeof(*mac)))
+ break;
+ }
+ return iter;
+}
+
+static void bal_oam_negotiation_result_cb(void *context, const eon_link_key_t *link_key, bcmos_errno result)
+{
+ bal_oam_context *_context = context;
+
+ _context->cb(_context->context, _context->device_id, _context->epon_ni, &_context->mac, result);
+
+ bcmos_free(_context);
+}
+
+bcmos_errno bal_oam_start_oam_negotiation(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, bcmos_mac_address *mac, bal_oam_cb cb, void *context)
+{
+ eon_link_key_t link_key = {};
+ bal_oam_context *_context;
+
+ link_key.device_id = device_id;
+ link_key.epon_ni = epon_ni;
+ link_key.mac_address = *mac;
+
+ _context = bcmos_calloc(sizeof(*_context));
+ _context->cb = cb;
+ _context->context = context;
+ _context->device_id = device_id;
+ _context->epon_ni = epon_ni;
+ _context->mac = *mac;
+
+ return bcmolt_user_appl_eon_start(&link_key, eon_oam_set_id_dpoe, bal_oam_negotiation_result_cb, _context, BCMOS_TRUE);
+}
+
+static void bal_oam_configure_traffic_complete(bal_oam_context *context, bcmos_errno result)
+{
+ context->cb(context->context, context->device_id, context->epon_ni, &context->mac, result);
+
+ bcmos_timer_destroy(&context->timer);
+
+ TAILQ_REMOVE(&bal_oam_contexts, context, next);
+
+ /* No need to set context->state to BAL_OAM_STATE_IDLE - it is going to be destroyed here anyway. */
+ bcmos_free(context);
+}
+
+static void bal_oam_timeout_msg_cb(bcmos_module_id module_id, bcmos_msg *msg)
+{
+ bal_oam_timeout_msg *timeout_msg = (bal_oam_timeout_msg *)msg;
+ bal_oam_context *context = bal_oam_get_context(timeout_msg->device_id, timeout_msg->epon_ni, &timeout_msg->mac);
+
+ bal_oam_configure_traffic_complete(context, BCM_ERR_TIMEOUT);
+
+ bcmos_msg_free(msg);
+}
+
+static bcmos_errno bal_oam_state_any_event_timeout(bal_oam_context *context)
+{
+ bal_oam_timeout_msg *msg;
+
+ /* We should not directly call bal_oam_configure_traffic_complete() from within timer context, because in bal_oam_configure_traffic_complete() we free the memory in which the timer
+ * resides. To overcome this, we use a message - the timer will finish executing and only then the message handler will execute. */
+ msg = bcmos_calloc(sizeof(*msg));
+ msg->device_id = context->device_id;
+ msg->epon_ni = context->epon_ni;
+ msg->mac = context->mac;
+ msg->m.handler = bal_oam_timeout_msg_cb;
+ bcmos_msg_send_to_module(BCMOS_MODULE_ID_WORKER_MGMT, &msg->m, 0);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_set_oam_rate_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Clear EPON port ingress. */
+ rc = epon_oam_dpoe_clear_ingress_rules_network_pon(context->device_id, context->epon_ni, &context->mac);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_CLEAR_INGRESS_RULES_NETWORK_PON;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_clear_ingress_rules_network_pon_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Clear UNI port ingress rules. */
+ rc = epon_oam_dpoe_clear_ingress_rules_user_port(context->device_id, context->epon_ni, &context->mac);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_CLEAR_INGRESS_RULES_USER_PORT;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_clear_ingress_rules_user_port_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Set ONU queue configuration. */
+ rc = epon_oam_dpoe_set_basic_queue_config(context->device_id, context->epon_ni, &context->mac, 255, 255);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_SET_BASIC_QUEUE_CONFIG;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_set_basic_queue_config_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Add EPON port ingress rules */
+ rc = epon_oam_dpoe_add_ingress_rules_network_pon(context->device_id, context->epon_ni, &context->mac, DPOE_RULE_VLAN_MODE_NONE, NULL);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_ADD_INGRESS_RULES_NETWORK_PON;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_add_ingress_rules_network_pon_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Add UNI port ingress rules. */
+ rc = epon_oam_dpoe_add_ingress_rules_user_port(context->device_id, context->epon_ni, &context->mac, DPOE_RULE_VLAN_MODE_NONE, NULL);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_ADD_INGRESS_RULES_USER_PORT;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_add_ingress_rules_user_port_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+ bcmolt_epon_oam_queue_sets queue_sets =
+ {
+ [0] = {16256},
+ [1] = {32512},
+ [2] = {48768},
+ [3] = {65024},
+ };
+
+ /* Set ONU report thresholds. */
+ rc = epon_oam_dpoe_set_report_thresholds(context->device_id, context->epon_ni, &context->mac, 1, queue_sets, 4);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_SET_REPORT_THRESHOLDS;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_set_report_thresholds_event_ack(bal_oam_context *context)
+{
+ bcmos_errno rc;
+
+ /* Enable user traffic. */
+ rc = epon_oam_dpoe_enable_user_traffic(context->device_id, context->epon_ni, &context->mac);
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(context, rc);
+ return rc;
+ }
+
+ bcmos_timer_start(&context->timer, BAL_OAM_TIMEOUT_US);
+
+ context->state = BAL_OAM_STATE_ENABLE_USER_TRAFFIC;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_enable_user_traffic_event_ack(bal_oam_context *context)
+{
+ bal_oam_configure_traffic_complete(context, BCM_ERR_OK);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_oam_state_disable_user_traffic_event_ack(bal_oam_context *context)
+{
+ bal_oam_configure_traffic_complete(context, BCM_ERR_OK);
+
+ return BCM_ERR_OK;
+}
+
+static bal_oam_sm_cb bal_oam_state_machine[BAL_OAM_STATE__NUM_OF][BAL_OAM_EVENT__NUM_OF] =
+{
+ [BAL_OAM_STATE_SET_OAM_RATE] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_set_oam_rate_event_ack,
+ },
+ [BAL_OAM_STATE_CLEAR_INGRESS_RULES_NETWORK_PON] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_clear_ingress_rules_network_pon_event_ack,
+ },
+ [BAL_OAM_STATE_CLEAR_INGRESS_RULES_USER_PORT] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_clear_ingress_rules_user_port_event_ack,
+ },
+ [BAL_OAM_STATE_SET_BASIC_QUEUE_CONFIG] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_set_basic_queue_config_event_ack,
+ },
+ [BAL_OAM_STATE_ADD_INGRESS_RULES_NETWORK_PON] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_add_ingress_rules_network_pon_event_ack,
+ },
+ [BAL_OAM_STATE_ADD_INGRESS_RULES_USER_PORT] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_add_ingress_rules_user_port_event_ack,
+ },
+ [BAL_OAM_STATE_SET_REPORT_THRESHOLDS] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_set_report_thresholds_event_ack,
+ },
+ [BAL_OAM_STATE_ENABLE_USER_TRAFFIC] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_enable_user_traffic_event_ack,
+ },
+ [BAL_OAM_STATE_DISABLE_USER_TRAFFIC] =
+ {
+ [BAL_OAM_EVENT_TIMEOUT] = bal_oam_state_any_event_timeout,
+ [BAL_OAM_EVENT_ACK] = bal_oam_state_disable_user_traffic_event_ack,
+ },
+};
+
+static void bal_oam_sm_run(bal_oam_context *context, bal_oam_event event)
+{
+ bal_oam_sm_cb cb = bal_oam_state_machine[context->state][event];
+
+ cb(context);
+}
+
+static bcmos_timer_rc bal_oam_timeout_cb(bcmos_timer *timer, long data)
+{
+ bal_oam_context *context = (bal_oam_context *)data;
+
+ bal_oam_sm_run(context, BAL_OAM_EVENT_TIMEOUT);
+
+ return BCMOS_TIMER_OK;
+}
+
+bcmos_errno bal_oam_configure_traffic(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, bcmos_mac_address *mac, bcmos_bool is_enabled, bal_oam_cb cb, void *context)
+{
+ bcmos_errno rc;
+ bal_oam_context *_context;
+ bcmos_timer_parm timer_params =
+ {
+ .name = "bal_oam_timer",
+ .owner = BCMOS_MODULE_ID_WORKER_MGMT,
+ .handler = bal_oam_timeout_cb,
+ };
+
+ _context = bcmos_calloc(sizeof(*_context));
+ _context->cb = cb;
+ _context->context = context;
+ _context->device_id = device_id;
+ _context->epon_ni = epon_ni;
+ _context->mac = *mac;
+ TAILQ_INSERT_TAIL(&bal_oam_contexts, _context, next);
+
+ if (is_enabled)
+ {
+ /* Set OAM rate. */
+ rc = epon_oam_dpoe_set_oam_rate(device_id, epon_ni, mac, 10, 3);
+ }
+ else
+ {
+ /* Disable user traffic. */
+ rc = epon_oam_dpoe_disable_user_traffic(device_id, epon_ni, mac);
+ }
+ if (rc != BCM_ERR_OK)
+ {
+ bal_oam_configure_traffic_complete(_context, rc);
+ return rc;
+ }
+
+ timer_params.data = (long)_context;
+ bcmos_timer_create(&_context->timer, &timer_params);
+ bcmos_timer_start(&_context->timer, BAL_OAM_TIMEOUT_US);
+
+ if (is_enabled)
+ _context->state = BAL_OAM_STATE_SET_OAM_RATE;
+ else
+ _context->state = BAL_OAM_STATE_DISABLE_USER_TRAFFIC;
+
+ return BCM_ERR_OK;
+}
+
+/* TODO: Currently we ignore rc. But we may want to check it. */
+void bal_oam_proxy_rx_cb(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac, bcmolt_user_appl_epon_oam_rx_id id, bcmos_errno rc)
+{
+ bal_oam_context *context;
+
+ if (id != BCMOLT_USER_APPL_EPON_OAM_RX_ID_DPOE_SET_RESPONSE)
+ return;
+
+ /* If applying set command not from within bal_oam_configure_traffic() (for example, from BAL CLI), context might be NULL. */
+ context = bal_oam_get_context(device_id, epon_ni, mac);
+ if (!context)
+ return;
+
+ bal_oam_sm_run(context, BAL_OAM_EVENT_ACK);
+}
+
+/*@}*/
+
diff --git a/bal_release/src/core/util/oam/bal_oam_util.h b/bal_release/src/core/util/oam/bal_oam_util.h
new file mode 100644
index 0000000..69af195
--- /dev/null
+++ b/bal_release/src/core/util/oam/bal_oam_util.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_oam_util.h
+ *
+ * @brief OAM util interfaces header file
+ *
+ * This file expose the APIs to the core to configure ONU via EPON OAM
+ *
+ * @defgroup oam_util OAM Util
+ * @ingroup core
+ */
+
+#ifndef BAL_OAM_UTIL_H
+#define BAL_OAM_UTIL_H
+
+#include <bcmolt_host_api.h>
+#include <bcmolt_user_appl_epon_oam.h>
+
+typedef void (*bal_oam_cb)(void *context, bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac_address, bcmos_errno result);
+
+/*****************************************************************************/
+/**
+ * @brief Start OAM negotiation for a given MAC address.
+ *
+ * @param device_id Device ID for which we start OAM negotiation
+ * @param epon_ni EPON NI for which we start OAM negotiation
+ * @param mac MAC address for which we start OAM negotiation
+ * @param cb Callback called upon completion, with success or failure
+ * code. If omitted, a default callback will be called and
+ * it will just log the return code
+ * @param context context for the above callback
+ *
+ * @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise
+ *
+ *****************************************************************************/
+bcmos_errno bal_oam_start_oam_negotiation(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, bcmos_mac_address *mac, bal_oam_cb cb, void *context);
+
+/*****************************************************************************/
+/**
+ * @brief Enable traffic for a given MAC address.
+ *
+ * @param device_id Device ID for which we enable/disable traffic
+ * @param epon_ni EPON NI for which we enable/disable traffic
+ * @param mac MAC address for which we enable/disable traffic
+ * @param is_enabled Whether we should enable or disable traffic
+ * @param cb Callback called upon completion, with success or failure
+ * code. If omitted, a default callback will be called and
+ * it will just log the return code
+ * @param context context for the above callback
+ *
+ * @returns BCM_ERR_OK on success, other bcmos_errno codes otherwise
+ *
+ *****************************************************************************/
+bcmos_errno bal_oam_configure_traffic(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, bcmos_mac_address *mac, bcmos_bool is_enabled, bal_oam_cb cb, void *context);
+
+/*****************************************************************************/
+/**
+ * @brief Callback being called whenever an OAM message (proxy rx) arrives and
+ * processed by bcmolt_user_appl_epon_oam_handle_proxy_rx().
+ *
+ * @param device_id Device ID for which we got the message
+ * @param epon_ni EPON NI for which we got the message
+ * @param mac MAC address for which we got the message
+ * @param id The type of message
+ * @param rc OAM response success/fail code
+ *
+ *****************************************************************************/
+void bal_oam_proxy_rx_cb(bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac, bcmolt_user_appl_epon_oam_rx_id id, bcmos_errno rc);
+
+#endif
+
diff --git a/bal_release/src/core/util/oam/common_epon_oam b/bal_release/src/core/util/oam/common_epon_oam
new file mode 120000
index 0000000..5376be7
--- /dev/null
+++ b/bal_release/src/core/util/oam/common_epon_oam
@@ -0,0 +1 @@
+../../../../3rdparty/maple/sdk/host_reference/common_epon_oam
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/Makefile b/bal_release/src/core/util/oam/eon/Makefile
new file mode 100644
index 0000000..bc94abe
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/Makefile
@@ -0,0 +1,57 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# EPON OAM Negotiation user application
+
+ifeq ("$(ENABLE_CLI)", "y")
+
+ MOD_NAME = bcm_user_appl_eon
+ MOD_TYPE = lib
+ MOD_DEPS = bal_api common_epon_oam bcm_user_appl_epon_oam
+
+ ifeq ("$(OS_KERNEL)", "linux")
+ MOD_DEPS += dev_log_linux
+ endif
+
+ srcs = bcmolt_eon.c bcmolt_eon_log.c bcmolt_oam_heartbeat.c
+
+ ENABLE_DPOE_OAM ?= y
+ ifeq ("$(ENABLE_DPOE_OAM)", "y")
+ EXTRA_DEFINES += -DEON_OAM_SET_DPOE_SUPPORTED
+ srcs += oam_sets/dpoe/dpoe.c
+ endif # ENABLE_DPOE_OAM
+
+ ENABLE_BRCM_OAM ?= y
+ ifeq ("$(ENABLE_BRCM_OAM)", "y")
+ EXTRA_DEFINES += -DEON_OAM_SET_BRCM_SUPPORTED
+ srcs += oam_sets/brcm/brcm.c
+ endif # ENABLE_BRCM_OAM
+
+endif
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_eon.c b/bal_release/src/core/util/oam/eon/bcmolt_eon.c
new file mode 120000
index 0000000..8f3003d
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_eon.c
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_eon.c
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_eon.h b/bal_release/src/core/util/oam/eon/bcmolt_eon.h
new file mode 120000
index 0000000..d7f8504
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_eon.h
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_eon.h
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_eon_log.c b/bal_release/src/core/util/oam/eon/bcmolt_eon_log.c
new file mode 120000
index 0000000..73c5c57
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_eon_log.c
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_eon_log.c
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_eon_log.h b/bal_release/src/core/util/oam/eon/bcmolt_eon_log.h
new file mode 120000
index 0000000..164ba04
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_eon_log.h
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_eon_log.h
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_eon_private.h b/bal_release/src/core/util/oam/eon/bcmolt_eon_private.h
new file mode 120000
index 0000000..3417ea1
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_eon_private.h
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_eon_private.h
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.c b/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.c
new file mode 120000
index 0000000..ee96fc5
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.c
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_oam_heartbeat.c
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.h b/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.h
new file mode 120000
index 0000000..a45c1cd
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/bcmolt_oam_heartbeat.h
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/bcmolt_oam_heartbeat.h
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/doc b/bal_release/src/core/util/oam/eon/doc
new file mode 120000
index 0000000..9a076c6
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/doc
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/doc
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/eon/oam_sets b/bal_release/src/core/util/oam/eon/oam_sets
new file mode 120000
index 0000000..a9926e8
--- /dev/null
+++ b/bal_release/src/core/util/oam/eon/oam_sets
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/eon/oam_sets
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/epon_oam/Makefile b/bal_release/src/core/util/oam/epon_oam/Makefile
new file mode 100644
index 0000000..969352a
--- /dev/null
+++ b/bal_release/src/core/util/oam/epon_oam/Makefile
@@ -0,0 +1,42 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+ifeq ("$(ENABLE_CLI)", "y")
+ MOD_NAME = bcm_user_appl_epon_oam
+ MOD_TYPE = lib
+ MOD_DEPS = utils dev_log common_epon_oam bal_api
+
+ srcs = bcmolt_user_appl_epon_oam.c
+
+ ifeq ("$(OS_KERNEL)", "linux")
+ MOD_DEPS += dev_log_linux
+ endif
+endif
+
diff --git a/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.c b/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.c
new file mode 120000
index 0000000..90fbfee
--- /dev/null
+++ b/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.c
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/epon_oam/bcmolt_user_appl_epon_oam.c
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.h b/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.h
new file mode 120000
index 0000000..ed97c3f
--- /dev/null
+++ b/bal_release/src/core/util/oam/epon_oam/bcmolt_user_appl_epon_oam.h
@@ -0,0 +1 @@
+../../../../../3rdparty/maple/sdk/host_reference/user_appl/epon_oam/bcmolt_user_appl_epon_oam.h
\ No newline at end of file
diff --git a/bal_release/src/core/util/oam/epon_oam_cli b/bal_release/src/core/util/oam/epon_oam_cli
new file mode 120000
index 0000000..f758382
--- /dev/null
+++ b/bal_release/src/core/util/oam/epon_oam_cli
@@ -0,0 +1 @@
+../../../../3rdparty/maple/sdk/host_reference/user_appl/epon_oam_cli
\ No newline at end of file
diff --git a/bal_release/src/core/util/switch/Makefile b/bal_release/src/core/util/switch/Makefile
new file mode 100644
index 0000000..d9f3aae
--- /dev/null
+++ b/bal_release/src/core/util/switch/Makefile
@@ -0,0 +1,46 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL Switch Util
+MOD_NAME = bal_switch_util
+MOD_TYPE = lib
+MOD_DEPS = dev_log utils bal_api bal_app_utils switch_util_dpp switch_util_esw
+srcs = bal_switch_util.c bal_switch_acc_term.c bal_switch_flow.c bal_switch_cli.c bal_switch_interface.c bal_switch_group.c bal_switch_tm_sched.c bal_switch_tm_queue.c
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../main
+
+ifeq ("$(TEST_SW_UTIL_LOOPBACK)", "y")
+ MOD_DEFS += -DTEST_SW_UTIL_LOOPBACK
+else
+ MOD_DEPS += switch_sdk
+endif
+
+ifeq ("$(SWITCH)", "kt2")
+ MOD_DEFS += -DESW_SWITCH
+endif
diff --git a/bal_release/src/core/util/switch/bal_switch_acc_term.c b/bal_release/src/core/util/switch/bal_switch_acc_term.c
new file mode 100644
index 0000000..fb1be7b
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_acc_term.c
@@ -0,0 +1,1071 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+#include "bal_switch_flow.h"
+#include <bal_worker.h>
+/* declare ENV so that the bcm/rx.h in the bal_dpp_acc_term.h can create the correct bcm_pkt_t structure */
+#ifdef ESW_SWITCH
+#define BCM_ESW_SUPPORT 1
+#else
+#define BCM_DNX_SUPPORT 1
+#endif
+#include "esw/bal_esw_acc_term.h"
+#include "dpp/bal_dpp_acc_term.h"
+/* Below local functions are used for real logic only */
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <arpa/inet.h>
+#include <bcm/init.h>
+#include <bcm/types.h>
+#include <bcm/port.h>
+#include <appl/diag/shell.h> /* for .soc loading */
+
+extern int socdiag_main(int argc, char *argv[]);
+
+/**
+ * @file bal_switch_acc_term.c
+ * @brief BAL Switch util functions that handle access terminal requests
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+/* forward declaration */
+static void sw_util_bcm_rx_cb (int unit, int port, int reason, unsigned char *p_payload, int payload_len);
+
+/* define a customized dpp packetIn receive registration function.
+ * This function will be called when the HW trap a CPU bound packet
+ */
+static bcm_rx_t dpp_rx_cb_register(int unit, bcm_pkt_t *pkt, void *cookie)
+{
+ int src_port, reason_code, payload_len;
+ unsigned char *p_payload;
+
+ /* extract trap code, ingress port and payload info */
+ src_port = pkt->src_port & 0xff;
+ reason_code = pkt->rx_trap_data;
+ p_payload = pkt->_pkt_data.data + (pkt->tot_len - pkt->pkt_len);
+ payload_len = pkt->pkt_len;
+
+ /* call sw_util_bcm_rx_cb to send packet to the BAL client */
+ sw_util_bcm_rx_cb(unit, src_port, reason_code, p_payload, payload_len);
+ return BCM_RX_HANDLED;
+}
+
+/* The default switch device the switch app is managed */
+#ifdef CONFIG_SWITCH_RPC
+static uint32_t g_dft_dev_id = 2;
+#else
+static uint32_t g_dft_dev_id = 0;
+#endif
+static uint32_t g_iwf_mode = 0;
+static uint32_t g_l2_age_time = 300;
+
+/* flag to determine if we need RPC for switch communication */
+#ifdef CONFIG_SWITCH_RPC
+static uint32_t g_use_rpc = 1;
+#else
+static uint32_t g_use_rpc = 0;
+#endif
+
+/* Socket to be connected to the switch driver msg receiving UDP port */
+bcmos_bool g_pkt_send_is_initialized = BCMOS_FALSE;
+
+static trap_target s_target_device;
+
+/* Index to determine which interface mapping table should be used.
+ * The mapping table is HW specific and depend on how physical wires are lay out
+ * Any customized board may need a different table entry to reflect the connections
+ */
+static bal_swapp_port_map_indx g_intf_maptable = BAL_SWAPP_PORT_MAP_GPON;
+
+ /* the logical interface to KT2 port mapping table
+ the tables is index by technology then logical interface number that used in the BAL CLI
+ the data is the switch port-bit-map number and device number
+*/
+
+/* table with gpon technology
+ based on KT2 port config option 4 - see page 22 on KT2 data sheet */
+/* gpon network interface mapping -
+ * KT2 is for Broadcom experiment purpose - not all function will work */
+bal_swapp_port net_inf_map_gpon[] = {
+ { 27, /* xe0 */ 0},
+ { 28, /* xe1 */ 0},
+ { 30, /* xe2 */ 0},
+ { 33, /* xe3 */ 0},
+ { 40, /* ge24 */ 0},
+ { -1, /* end */ 0}
+ };
+/* ARAD temp mapping xe128 - xe131 as nni ports */
+/* ARAD is for Broadcom experiment purpose - not all function will work */
+bal_swapp_port net_inf_map_exp[] = {
+ { 128, /* xe128 */ 0},
+ { 129, /* xe129 */ 0},
+ { 130, /* xe130 */ 0},
+ { 131, /* xe131 */ 0},
+ { -1, /* end */ 0}
+ };
+/* QAX temp mapping xe128-132 as nni ports 0-4 */
+bal_swapp_port net_inf_map_exp2[] = {
+ { 128, /* xe128 */ 0},
+ { 129, /* xe129 */ 0},
+ { 130, /* xe130 */ 0},
+ { 131, /* xe131 */ 0},
+ { 132, /* xe132 */ 0},
+ { -1, /* end */ 0}
+ };
+
+/* svk4 mapping xe128-133 as nni ports 0-5 */
+bal_swapp_port net_inf_map_svk4[] = {
+ { 128, /* xe128 */ 0},
+ { 129, /* xe129 */ 0},
+ { 130, /* xe130 */ 0},
+ { 131, /* xe131 */ 0},
+ { 132, /* xe132 */ 0},
+ { 133, /* xe133 */ 0},
+ { -1, /* end */ 0}
+ };
+
+/* epon 10g-capable mapping xe128-135 as nni ports 0-7 (best guess - needs to be tested) */
+bal_swapp_port net_inf_map_epon_tdma_10g[] = {
+ { 128, /* xe128 */ 0},
+ { 129, /* xe129 */ 0},
+ { 130, /* xe130 */ 0},
+ { 131, /* xe131 */ 0},
+ { 132, /* xe132 */ 0},
+ { 133, /* xe133 */ 0},
+ { 134, /* xe134 */ 0},
+ { 135, /* xe135 */ 0},
+ { -1, /* end */ 0}
+};
+
+/* epon 1g only mapping - copied from gpon KT2 example above (best guess - needs to be tested) */
+bal_swapp_port net_inf_map_epon_1g[] = {
+ { 27, /* xe0 */ 0},
+ { 28, /* xe1 */ 0},
+ { 30, /* xe2 */ 0},
+ { 33, /* xe3 */ 0},
+ { 40, /* ge24 */ 0},
+ { -1, /* end */ 0}
+};
+
+/* gpon pon interface mapping */
+bal_swapp_port pon_inf_map_gpon[] = {
+ { 5, /* ge4 */ 0},
+ { 6, /* ge5 */ 0},
+ { 2, /* ge1 */ 0},
+ { 1, /* ge0 */ 0},
+ { 8, /* ge7 */ 0},
+ { 7, /* ge6 */ 0},
+ { 4, /* ge3 */ 0},
+ { 3, /* ge2 */ 0},
+ { 12, /* ge11 */ 0},
+ { 19, /* ge18 */ 0},
+ { 10, /* ge9 */ 0},
+ { 15, /* ge14 */ 0},
+ { 11, /* ge10 */ 0},
+ { 17, /* ge16 */ 0},
+ { 9, /* ge8 */ 0},
+ { 13, /* ge12 */ 0},
+ { -1, /* end */ 0}
+ };
+bal_swapp_port pon_inf_map_gpon_v3[] = {
+ { 8, /* ge7 */ 0},
+ { 7, /* ge6 */ 0},
+ { 4, /* ge3 */ 0},
+ { 3, /* ge2 */ 0},
+ { 6, /* ge5 */ 0},
+ { 5, /* ge4 */ 0},
+ { 2, /* ge1 */ 0},
+ { 1, /* ge0 */ 0},
+ { 15, /* ge14 */ 0},
+ { 16, /* ge15 */ 0},
+ { 11, /* ge10 */ 0},
+ { 12, /* ge11 */ 0},
+ { 13, /* ge12 */ 0},
+ { 14, /* ge13 */ 0},
+ { 9, /* ge8 */ 0},
+ { 10, /* ge9 */ 0},
+ { -1, /* end */ 0}
+ };
+/* ARAD temp mapping xe0 - xe3 as PON ports */
+bal_swapp_port pon_inf_map_exp[] = {
+ { 0, /* xe0 */ 0},
+ { 1, /* xe1 */ 0},
+ { 2, /* xe2 */ 0},
+ { 3, /* xe3 */ 0},
+ { -1, /* end */ 0}
+ };
+/* QAX temp mapping xe1-6, as PON ports 0-5 */
+bal_swapp_port pon_inf_map_exp2[] = {
+ { 1, /* xe1 */ 0},
+ { 2, /* xe2 */ 0},
+ { 3, /* xe3 */ 0},
+ { 4, /* xe4 */ 0},
+ { 5, /* xe5 */ 0},
+ { 6, /* xe6 */ 0},
+ { -1, /* end */ 0}
+ };
+
+/* svk4 mapping xe1-4, as PON ports 0-3 */
+bal_swapp_port pon_inf_map_svk4[] = {
+ { 1, /* xe1 */ 0},
+ { 2, /* xe2 */ 0},
+ { 3, /* xe3 */ 0},
+ { 4, /* xe4 */ 0},
+ { -1, /* end */ 0}
+ };
+
+/* epon 10g-capable mapping xe1-8, as PON ports 0-7 (best guess - untested) */
+bal_swapp_port pon_inf_map_epon_tdma_10g[] = {
+ { 1, /* xe1 */ 0},
+ { 2, /* xe2 */ 0},
+ { 3, /* xe3 */ 0},
+ { 4, /* xe4 */ 0},
+ { 5, /* xe5 */ 0},
+ { 6, /* xe6 */ 0},
+ { 7, /* xe7 */ 0},
+ { 8, /* xe8 */ 0},
+ { -1, /* end */ 0}
+};
+
+/* epon 1g mapping xe1-16, as PON ports 0-15 (best guess - untested) */
+bal_swapp_port pon_inf_map_epon_1g[] = {
+ { 1, /* xe1 */ 0},
+ { 2, /* xe2 */ 0},
+ { 3, /* xe3 */ 0},
+ { 4, /* xe4 */ 0},
+ { 5, /* xe5 */ 0},
+ { 6, /* xe6 */ 0},
+ { 7, /* xe7 */ 0},
+ { 8, /* xe8 */ 0},
+ { 9, /* xe9 */ 0},
+ { 10, /* xe10 */ 0},
+ { 11, /* xe11 */ 0},
+ { 12, /* xe12 */ 0},
+ { 13, /* xe13 */ 0},
+ { 14, /* xe14 */ 0},
+ { 15, /* xe15 */ 0},
+ { 16, /* xe16 */ 0},
+ { -1, /* end */ 0}
+};
+
+/* network interface mapping table */
+bal_swapp_port *g_net_inf_map_table[BAL_SWAPP_PORT_MAP__NUM_OF] = {
+ net_inf_map_gpon, /* BAL_SWAPP_PORT_MAP_GPON */
+ net_inf_map_gpon, /* BAL_SWAPP_PORT_MAP_GPON_V3 */
+ net_inf_map_exp, /* BAL_SWAPP_PORT_MAP_EXP */
+ net_inf_map_exp2, /* BAL_SWAPP_PORT_MAP_EXP2 */
+ net_inf_map_svk4, /* BAL_SWAPP_PORT_MAP_SVK4 */
+ net_inf_map_epon_tdma_10g, /* BAL_SWAPP_PORT_MAP_EPON_TDMA */
+ net_inf_map_epon_1g, /* BAL_SWAPP_PORT_MAP_EPON_1G */
+ net_inf_map_epon_tdma_10g, /* BAL_SWAPP_PORT_MAP_EPON_10G */
+};
+/* pon interface mapping table */
+bal_swapp_port *g_pon_inf_map_table[BAL_SWAPP_PORT_MAP__NUM_OF] = {
+ pon_inf_map_gpon, /* BAL_SWAPP_PORT_MAP_GPON */
+ pon_inf_map_gpon_v3, /* BAL_SWAPP_PORT_MAP_GPON_V3 */
+ pon_inf_map_exp, /* BAL_SWAPP_PORT_MAP_EXP */
+ pon_inf_map_exp2, /* BAL_SWAPP_PORT_MAP_EXP2 */
+ pon_inf_map_svk4, /* BAL_SWAPP_PORT_MAP_SVK4 */
+ pon_inf_map_epon_tdma_10g, /* BAL_SWAPP_PORT_MAP_EPON_TDMA */
+ pon_inf_map_epon_1g, /* BAL_SWAPP_PORT_MAP_EPON_1G */
+ pon_inf_map_epon_tdma_10g, /* BAL_SWAPP_PORT_MAP_EPON_10G */
+};
+
+/* network interface mapping table size */
+int g_net_inf_map_table_size[BAL_SWAPP_PORT_MAP__NUM_OF] = {
+ sizeof(net_inf_map_gpon)/sizeof(net_inf_map_gpon[0]), /* BAL_SWAPP_PORT_MAP_GPON */
+ sizeof(net_inf_map_gpon)/sizeof(net_inf_map_gpon[0]), /* BAL_SWAPP_PORT_MAP_GPON_V3 */
+ sizeof(net_inf_map_exp)/sizeof(net_inf_map_exp[0]), /* BAL_SWAPP_PORT_MAP_EXP */
+ sizeof(net_inf_map_exp2)/sizeof(net_inf_map_exp2[0]), /* BAL_SWAPP_PORT_MAP_EXP2 */
+ sizeof(net_inf_map_svk4)/sizeof(net_inf_map_svk4[0]), /* BAL_SWAPP_PORT_MAP_SVK4 */
+ sizeof(net_inf_map_epon_tdma_10g)/sizeof(net_inf_map_epon_tdma_10g[0]), /* BAL_SWAPP_PORT_MAP_EPON_TDMA */
+ sizeof(net_inf_map_epon_1g)/sizeof(net_inf_map_epon_1g[0]), /* BAL_SWAPP_PORT_MAP_EPON_1G */
+ sizeof(net_inf_map_epon_tdma_10g)/sizeof(net_inf_map_epon_tdma_10g[0]), /* BAL_SWAPP_PORT_MAP_EPON_10G */
+};
+/* pon interface mapping table size */
+int g_pon_inf_map_table_size[BAL_SWAPP_PORT_MAP__NUM_OF] = {
+ sizeof(pon_inf_map_gpon)/sizeof(pon_inf_map_gpon[0]), /* BAL_SWAPP_PORT_MAP_GPON */
+ sizeof(pon_inf_map_gpon_v3)/sizeof(pon_inf_map_gpon_v3[0]), /* BAL_SWAPP_PORT_MAP_GPON_V3 */
+ sizeof(pon_inf_map_exp)/sizeof(pon_inf_map_exp[0]), /* BAL_SWAPP_PORT_MAP_EXP */
+ sizeof(pon_inf_map_exp2)/sizeof(pon_inf_map_exp2[0]), /* BAL_SWAPP_PORT_MAP_EXP2 */
+ sizeof(pon_inf_map_svk4)/sizeof(pon_inf_map_svk4[0]), /* BAL_SWAPP_PORT_MAP_SVK4 */
+ sizeof(pon_inf_map_epon_tdma_10g)/sizeof(pon_inf_map_epon_tdma_10g[0]), /* BAL_SWAPP_PORT_MAP_EPON_TDMA */
+ sizeof(pon_inf_map_epon_1g)/sizeof(pon_inf_map_epon_1g[0]), /* BAL_SWAPP_PORT_MAP_EPON_1G */
+ sizeof(pon_inf_map_epon_tdma_10g)/sizeof(pon_inf_map_epon_tdma_10g[0]), /* BAL_SWAPP_PORT_MAP_EPON_10G */
+};
+
+/**
+ * @brief get the number of valid network interface
+ * @return num_nni number of nni interfaces
+ */
+int bal_bcm_net_inf_map_size_get()
+{
+ return g_net_inf_map_table_size[g_intf_maptable];
+};
+
+ /**
+ * @brief get the number of valid pon interface
+ * @return num_nni number of pon interfaces
+ */
+int bal_bcm_pon_inf_map_size_get()
+{
+ return g_pon_inf_map_table_size[g_intf_maptable];
+};
+
+/**
+ * @brief get KT2 PBM of a network interface from current mapping table
+ *
+ * @param net_inf_id logical nni interface number from CLI
+ *
+ * @return pbm PortBitMap that will be used in bcm api calls
+ */
+uint32_t bal_bcm_net_inf_pbm_get(uint32_t net_inf_id)
+{
+ bal_swapp_port *port = (g_net_inf_map_table[g_intf_maptable] + net_inf_id);
+ return port->pbm_id;
+};
+
+/**
+ * @brief get bal nni port number (index of the mapping table) of a physical nni interface
+ *
+ * @param nni_id physical nni interface in the switch
+ *
+ * @return index index to PortBitMap that contains the physical interface number
+ */
+int bal_bcm_net_inf_idx_get(uint32_t nni_id)
+{
+ int indx;
+ bal_swapp_port *port = g_net_inf_map_table[g_intf_maptable];
+ for( indx = 0; port->pbm_id != -1; indx++)
+ {
+ if (port->pbm_id == nni_id)
+ {
+ break;
+ }
+ port++;
+ }
+ if (port->pbm_id == -1)
+ {
+ return -1;
+ }
+ else
+ {
+ return indx;
+ }
+}
+
+/**
+ * @brief get KT2 device id of a network interface from current mapping table
+ *
+ * @param net_inf_id logical nni interface number from CLI
+ *
+ * @return pbm device number that will be used in bcm api calls
+ */
+int bal_bcm_net_inf_dev_get(uint32_t net_inf_id)
+{
+ if(net_inf_id > sizeof(g_net_inf_map_table))
+ {
+ return bal_bcm_dft_dev_get();
+ }
+ else
+ {
+ bal_swapp_port *port = (g_net_inf_map_table[g_intf_maptable] + net_inf_id);
+ return port->device_id;
+ }
+};
+
+/**
+ * @brief get KT2 PBM of a pon interface from current mapping table
+ *
+ * @param pon_inf_id logical pon interface number from CLI
+ *
+ * @return pbm PortBitMap that will be used in bcm api calls
+ */
+uint32_t bal_bcm_pon_inf_pbm_get(uint32_t pon_inf_id)
+{
+ bal_swapp_port *port = (g_pon_inf_map_table[g_intf_maptable] + pon_inf_id);
+ return port->pbm_id;
+};
+
+/**
+ * @brief get bal pon port number (index of the mapping table) of a physical pon interface
+ *
+ * @param pon_id physical pon interface in the switch
+ *
+ * @return index index to PortBitMap that contains the physical interface number
+ */
+int bal_bcm_pon_inf_idx_get(uint32_t pon_id)
+{
+ int indx;
+ bal_swapp_port *port = g_pon_inf_map_table[g_intf_maptable];
+ for( indx = 0; port->pbm_id != -1; indx++)
+ {
+ if (port->pbm_id == pon_id)
+ {
+ break;
+ }
+ port++;
+ }
+ if (port->pbm_id == -1)
+ {
+ return -1;
+ }
+ else
+ {
+ return indx;
+ }
+}
+
+/**
+ * @brief get KT2 device number of a pon interface from current mapping table
+ *
+ * @param pon_inf_id logical pon interface number from CLI
+ *
+ * @return pbm device number that will be used in bcm api calls
+ */
+int bal_bcm_pon_inf_dev_get(uint32_t pon_inf_id)
+{
+ if(pon_inf_id > sizeof(g_pon_inf_map_table))
+ {
+ return bal_bcm_dft_dev_get();
+ }
+ else
+ {
+ bal_swapp_port *port = (g_pon_inf_map_table[g_intf_maptable] + pon_inf_id);
+ return port->device_id;
+ }
+};
+
+/**
+ * @brief setting the local default device id
+ */
+void bal_bcm_dft_dev_set(uint32_t id)
+{
+ g_dft_dev_id = (int)id;
+}
+
+/**
+ * @brief getting the local default device id
+ */
+uint32_t bal_bcm_dft_dev_get()
+{
+ return g_dft_dev_id;
+}
+
+/**
+ * @brief setting the L2 table aging time (seconds)
+ */
+void bal_bcm_l2_age_time_set(uint32_t age_time)
+{
+ g_l2_age_time = age_time;
+}
+
+/**
+ * @brief getting current L2 table aging time value
+ */
+uint32_t bal_bcm_l2_age_time_get()
+{
+ return g_l2_age_time;
+}
+
+/**
+ * @brief getting the device type
+ */
+uint32_t bal_bcm_dev_type_get(uint32_t id)
+{
+ int rc;
+ bcm_info_t dev_info;
+
+ rc = bcm_info_get(id, &dev_info);
+ if (rc)
+ {
+ return 0;
+ }
+
+ return dev_info.device;
+}
+
+/**
+ * @brief getting the iwf mode of an access terminal
+ */
+uint32_t bal_bcm_iwf_mode_get()
+{
+ /* currently only support one access terminal */
+ BCM_LOG(DEBUG, log_id_sw_util, " Get iwf mode for acc_term\n");
+ return g_iwf_mode;
+}
+
+/**
+ * @brief setting the use of RPC (remote) or not (local)
+ */
+void bal_bcm_use_rpc_set(uint32_t use_rpc)
+{
+ g_use_rpc = (int)use_rpc;
+}
+
+/**
+ * @brief getting the use of RPC (remote) or not (local)
+ */
+bcmos_bool bal_bcm_use_rpc_get(void)
+{
+ if (g_use_rpc)
+ {
+ return BCMOS_TRUE;
+ }
+ else
+ {
+ return BCMOS_FALSE;
+ }
+}
+
+static void sw_util_bcm_rx_cb (int unit, int port, int reason, unsigned char *p_payload, int payload_len)
+{
+ int i, len, obj_len;
+ unsigned char *payload;
+ char bytestr[32];
+ char *p_bytestr = bytestr;
+
+ BCM_LOG(INFO, log_id_sw_util, "BAL: Captured packet from datapath (len: %d bytes)\n", payload_len);
+
+ BCM_LOG(DEBUG, log_id_sw_util, " ingress port %d\n", port);
+ BCM_LOG(DEBUG, log_id_sw_util, " rcv reason 0x%x\n", reason);
+
+ len = (payload_len > 64)? 64 : payload_len;
+
+ /* dump out the captured packet */
+ payload = p_payload;
+ BCM_LOG(DEBUG, log_id_sw_util, " payload: (first %d bytes shown)", len);
+ for(i=0; i<len; i++)
+ {
+ if ( i%8 == 0)
+ {
+ sprintf(p_bytestr, "\n");
+ BCM_LOG(DEBUG, log_id_sw_util, "%s", bytestr);
+ p_bytestr = bytestr;
+
+ }
+ sprintf(p_bytestr, " %02x", *payload++);
+ p_bytestr += 3;
+ }
+
+ /* Log the string being crafted when the loop terminated */
+ sprintf(p_bytestr, "\n");
+ BCM_LOG(DEBUG, log_id_sw_util, "%s", bytestr);
+
+ /* Send Auto Indication */
+ if ( p_bal_core_to_api_ind_queue )
+ {
+ bcmbal_packet_cfg *p_ind_msg = NULL;
+ bcmbal_packet_key key;
+ bal_sw_flow *p_flow_elm;
+ int tmp_port;
+
+ /* find the flow info corresponding to this trap REASON */
+ p_flow_elm = bal_sw_util_flow_list_get_by_trap_code(reason);
+ if(p_flow_elm == NULL)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " TrapCallBack: Can't match trap code 0x%x to element in flow list\n", reason);
+ return;
+ }
+
+ /* The packet indication object contains the bcmbal_packet_cfg structure plus the captured packet
+ * content
+ */
+ obj_len = payload_len + sizeof(bcmbal_packet_cfg);
+
+ p_ind_msg = bcmbal_msg_calloc(obj_len);
+
+ if(p_ind_msg == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " TrapCallBack: No memory to send indication\n");
+ return;
+ }
+
+ key.packet_send_dest.type = BCMBAL_DEST_TYPE_HOST;
+
+ BCMBAL_CFG_INIT(p_ind_msg, packet, key);
+
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, flow_id, p_flow_elm->id);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, svc_port, p_flow_elm->svc_port);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, flow_cookie, p_flow_elm->flow_cookie);
+
+ /* first search the PON table */
+ tmp_port = bal_bcm_pon_inf_idx_get(port);
+ if( tmp_port != -1)
+ {
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, flow_type, BCMBAL_FLOW_TYPE_UPSTREAM);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, intf_id, tmp_port);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, intf_type, BCMBAL_INTF_TYPE_PON);
+ }
+ else /* if failed, search for NNI table */
+ {
+ tmp_port = bal_bcm_net_inf_idx_get(port);
+ if( tmp_port != -1)
+ {
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, flow_type, BCMBAL_FLOW_TYPE_DOWNSTREAM);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, intf_id, tmp_port);
+ BCMBAL_CFG_PROP_SET(p_ind_msg, packet, intf_type, BCMBAL_INTF_TYPE_NNI);
+ }
+ }
+ /* if both failed, return */
+ if(tmp_port == -1)
+ {
+ /* something went wrong, free up the message */
+ bcmbal_msg_free(p_ind_msg);
+ BCM_LOG(ERROR, log_id_sw_util, " TrapCallBack: can't match ingress port to bal port tables\n");
+ return;
+ }
+
+ ((bcmbal_obj *)p_ind_msg)->status = BCM_ERR_OK;
+ ((bcmbal_obj *)p_ind_msg)->obj_type = BCMBAL_OBJ_ID_PACKET;
+ ((bcmbal_obj *)p_ind_msg)->group = BCMBAL_MGT_GROUP_AUTO;
+
+ /* now copy the contents of the packet */
+ p_ind_msg->data.pkt.val = (uint8_t *)(p_ind_msg + 1);
+ memcpy(p_ind_msg->data.pkt.val, p_payload, payload_len);
+
+ /* and record the length of the captured packet */
+ p_ind_msg->data.pkt.len = payload_len;
+
+ BCMBAL_PROP_SET_PRESENT(p_ind_msg, packet, _cfg, pkt);
+
+ BCM_LOG(INFO, log_id_sw_util, " TrapCallBack: Flow id = %d, type=%d, Interface id = %d, type=%d, svc_port=%d\n",
+ p_ind_msg->data.flow_id, p_ind_msg->data.flow_type,
+ p_ind_msg->data.intf_id, p_ind_msg->data.intf_type,
+ p_ind_msg->data.svc_port);
+
+ /* Send this indication straight to the API client
+ */
+ bcmbal_msg_hdr_set(p_ind_msg,
+ BCMBAL_MGMT_API_IND_MSG,
+ BAL_MSG_TYPE_AUTO_IND,
+ BAL_SUBSYSTEM_CORE,
+ BCMBAL_OBJ_ID_PACKET,
+ 0, /* operation code */
+ 0); /* exchange id */
+
+ if(BCM_ERR_OK != bcmbal_msg_send(p_bal_core_to_api_ind_queue,
+ p_ind_msg,
+ BCMOS_MSG_SEND_AUTO_FREE))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " TrapCallBack: send auto indication failed\n");
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " TrapCallBack: auto indication sent\n");
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " TrapCallBack: no auto indication queue\n");
+ }
+ return;
+}
+
+/**
+ * @brief Connect access terminal
+ *
+ * This routine is called by acc_term_fsm in the BAL core
+ * Upon receiving the request from the core, this function
+ * assign the device number that each logical nni or pon interface belong
+ * and restrict the egress ports of each interface. This mapping is highly
+ * topology dependent and should be customized according to the actual hardware
+ * layout.
+ * @param p_acc_term Pointer to access terminal instance
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno sw_util_access_terminal_connect(acc_term_inst *p_acc_term)
+{
+ bcmos_errno ret = BCM_ERR_INTERNAL;
+ int rc;
+ bal_swapp_port *port;
+ char *argv[] = { "socdiag", NULL };
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util, " Got a access terminal SET\n");
+
+ /* make sure the abstraction layer is initialized - no harm to initialize multiple time */
+ bcmos_init();
+
+ /* Initialize SDK */
+ rc = socdiag_main(1, argv);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Init BCM SDK failed - %d\n", rc);
+ return BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " %s RPC\n", (1 == g_use_rpc) ? "Using" : "Not using" );
+
+ /* use a soc script to establish rpc connection if switch is remotely located */
+ if (bal_bcm_use_rpc_get())
+ {
+ sleep(3); /* allow remote device to settle */
+
+ BCM_LOG(INFO, log_id_sw_util, " starting RPC connection\n");
+ rc = sh_rcload_file(-1, NULL, "rpc.soc", 0);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " start RPC connection failed\n");
+ return BCM_ERR_INTERNAL;
+ }
+
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Using interface table: %d Device: %d\n", g_intf_maptable, g_dft_dev_id );
+
+ /* setup the device ID - This is very hardware specific */
+ port = g_net_inf_map_table[g_intf_maptable];
+ /* -1 indicate end of table */
+ while(port->pbm_id != -1)
+ {
+ port->device_id = g_dft_dev_id;
+ port++;
+ }
+
+ port = g_pon_inf_map_table[g_intf_maptable];
+ while(port->pbm_id != -1)
+ {
+ port->device_id = g_dft_dev_id;
+ port++;
+ }
+ /* get the switch model from the chip */
+ dev_type = bal_bcm_dev_type_get(g_dft_dev_id);
+ if (dev_type == 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Error retrieving device type on access-terminal connect: 0x%x\n", dev_type);
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* set up the valid egress ports for net/pon facing ports */
+ if (dev_type == BCM_DEVICE_KT2)
+ {
+ ret = sw_util_esw_acc_term_connect(g_net_inf_map_table[g_intf_maptable], g_pon_inf_map_table[g_intf_maptable]);
+ }
+ else if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ /* for rpc case, dpp use a special api to register rx callback.
+ for non-rpc use case, use bcm_rx_register() to register the rx callback
+ */
+ if (bal_bcm_use_rpc_get())
+ {
+ /* if the trap receive udp port in bal_config.ini is not zero, start a receiving thread */
+ if(bal_bcm_trap_rcv_port_get())
+ {
+ sw_util_dpp_rx_cb_register(bal_bcm_dft_dev_get(), sw_util_bcm_rx_cb);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Missing UDP port number for RPC packet In receiver \n");
+ return BCM_ERR_INTERNAL;
+ }
+ }
+ else
+ {
+ bcm_rx_register(bal_bcm_dft_dev_get(), "Bal Cpu Traps", dpp_rx_cb_register, 50, NULL, BCM_RCO_F_ALL_COS);
+ }
+
+ ret = sw_util_dpp_acc_term_connect(g_net_inf_map_table[g_intf_maptable], g_pon_inf_map_table[g_intf_maptable]);
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return access terminal connect request with %d on device 0x%x\n", ret, dev_type );
+
+ /* for now, only support one iwf */
+ g_iwf_mode = (uint32_t)p_acc_term->api_req_acc_term_obj_info.data.iwf_mode;
+
+ return ret;
+}
+
+/**
+ * @brief getting the interface mapping table that applied to the HW connections
+ */
+bal_swapp_port_map_indx bal_bcm_intf_maptable_get()
+{
+ return g_intf_maptable;
+}
+
+/**
+ * @brief SWITCH module: internal packet_send function
+ *
+ * This routine distribute the SEND function to supported switch family
+ *
+ * @param dst_port_id Switch port id the packet is going to be sent out
+ * @param reason REASON_SEND_TO_NNI or REASON_SEND_TO_PON
+ * @param payload pointer to the data
+ * @param payload_len the length of the data
+ * @param tunnel_id pon port tunnel id if REASON_SEND_TO_PON
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno sw_util_pkt_send_intl(int dst_port_id,
+ int reason,
+ unsigned char *payload,
+ int payload_len,
+ int tunnel_id)
+{
+ uint32_t dev_type;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /* get the switch chip type from default device id
+ TBD - in the future, the device id should be obtained from port mapping table */
+ dev_type = bal_bcm_dev_type_get(g_dft_dev_id);
+ if (dev_type == 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Error retrieving device type on pkt send: 0x%x\n", dev_type);
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* set up the valid egress ports for net/pon facing ports */
+ if (dev_type == BCM_DEVICE_KT2)
+ {
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ else if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = sw_util_dpp_pkt_send(dst_port_id, reason, payload, payload_len, s_target_device, tunnel_id);
+ }
+ else
+ {
+ ret = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return access terminal connect request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+
+/* the listening UDP port that the switch will send the trapped messages */
+static uint32_t g_trap_rcv_port = 0;
+
+/**
+ * @brief set the receiving UDP port for trap packets - from config file
+ */
+uint32_t bal_bcm_trap_rcv_port_set(uint32_t udp_port)
+{
+ g_trap_rcv_port = udp_port;
+ return 0;
+}
+
+/**
+ * @brief getting the receiving UDP port for trap packets
+ */
+uint32_t bal_bcm_trap_rcv_port_get()
+{
+ return g_trap_rcv_port;
+}
+
+
+/* the global portChannel DownStream Max rate scheduling mode */
+static uint32_t g_ds_sched_mode = 0; /* default to strict priority */
+
+/**
+ * @brief set the DS max rate scheduling mode - from config file
+ */
+uint32_t bal_bcm_ds_sched_mode_set(uint32_t sched_mode)
+{
+ g_ds_sched_mode = sched_mode;
+ return 0;
+}
+
+/**
+ * @brief getting the DS max rate scheduling mode
+ */
+uint32_t bal_bcm_ds_sched_mode_get()
+{
+ return g_ds_sched_mode;
+}
+
+/**
+ * @brief SWITCH module: access terminal SET handler
+ *
+ * This routine is called by acc_term_fsm in the BAL core upon
+ * SET request for acc_terminal object.
+ *
+ * @param p_acc_term Pointer to access terminal instance
+ * @param opt_type Operation type on access terminal instance
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_access_terminal_set(acc_term_inst *p_acc_term,
+ bal_util_oper_acc_term opt_type)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ if (opt_type != BAL_UTIL_OPER_ACC_TERM_CONNECT)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Access terminal currently supports only CONNECT request\n");
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ ret = sw_util_access_terminal_connect(p_acc_term);
+#else
+ BCM_LOG(INFO, log_id_sw_util, " dummy SUCCESS\n");
+#endif
+
+ return ret;
+}
+
+/**
+ * @brief setting the interface mapping table that applied to the HW connections
+ */
+int bal_bcm_intf_maptable_set(uint32_t intf_maptable)
+{
+ int ret = 0;
+#ifndef TEST_SW_UTIL_LOOPBACK
+ switch(intf_maptable)
+ {
+ case 0:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_GPON;
+ break;
+ case 1:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_GPON_V3;
+ break;
+ case 2:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_EXP;
+ break;
+ case 3:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_EXP2;
+ break;
+ case 4:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_SVK4;
+ break;
+ case 5:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_EPON_TDMA;
+ break;
+ case 6:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_EPON_1G;
+ break;
+ case 7:
+ g_intf_maptable = BAL_SWAPP_PORT_MAP_EPON_10G;
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_sw_util, " Mapping Table Id %d is not supported\n", intf_maptable);
+ ret = BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+#endif
+ return ret;
+}
+
+/**
+ * @brief SWITCH module: packet_send
+ *
+ * This routine is called by work thread in the BAL core upon
+ * user request to send a raw packet out of a switch port.
+ *
+ * @param dst_port_id Switch port id the packet is going to be sent out
+ * @param reason REASON_SEND_TO_NNI or REASON_SEND_TO_PON
+ * @param payload pointer to the data
+ * @param payload_len the length of the data
+ * @param tunnel_id pon tunnel_id
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_pkt_send(int dst_port_id,
+ int reason,
+ unsigned char *payload,
+ int payload_len,
+ int tunnel_id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ if ( reason != REASON_SEND_TO_NNI && reason != REASON_SEND_TO_PON)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " pkt_send currently does not support reason %d\n", reason);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if ( reason == REASON_SEND_TO_NNI && BCMOS_FALSE == bcm_topo_nni_is_valid(dst_port_id))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " pkt_send to invalid nni port %d\n", dst_port_id);
+ return BCM_ERR_PARM;
+ }
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ ret = sw_util_pkt_send_intl(dst_port_id, reason, payload, payload_len, tunnel_id);
+#else
+ BCM_LOG(INFO, log_id_sw_util, " dummy SUCCESS\n");
+#endif
+
+ return ret;
+}
+
+/*
+ * Called from bal_core to set up the packet out server IP:port (i.e. the bcm_user process location)
+ * when Switch is on the same board where the core is run, there is no RPC and this init function should not be called
+ */
+bcmos_errno sw_util_pkt_send_init(const char *pkt_send_server_ip, uint16_t pkt_send_server_listen_port)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+ do
+ {
+ /* If the packet_out interface has already been initialized, just return OK */
+ if(g_pkt_send_is_initialized == BCMOS_FALSE)
+ {
+#ifdef CONFIG_SWITCH_RPC
+ /*
+ * Set up the socket to be used for sending "packet send" messages
+ * to the bcm.user server
+ */
+ if((s_target_device.socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ ret = BCM_ERR_NORES;
+ break;
+ }
+
+ s_target_device.addr.sin_family = AF_INET;
+ inet_pton(s_target_device.addr.sin_family, pkt_send_server_ip, &s_target_device.addr.sin_addr.s_addr);
+ s_target_device.addr.sin_port = htons(pkt_send_server_listen_port);
+#endif /* CONFIG_SWITCH_RPC */
+ g_pkt_send_is_initialized = BCMOS_TRUE;
+ }
+
+ }
+ while(0);
+
+#endif /*TEST_SW_UTIL_LOOPBACK*/
+
+ return ret;
+}
+/*@}*/
diff --git a/bal_release/src/core/util/switch/bal_switch_acc_term.h b/bal_release/src/core/util/switch/bal_switch_acc_term.h
new file mode 100644
index 0000000..e60b91b
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_acc_term.h
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_acc_term.h
+ *
+ * @brief bal switch util access terminal service function header file
+ *
+ * @addtogroup sw_util
+ */
+
+#ifndef _BAL_BCM_ACC_TERM_H_
+#define _BAL_BCM_ACC_TERM_H_
+
+/*@{*/
+#include "bcmos_errno.h"
+
+#define BAL_BCM_MAX_INTF 32
+
+/* structure of each entry in the port mapping table */
+typedef struct bal_swapp_port_t
+{
+ uint32_t pbm_id;
+ int device_id;
+} bal_swapp_port;
+
+/* Index of different tables that map core interface number to physical ports on the device
+ * for example, GPON mapping table will be table[0], EPON mapping table will be table[2]
+ */
+typedef enum
+{
+ BAL_SWAPP_PORT_MAP_GPON,
+ BAL_SWAPP_PORT_MAP_GPON_V3,
+ BAL_SWAPP_PORT_MAP_EXP,
+ BAL_SWAPP_PORT_MAP_EXP2,
+ BAL_SWAPP_PORT_MAP_SVK4,
+ BAL_SWAPP_PORT_MAP_EPON_TDMA,
+ BAL_SWAPP_PORT_MAP_EPON_1G,
+ BAL_SWAPP_PORT_MAP_EPON_10G,
+ BAL_SWAPP_PORT_MAP__NUM_OF,
+} bal_swapp_port_map_indx;
+
+/*
+ * @brief Packet send structures and defines
+ */
+enum
+{
+ REASON_SEND_TO_NNI = 1,
+ REASON_SEND_TO_PON
+};
+
+typedef struct
+{
+ int socket;
+ struct sockaddr_in addr;
+} trap_target;
+
+extern bcmos_errno bal_bcm_acc_term_connect(void);
+extern void bal_bcm_dft_dev_set(uint32_t id);
+extern uint32_t bal_bcm_dft_dev_get(void);
+extern void bal_bcm_l2_age_time_set(uint32_t time);
+extern uint32_t bal_bcm_l2_age_time_get(void);
+extern uint32_t bal_bcm_dev_type_get(uint32_t id);
+extern void bal_bcm_use_rpc_set(uint32_t use_rpc);
+extern int bal_bcm_intf_maptable_set(uint32_t intf_maptable);
+extern uint32_t bal_bcm_net_inf_pbm_get(uint32_t net_inf_id);
+extern uint32_t bal_bcm_pon_inf_pbm_get(uint32_t pon_inf_id);
+extern int bal_bcm_net_inf_dev_get(uint32_t net_inf_id);
+extern int bal_bcm_pon_inf_dev_get(uint32_t pon_inf_id);
+extern uint32_t bal_bcm_iwf_mode_get(void);
+extern bcmos_bool bal_bcm_use_rpc_get(void);
+extern uint32_t bal_bcm_trap_rcv_port_get(void);
+extern uint32_t bal_bcm_trap_rcv_port_set(uint32_t udp_port);
+extern int bal_bcm_pon_inf_idx_get(uint32_t pon_id);
+extern int bal_bcm_net_inf_idx_get(uint32_t nni_id);
+extern bal_swapp_port_map_indx bal_bcm_intf_maptable_get(void);
+extern uint32_t bal_bcm_ds_sched_mode_get(void);
+extern uint32_t bal_bcm_ds_sched_mode_set(uint32_t sched_mode);
+extern bcmos_errno sw_util_pkt_send(int dst_port_id, int reason, unsigned char *payload, int payload_len, int tunnel_id);
+extern bcmos_errno sw_util_pkt_send_init(const char *pkt_send_server_ip, uint16_t pkt_send_server_listen_port);
+extern int bal_bcm_net_inf_map_size_get(void);
+extern int bal_bcm_pon_inf_map_size_get(void);
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/bal_switch_cli.c b/bal_release/src/core/util/switch/bal_switch_cli.c
new file mode 100644
index 0000000..779f125
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_cli.c
@@ -0,0 +1,172 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_cli.c
+ * @brief Sample CLI for switch integration module
+ *
+ */
+
+/*@{*/
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+#include <bcmcli.h>
+
+/* Below local functions are used for real logic only */
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#include "bal_switch_acc_term.h"
+#include <bcm/types.h>
+#include <bcm/port.h>
+#include <appl/diag/shell.h>
+
+static bcmcli_entry *switch_cli_dir;
+
+/* Function declarations */
+
+/*
+ * CLI backend helper functions
+ */
+
+static bcmos_errno bal_switch_device(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bal_bcm_dft_dev_set(parm[0].value.number);
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_switch_l2_age_time(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bal_bcm_l2_age_time_set(parm[0].value.number);
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_switch_rpc_mode(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bal_bcm_use_rpc_set(parm[0].value.number);
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_switch_intf_map(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bal_bcm_intf_maptable_set(parm[0].value.number);
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_switch_trap_udp_port(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ bal_bcm_trap_rcv_port_set(parm[0].value.number);
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bal_switch_shell(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ sh_process(-1, "BCM", TRUE);
+ return BCM_ERR_OK;
+}
+/* allow CLI to send a testing packet out of NNI interface, input is interface_number */
+static bcmos_errno bal_switch_pkt_out(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ int out_port = parm[0].value.number;
+ unsigned char pkt_tagged_data[64] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, /* DA */
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, /* SA */
+ 0x81, 0x00, 0x00, 0x01, /* TPID + VID */
+ 0x08, 0x00, 0x45, 0x10, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x32, 0x06,
+ 0x82, 0xab, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x04, 0x00, 0x04, 0x01, 0x00, 0x56, 0xf1, 0x39, 0x00, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+
+ sw_util_pkt_send(out_port, REASON_SEND_TO_NNI, pkt_tagged_data, 64, 0);
+ return BCM_ERR_OK;
+}
+
+/* allow CLI to send a testing packet out of PON interface, inputs are interface_number and tunnel_id */
+static bcmos_errno bal_switch_pon_out(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms)
+{
+ int out_port = parm[0].value.number;
+ int tunnel_id = parm[1].value.number;
+ unsigned char pkt_tagged_data[64] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, /* DA */
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, /* SA */
+ 0x81, 0x00, 0x00, 0x01, /* TPID + VID */
+ 0x08, 0x00, 0x45, 0x10, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x32, 0x06,
+ 0x82, 0xab, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x04, 0x00, 0x04, 0x01, 0x00, 0x56, 0xf1, 0x39, 0x00, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+
+ sw_util_pkt_send(out_port, REASON_SEND_TO_PON, pkt_tagged_data, 64, tunnel_id);
+ return BCM_ERR_OK;
+}
+
+#endif
+
+/* Create CLI directory */
+bcmos_errno sw_util_cli_init(bcmcli_entry *top_dir)
+{
+#ifndef TEST_SW_UTIL_LOOPBACK
+ if (switch_cli_dir)
+ {
+ return BCM_ERR_ALREADY;
+ }
+ switch_cli_dir = bcmcli_dir_add(top_dir, "switch", "Switch CLI commands", BCMCLI_ACCESS_GUEST, NULL);
+ BCMOS_CHECK_RETURN_ERROR(!switch_cli_dir, BCM_ERR_INTERNAL);
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "device", "Set default device", bal_switch_device,
+ BCMCLI_MAKE_PARM("index", "Device index", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "l2_agetime", "Set L2 table aging time", bal_switch_l2_age_time,
+ BCMCLI_MAKE_PARM("time", "L2 Aging Time", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "rpc_mode", "Set RPC mode", bal_switch_rpc_mode,
+ BCMCLI_MAKE_PARM_ENUM("enable", "Enable RPC mode", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "intf_map_table", "Select interface mapping table", bal_switch_intf_map,
+ BCMCLI_MAKE_PARM("table", "Interface Mapping Table Number", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "trap_udp_port", "Set trap packet receiving udp port", bal_switch_trap_udp_port,
+ BCMCLI_MAKE_PARM("port", "Receiving Port number", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "nni_packet_out", "Send example packet vid=1 to switch nni port", bal_switch_pkt_out,
+ BCMCLI_MAKE_PARM("port", "Sending Port number", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD(switch_cli_dir, "pon_packet_out", "Send example packet vid=1 to switch pon port", bal_switch_pon_out,
+ BCMCLI_MAKE_PARM("port", "Sending Port number", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
+ BCMCLI_MAKE_PARM("tunnel", "Sending Tunnel Id", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE));
+
+ BCMCLI_MAKE_CMD_NOPARM(switch_cli_dir, "shell", "Switch SDK shell", bal_switch_shell);
+#endif
+ return BCM_ERR_OK;
+}
+
+/*@}*/
diff --git a/bal_release/src/core/util/switch/bal_switch_flow.c b/bal_release/src/core/util/switch/bal_switch_flow.c
new file mode 100644
index 0000000..acb85d3
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_flow.c
@@ -0,0 +1,664 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_flow.c
+ * @brief BAL Switch util functions that handle flow requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_flow.h"
+#include "flow_fsm.h"
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/types.h>
+#include <sal/core/libc.h>
+#ifndef sal_memset
+#define sal_memset memset
+#endif
+#include <bcm/port.h>
+#include <bcm/vlan.h>
+#include <bcm/field.h>
+#include <bcm/error.h>
+#include <sal/core/libc.h>
+
+#include "bal_switch_acc_term.h"
+#include "esw/bal_esw_flow.h"
+#include "dpp/bal_dpp_flow.h"
+#include "dpp/bal_dpp_vswitch.h"
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+
+/* A golbal link list to keep track of flows in the switch */
+TAILQ_HEAD(bal_sw_flow_list_head, bal_sw_flow) g_swutil_flow_list;
+
+static void sw_util_flow_dump_classifier(bcmbal_flow_cfg *p_flow)
+{
+ char dst_ip_str[16];
+
+ bcmos_inet_ntoa(&p_flow->data.classifier.dst_ip, dst_ip_str);
+
+ /* Do not use normal BCM_LOG() (but BCM_LOG_CALLER_FMT()), as IP address is a stack variable. */
+ BCM_LOG_CALLER_FMT(DEBUG, log_id_sw_util,
+ " classifier - otpid=0x%x itpid=0x%x ovid=0x%x ivid=0x%x opcp=0x%x, ipcp=0x%x "
+ "ether_type=0x%x dst_mac=%02x:%02x:%02x:%02x:%02x:%02x ip_proto=0x%x dst_ip=%s src_port=%u dst_port=%u attr_mask=0x%x\n",
+ p_flow->data.classifier.o_tpid, p_flow->data.classifier.i_tpid,
+ p_flow->data.classifier.o_vid, p_flow->data.classifier.i_vid,
+ p_flow->data.classifier.o_pbits,
+ p_flow->data.classifier.i_pbits,
+ p_flow->data.classifier.ether_type,
+ p_flow->data.classifier.dst_mac.u8[0], p_flow->data.classifier.dst_mac.u8[1], p_flow->data.classifier.dst_mac.u8[2],
+ p_flow->data.classifier.dst_mac.u8[3], p_flow->data.classifier.dst_mac.u8[4], p_flow->data.classifier.dst_mac.u8[5],
+ p_flow->data.classifier.ip_proto,
+ dst_ip_str,
+ p_flow->data.classifier.src_port,
+ p_flow->data.classifier.dst_port,
+ (unsigned int)p_flow->data.classifier.presence_mask);
+}
+
+static void sw_util_flow_dump_sla(bcmbal_flow_cfg *p_flow)
+{
+ BCM_LOG(DEBUG, log_id_sw_util, " sla - min_rate=%u max_rate=%u attr_mask=0x%x\n",
+ p_flow->data.sla.min_rate,
+ p_flow->data.sla.max_rate,
+ (unsigned int)p_flow->data.sla.presence_mask);
+}
+
+#define OUTER_VLAN_TAG_REQ_BITMASK (BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG | \
+ BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG | \
+ BCMBAL_ACTION_CMD_ID_XLATE_TWO_TAGS | \
+ BCMBAL_ACTION_CMD_ID_REMOVE_TWO_TAGS | \
+ BCMBAL_ACTION_CMD_ID_REMARK_PBITS | \
+ BCMBAL_ACTION_CMD_ID_COPY_PBITS | \
+ BCMBAL_ACTION_CMD_ID_REVERSE_COPY_PBITS | \
+ BCMBAL_ACTION_CMD_ID_DSCP_TO_PBITS)
+
+#define NOT_WORKING_ACTION_BITMASK (BCMBAL_ACTION_CMD_ID_ADD_TWO_TAGS | \
+ BCMBAL_ACTION_CMD_ID_REMOVE_TWO_TAGS | \
+ BCMBAL_ACTION_CMD_ID_XLATE_TWO_TAGS | \
+ BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST | \
+ BCMBAL_ACTION_CMD_ID_DISCARD_DS_UNKNOWN | \
+ BCMBAL_ACTION_CMD_ID_COPY_PBITS | \
+ BCMBAL_ACTION_CMD_ID_REVERSE_COPY_PBITS | \
+ BCMBAL_ACTION_CMD_ID_DSCP_TO_PBITS)
+
+/**
+ * @brief The flow check function validate the flow parameters from the core
+ *
+ * @param p_msg A pointer to the flow object to validate
+ * @return error code
+ */
+bcmos_errno sw_util_flow_info_validate(void *p_msg)
+{
+ bcmbal_flow_cfg *p_flow = (bcmbal_flow_cfg *)p_msg;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ if (p_flow == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " No flow specified during validation\n" );
+ return BCM_ERR_PARM;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a flow request - flow_id=%d sub_port=%d svc_id=%d, attr_mask=0x%x\n",
+ p_flow->key.flow_id, p_flow->data.access_int_id,
+ p_flow->data.svc_port_id, (unsigned int)p_flow->hdr.hdr.presence_mask);
+
+ sw_util_flow_dump_classifier(p_flow);
+ if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)
+ sw_util_flow_dump_sla(p_flow);
+ }
+
+ /* validate the NNI range */
+ if((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id)) &&
+ (BCMOS_FALSE == bcm_topo_nni_is_valid(p_flow->data.network_int_id )) )
+ {
+ uint32_t max_nni_ports = 0;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ bcm_topo_dev_get_max_nni(bal_bcm_net_inf_dev_get(p_flow->data.network_int_id), &max_nni_ports);
+#else
+ bcm_topo_dev_get_max_nni(0, &max_nni_ports);
+#endif
+ BCM_LOG(ERROR, log_id_sw_util,
+ " Request network interface %d is out of max range %d\n",p_flow->data.network_int_id, max_nni_ports );
+ return BCM_ERR_PARM;
+ }
+
+ /* return BCM_ERR_NOT_SUPPORTED for actions that has not yet implemented */
+ if((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) &&
+ (p_flow->data.action.cmds_bitmask & NOT_WORKING_ACTION_BITMASK))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " Request Action Command 0x%x not supported yet\n",p_flow->data.action.cmds_bitmask );
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, classifier))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " a classifier must be specified in a flow\n" );
+ ret = BCM_ERR_PARM;
+ }
+ else
+ {
+ /* ING SDK allows priority range from 0x7fffffff to 0 */
+ /* Need to check the configuration range if unit32_t is used for the attribute */
+
+ /* An outer vid is required in the classifier for all actions that operate on the outer vlan tag */
+ if(BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid) &&
+ ((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) &&
+ (p_flow->data.action.cmds_bitmask & OUTER_VLAN_TAG_REQ_BITMASK)))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " o_vid must be specified when actions requiring an outer vlan tag is specified\n" );
+ ret = BCM_ERR_PARM;
+ }
+
+ /*An outer vid must be specified when an inner vid is specified */
+ if((BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid)) &&
+ (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid)))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " o_vid must be specified when i_vid is specified\n" );
+ ret = BCM_ERR_PARM;
+ }
+
+ /* Check that user has specified pbits when the action is pbit remarking */
+ if((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) &&
+ (p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMARK_PBITS) )
+ {
+ if((BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid)) ||
+ (BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.action, action, o_pbits)) )
+ {
+
+ BCM_LOG(ERROR, log_id_sw_util,
+ " o_vid in classifier and o_pibts in action must be specified when outer pbit remarking is specified\n" );
+ ret = BCM_ERR_PARM;
+ }
+ }
+
+ /* Check that the user has specified a valid packet tag type given the o_vid and i_vid choices (if any)*/
+ if(((BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid)) ||
+ (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid))))
+ {
+ if((BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type)) ||
+ ((BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type)) &&
+ (BCMBAL_PKT_TAG_TYPE_UNTAGGED == p_flow->data.classifier.pkt_tag_type)))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " pkt_tag_type must be either SINGLE or DOUBLE tagged when o_vid or i_vid are specified\n" );
+ ret = BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ /* If the pkt_tag_type is not specified OR the pkt_tag_type is not UNTAGGED (and it's not destined
+ * to the host CPU), then it's an error
+ */
+ if(!(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action) &&
+ (p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)))
+ {
+ if(BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type) ||
+ (!(BCMBAL_PKT_TAG_TYPE_UNTAGGED == p_flow->data.classifier.pkt_tag_type)))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " pkt_tag_type must be UNTAGGED when neither o_vid nor i_vid are specified\n" );
+ ret = BCM_ERR_PARM;
+ }
+ }
+ }
+
+ /* Now test the multicast flow cases */
+ if (BCMOS_TRUE == (BCMBAL_FLOW_TYPE_MULTICAST == p_flow->key.flow_type))
+ {
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action) &&
+ (p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " A multicast flow must not terminate in the host\n");
+ ret = BCM_ERR_PARM;
+ }
+
+ /* A Multicast flow must have a group_id that is valid (i.e. an active group) */
+ if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " A multicast flow must have a specified group_id\n");
+ ret = BCM_ERR_PARM;
+ }
+ else
+ {
+ /* Now check that the referenced group is valid */
+ bcmbal_group_key group_key = { .group_id = p_flow->data.group_id };
+ bcmbal_group_owner group_owner;
+
+ /* make sure the group owner is multicast */
+ if(BCM_ERR_OK == group_owner_get(group_key, &group_owner))
+ {
+ if ( BCMBAL_GROUP_OWNER_MULTICAST != group_owner)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " A multicast flow must have group owner of type Multicast, group_id:%d\n",
+ group_key.group_id);
+ ret = BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " A multicast flow must have an valid group_id (Active group_id:%d not found)\n",
+ group_key.group_id);
+ ret = BCM_ERR_PARM;
+ }
+ }
+ }
+ /* check N:1 service Group Owner to be UNICAST */
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id) &&
+ (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow->key.flow_type ||
+ BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type )
+ )
+ {
+ /* Now check that the referenced group is valid */
+ bcmbal_group_key group_key = { .group_id = p_flow->data.group_id };
+ bcmbal_group_owner group_owner;
+
+ /* make sure the group owner is unicast */
+ if(BCM_ERR_OK == group_owner_get(group_key, &group_owner))
+ {
+ if ( BCMBAL_GROUP_OWNER_UNICAST != group_owner)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " A N:1 flow must have group owner of type unicast, group_id:%d\n",
+ group_key.group_id);
+ ret = BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " A N:1 flow must have an valid group_id (Active group_id:%d not found)\n",
+ group_key.group_id);
+ ret = BCM_ERR_PARM;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* Below local functions are used for real logic only */
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+/**
+ * @brief The flow add function program the switch to forward packets that have
+ * specified attributes to the designated ports.
+ * The packets is modified before egress
+ * On the downstream, an access id (outer vlan tag) is added to the packets
+ * On the upstream, outer vlan tag (access id) is removed from the packets
+ *
+ * @param p_flow_inst A pointer to the flow instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_flow_add(flow_inst *p_flow_inst)
+{
+ bcmbal_flow_cfg *p_flow = &p_flow_inst->api_req_flow_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+ bcmbal_iwf_mode iwf_mode;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a flow request - flow_id=%d sub_port=%d svc_id=%d\n",
+ p_flow->key.flow_id, p_flow->data.access_int_id, p_flow->data.svc_port_id);
+
+ unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id);
+ dev_type = bal_bcm_dev_type_get(unit);
+ iwf_mode = bal_bcm_iwf_mode_get();
+
+ /* call the flow add function based on device type */
+ if (dev_type == BCM_DEVICE_KT2)
+ {
+ ret = bal_sw_util_esw_flow_add(iwf_mode, p_flow);
+ }
+ else if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_flow_add(iwf_mode, p_flow);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on flow add: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return flow add request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+
+/**
+ * @brief The flow remove function program switch to release resource that have
+ * been allocated during the flow add operation.
+ *
+ * @param p_flow_inst A pointer to the flow instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_flow_remove(flow_inst *p_flow_inst)
+{
+ bcmbal_flow_cfg *p_flow = &p_flow_inst->api_req_flow_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+ bcmbal_iwf_mode iwf_mode;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a flow remove request - flow_id=%d sub_port=%d svc_id=%d\n",
+ p_flow->key.flow_id, p_flow->data.access_int_id, p_flow->data.svc_port_id);
+
+ unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id);
+ dev_type = bal_bcm_dev_type_get(unit);
+ iwf_mode = bal_bcm_iwf_mode_get();
+
+ /* call the flow add function based on device type */
+ if (dev_type == BCM_DEVICE_KT2)
+ {
+ ret = bal_sw_util_esw_flow_remove(iwf_mode, p_flow);
+ }
+ else if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_flow_remove(iwf_mode, p_flow);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on flow remove: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return flow remove request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+
+/**
+ * @brief The flow list init function prepare a link list to keep track of flows in the switch util
+ *
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_flow_list_init(void)
+{
+ TAILQ_INIT(&g_swutil_flow_list);
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The flow list finish function release all resources allocated in the flow list
+ *
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_flow_list_finish(void)
+{
+ bal_sw_flow *current_entry, *p_temp_entry;
+
+ /* Free all the entries in the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &g_swutil_flow_list,
+ flow_next,
+ p_temp_entry)
+ {
+ /* Remove it from the list */
+ TAILQ_REMOVE(&g_swutil_flow_list, current_entry, flow_next);
+
+ bcmos_free(current_entry);
+ }
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The flow list search function by flow id
+ *
+ * @param id Flow id that need to match the entry in the list
+ * @return pointer to an element in the list
+ */
+bal_sw_flow *bal_sw_util_flow_list_get_by_id(uint32_t id)
+{
+ bal_sw_flow *p_entry, *p_temp;
+ TAILQ_FOREACH_SAFE(p_entry, &g_swutil_flow_list, flow_next, p_temp)
+ {
+ if( p_entry->id == id)
+ {
+ break;
+ }
+ }
+ /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
+ return p_entry;
+}
+
+/**
+ * @brief The flow list search function by flow id
+ *
+ * @param trap_code Trap id that need to match the entry in the list
+ * @return pointer to an element in the list
+ */
+bal_sw_flow *bal_sw_util_flow_list_get_by_trap_code(uint32_t trap_code)
+{
+ bal_sw_flow *p_entry, *p_temp;
+
+ if (trap_code == 0)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "Invalid trap code %d in Flow list search by trap code\n", trap_code);
+ return NULL;
+ }
+ TAILQ_FOREACH_SAFE(p_entry, &g_swutil_flow_list, flow_next, p_temp)
+ {
+ if( p_entry->trap_code == trap_code)
+ {
+ break;
+ }
+ }
+ /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
+ return p_entry;
+}
+
+/*
+ * @brief The flow list insert function
+ *
+ * @param entry the element to be added in the link list
+ * @return error code
+*/
+bcmos_errno bal_sw_util_flow_list_insert(bal_sw_flow entry)
+{
+ bal_sw_flow *p_new_entry;
+
+ p_new_entry = bcmos_calloc(sizeof(bal_sw_flow));
+ if(NULL == p_new_entry)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Flow list insert out of memory\n");
+ return BCM_ERR_NOMEM;
+ }
+ *p_new_entry = entry;
+ TAILQ_INSERT_TAIL(&g_swutil_flow_list, p_new_entry, flow_next);
+ return BCM_ERR_OK;
+}
+
+/*
+ * @brief The flow list remove function
+ *
+ * @param p_entry Pointer to the element in the link list result from one of the search functions
+ * @return error code
+*/
+bcmos_errno bal_sw_util_flow_list_remove(bal_sw_flow *p_entry)
+{
+ TAILQ_REMOVE(&g_swutil_flow_list, p_entry, flow_next);
+ bcmos_free(p_entry);
+ return BCM_ERR_OK;
+}
+
+
+/*
+ * @brief down Stream Flow classifier check to see if an ACL rule is needed for classification
+ *
+ * In ING SDK, vswitch LIF is mostly used to classify VLAN and ingress port only.
+ * Any packet classification more than that requires an ACL rule to filter the
+ * traffics. This routine check if an ACL is needed.
+ * If only VLAN ids are classify, return FALSE, otherwise return TRUE
+ *
+ * @param p_flow Pointer to the flow object that contains the classifier
+ * @return TRUE or FALSE
+*/
+bcmos_bool bal_sw_util_flow_ds_acl_cls_chk(bcmbal_flow_cfg *p_flow)
+{
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ether_type) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ip_proto) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_pbits) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip)
+ )
+ return BCMOS_TRUE;
+ else
+ return BCMOS_FALSE;
+}
+
+/*
+ * @brief Up Stream Flow classifier check to see if an ACL rule is needed for classification
+ *
+ * In ING SDK, vswitch LIF is mostly used to classify VLAN and ingress port only.
+ * Any packet classification more than that requires an ACL rule to filter the
+ * traffics. This routine check if an ACL is needed.
+ * If only VLAN ids are classify, return FALSE, otherwise return TRUE
+ *
+ * @param p_flow Pointer to the flow object that contains the classifier
+ * @return TRUE or FALSE
+*/
+bcmos_bool bal_sw_util_flow_us_acl_cls_chk(bcmbal_flow_cfg *p_flow)
+{
+ /* Up Stream Outer Pbits classification is done using PON LIF, no need to use ACL */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ether_type) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ip_proto) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_pbits) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip) ||
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip)
+ )
+ return BCMOS_TRUE;
+ else
+ return BCMOS_FALSE;
+}
+
+static uint32_t g_flow_inited = 0;
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+/**
+ * @brief SWITCH module: flow SET handler
+ *
+ * This routine is called by flow_fsm in the BAL core upon
+ * SET request for flow object.
+ *
+ * @param p_flow Pointer to flow instance
+ * @param opt_type Operation type on flow instance
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_flow_set(flow_inst *p_flow, bal_util_oper_flow opt_type)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ bal_sw_util_vsi_list_init();
+ if (opt_type == BAL_UTIL_OPER_FLOW_ADD)
+ {
+ if (g_flow_inited == 0)
+ {
+ /* initialized the internal flow link list */
+ bal_sw_util_flow_list_init();
+ /* call flow_init in switch device */
+ bal_sw_util_dpp_flow_init();
+ g_flow_inited = 1;
+ }
+ ret = bal_sw_util_flow_add(p_flow);
+ }
+ else if( BAL_UTIL_OPER_FLOW_REMOVE == opt_type )
+ {
+ ret = bal_sw_util_flow_remove(p_flow);
+ }
+ else if( BAL_UTIL_OPER_FLOW_CLEAR == opt_type )
+ {
+ ret = bal_sw_util_flow_remove(p_flow);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Only ADD/REMOVE/CLEAR request is supported for FLOW object\n");
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+#else
+ BCM_LOG(INFO, log_id_sw_util, "dummy flow %s SUCCESS\n",
+ ( BAL_UTIL_OPER_FLOW_ADD == opt_type ) ? "flow add" : "flow remove");
+#endif
+
+ return ret;
+}
+
+/**
+ * @brief SWITCH module: flow clean up function
+ *
+ * This routine is called by bal_switch_util() when the BAL core issue finish request
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_flow_finish()
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ if (g_flow_inited )
+ {
+ /* release the internal flow link list */
+ bal_sw_util_flow_list_finish();
+
+ g_flow_inited = 0;
+ }
+#endif
+ return ret;
+}
+/*@}*/
diff --git a/bal_release/src/core/util/switch/bal_switch_flow.h b/bal_release/src/core/util/switch/bal_switch_flow.h
new file mode 100644
index 0000000..e6d84eb
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_flow.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_flow.h
+ *
+ * @brief Switch flow interfaces header file
+ *
+ * This file expose the APIs to the core to configure the switches
+ * with regarding to the operation of a flow.
+ *
+ * @defgroup sw_util Switch Util
+ * @ingroup core
+ */
+
+#ifndef _BAL_SWITCH_FLOW_H_
+#define _BAL_SWITCH_FLOW_H_
+
+#include <bal_utils_msg.h>
+#include "bcmos_errno.h"
+#include "flow_fsm.h"
+
+/*@{*/
+
+/* Data structure to keep a link list of flow that has been programmed in the switch */
+/* reserve 16 pairs of uni-direction ports */
+#define MAX_PON_PORT 32
+#define MAX_NET_PORT 32
+#define MAX_FIELD_EID 64
+
+#define BAL_SW_FLOW_TYPE_NONE 0
+#define BAL_SW_FLOW_TYPE_DOWNSTREAM (1 << BCMBAL_FLOW_TYPE_DOWNSTREAM)
+#define BAL_SW_FLOW_TYPE_UPSTREAM (1 << BCMBAL_FLOW_TYPE_UPSTREAM)
+#define BAL_SW_FLOW_TYPE_MULTICAST (1 << BCMBAL_FLOW_TYPE_MULTICAST)
+
+typedef struct bal_sw_flow bal_sw_flow;
+struct bal_sw_flow
+{
+ uint32_t id; /* flow id */
+ uint32_t type; /* downstream or upstream */
+ uint32_t device; /* device id, aka unit of the device */
+ uint32_t trap_code; /* id for trap reason */
+ uint32_t trap_port; /* trap gport */
+ uint32_t num_eid;
+ uint32_t field_entry_id[MAX_FIELD_EID]; /* field entry for ACL rules */
+ void *p_vsi_svc; /* vswitch entry in the vsi list */
+ uint32_t vsi_svc_indx; /* index to the service within the vswitch this flow is using */
+ uint32_t svc_port; /* LLId or GEMID */
+ uint32_t num_pon;
+ uint32_t pon_port[MAX_PON_PORT]; /* pon gport attached to vswitch */
+ uint32_t num_net;
+ uint32_t net_port[MAX_NET_PORT]; /* nni gport attached to vswitch */
+ bcmbal_cookie flow_cookie;
+ void *p_service_cfg;
+ uint32_t group_id;
+ uint32_t valid;
+ TAILQ_ENTRY(bal_sw_flow) flow_next;
+};
+
+extern bcmos_errno bal_sw_util_flow_list_insert(bal_sw_flow entry);
+extern bcmos_errno bal_sw_util_flow_list_remove(bal_sw_flow *p_entry);
+extern bal_sw_flow *bal_sw_util_flow_list_get_by_id(uint32_t id);
+extern bal_sw_flow *bal_sw_util_flow_list_get_by_trap_code(uint32_t trap_code);
+extern bcmos_bool bal_sw_util_flow_ds_acl_cls_chk(bcmbal_flow_cfg *p_flow);
+extern bcmos_bool bal_sw_util_flow_us_acl_cls_chk(bcmbal_flow_cfg *p_flow);
+
+/*@}*/
+
+#endif /* _BAL_SWITCH_FLOW_H_ */
diff --git a/bal_release/src/core/util/switch/bal_switch_group.c b/bal_release/src/core/util/switch/bal_switch_group.c
new file mode 100644
index 0000000..4fc020e
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_group.c
@@ -0,0 +1,392 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_group.c
+ * @brief BAL Switch util functions that handle group requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bcmos_errno.h"
+#include "bal_switch_util.h" /* include bal_util.msg.h for bal_util_oper_group */
+#include "group_fsm.h" /* for struct group_inst */
+
+
+#include "bal_dpp_group.h"
+#include "bal_switch_acc_term.h"
+
+#ifdef TEST_SW_UTIL_LOOPBACK
+/* nothing to check in loop back mode */
+bcmos_errno sw_util_group_info_validate(void *p_msg)
+{
+ return BCM_ERR_OK;
+}
+
+#else
+/**
+ * @brief The group check function validate the group parameters from the core
+ *
+ * @param p_msg A pointer to the group object to validate
+ * @return error code
+ */
+bcmos_errno sw_util_group_info_validate(void *p_msg)
+{
+ bcmbal_group_cfg *p_grp = (bcmbal_group_cfg *)p_msg;
+ int i, num_of_pon;
+
+ if (p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " No group specified during validation\n" );
+ return BCM_ERR_PARM;
+ }
+
+ /* if members field is set, make sure the PON interfaces are valid */
+ if (BCMBAL_CFG_PROP_IS_SET(p_grp, group, members))
+ {
+ num_of_pon = bal_bcm_pon_inf_map_size_get();
+ for(i=0; i<p_grp->data.members.len; i++)
+ {
+ bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
+
+ if (p_member->intf_id >= num_of_pon)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " invalid group member with pon id = %d\n", p_member->intf_id );
+ return BCM_ERR_PARM;
+ }
+ }
+ }
+
+ /* member action is not supported yet */
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The group remove function program switch to release resource that have
+ * been allocated during the group add operation.
+ *
+ * @param p_group_inst A pointer to the group instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_group_remove(group_inst *p_group_inst)
+{
+ bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a group remove request - group_id=%d \n", p_group->key.group_id);
+
+ /* remove must have at least one member */
+ if(p_group->data.members.len == 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group remove request must have at least one member\n");
+ return BCM_ERR_PARM;
+ }
+
+ unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the group add function based on device type */
+ if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_group_rem(unit, p_group);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group remove: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return group remove request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+/**
+ * @brief The group add function program switch to add a member interface to the group
+ *
+ * @param p_group_inst A pointer to the group instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_group_add(group_inst *p_group_inst)
+{
+ bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a group add request - group_id=%d \n", p_group->key.group_id);
+
+ /* add must have at least one member */
+ if(p_group->data.members.len == 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group add request must have at least one member\n");
+ return BCM_ERR_PARM;
+ }
+
+ unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the group add function based on device type */
+ if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_group_add(unit, p_group);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group add: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return group add request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+
+/**
+ * @brief The group set function program switch to replace member interfaces of a group
+ *
+ * @param p_group_inst A pointer to the group instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_group_set(group_inst *p_group_inst)
+{
+ bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a group set request - group_id=%d \n", p_group->key.group_id);
+
+ if(p_group->data.members.len == 0)
+ {
+ unit = bal_bcm_dft_dev_get();
+ }
+ else
+ {
+ unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
+ }
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the group set function based on device type */
+ if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_group_set(unit, p_group);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group set: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return group set request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+/**
+ * @brief The group create function program switch to create an empty group
+ *
+ * @param p_group_inst A pointer to the group instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_group_create(group_inst *p_group_inst)
+{
+ bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a group create request - group_id=%d \n", p_group->key.group_id);
+
+
+ /* For now, only one switch device for a system. If multiple devices support is required,
+ need to loop through all devices to create the group */
+ unit = bal_bcm_dft_dev_get();
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the group create function based on device type */
+ if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ if( NULL == bal_sw_util_dpp_group_create(unit, p_group))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " switch group create failed\n");
+ ret = BCM_ERR_INTERNAL;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group create: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return group create request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+/**
+ * @brief The group destroy function program switch to release all resource used in a group
+ *
+ * @param p_group_inst A pointer to the group instance being referenced
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_group_destroy(group_inst *p_group_inst)
+{
+ bcmbal_group_cfg *p_group = &p_group_inst->current_group_info;
+ bcmos_errno ret = BCM_ERR_OK;
+ int unit;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a group destroy request - group_id=%d \n", p_group->key.group_id);
+
+
+ /* For now, only one switch device for a system. If multiple devices support is required,
+ need to loop through all devices to create the group */
+ unit = bal_bcm_dft_dev_get();
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the group destroy function based on device type */
+ if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_group_destroy(unit, p_group);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group destroy: 0x%x\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " Return group destroy request with %d on device 0x%x\n", ret, dev_type );
+
+ return ret;
+}
+
+static uint32_t g_group_inited = 0;
+
+#endif
+/**
+ * @brief SWITCH module: group SET handler
+ *
+ * This routine is called by group_fsm in the BAL core upon
+ * SET request for group object.
+ *
+ * @param p_group_inst Pointer to group instance
+ * @param opt_type Operation type on group instance
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_group_set(group_inst *p_group_inst, bal_util_oper_group opt_type)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ bal_sw_util_vsi_list_init();
+ if (g_group_inited == 0)
+ {
+ /* initialized the internal group link list */
+ bal_sw_util_dpp_group_list_init();
+
+ g_group_inited = 1;
+ }
+
+ if(p_group_inst == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group set request with NULL pointer to the group instance\n");
+ return BCM_ERR_PARM;
+ }
+
+ if (opt_type == BAL_UTIL_OPER_GROUP_CREATE)
+ {
+ ret = bal_sw_util_group_create(p_group_inst);
+ }
+ else if (opt_type == BAL_UTIL_OPER_GROUP_ADD)
+ {
+ ret = bal_sw_util_group_add(p_group_inst);
+ }
+ else if( BAL_UTIL_OPER_GROUP_REMOVE == opt_type )
+ {
+ ret = bal_sw_util_group_remove(p_group_inst);
+ }
+ else if( BAL_UTIL_OPER_GROUP_SET == opt_type )
+ {
+ ret = bal_sw_util_group_set(p_group_inst);
+ }
+ else if( BAL_UTIL_OPER_GROUP_DESTROY == opt_type )
+ {
+ ret = bal_sw_util_group_destroy(p_group_inst);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Only CREATE/ADD/REMOVE/SET/DESTROY request is supported for GROUP object\n");
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+#else
+ BCM_LOG(INFO, log_id_sw_util, "dummy group %s SUCCESS\n",
+ BCMBAL_UTIL_GROUP_OPER_STR_GET(opt_type));
+#endif
+
+ return ret;
+}
+
+/**
+ * @brief SWITCH module: group clean up function
+ *
+ * This routine is called from the bal_switch_util() when Core calls the finish function.
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_group_finish()
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ if (g_group_inited)
+ {
+ /* release the internal group link list */
+ bal_sw_util_dpp_group_list_finish();
+
+ g_group_inited = 0;
+ }
+#endif
+ return ret;
+}
+/*@}*/
+
+
diff --git a/bal_release/src/core/util/switch/bal_switch_interface.c b/bal_release/src/core/util/switch/bal_switch_interface.c
new file mode 100644
index 0000000..cbd9f1b
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_interface.c
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+#include "bal_switch_interface.h"
+#include "dpp/bal_dpp_interface.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/types.h>
+#include <bcm/port.h>
+
+/**
+ * @file bal_dpp_interface.c
+ * @brief BAL Switch util functions that handle interface requests on DUNE PACKET PROCESSOR
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+
+
+/**
+ * @brief Set up pon interface with DPP
+ *
+ * This routine is called by sw_util_interface_set in the BAL core
+ * to execute DPP specific API for pon interface request
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param opt_type UP/DOWN/RESTART the interface
+ * @return bcmos_errno
+ */
+bcmos_errno bal_sw_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if opt_type )
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
+ int unit, intf_id;
+ uint32_t dev_type;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a interface request - interface_id=%d \n", intf_key.intf_id);
+
+ unit = bal_bcm_pon_inf_dev_get(intf_key.intf_id);
+ intf_id = bal_bcm_pon_inf_pbm_get(intf_key.intf_id);
+ dev_type = bal_bcm_dev_type_get(unit);
+
+ /* call the interface set function based on device type */
+ if (dev_type == BCM_DEVICE_KT2)
+ {
+ ret = BCM_ERR_OK;
+ }
+ else if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
+ {
+ ret = bal_sw_util_dpp_interface_set(p_interface_inst, opt_type);
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " Unknown device type (0x%x)found on interface set\n", dev_type );
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ BCM_LOG(DEBUG, log_id_sw_util, " Return interface set request with %d on %s 0x%x\n", ret,
+ (intf_key.intf_type == BCMBAL_INTF_TYPE_PON ? "pon" : "nni"), intf_id);
+
+ return ret;
+}
+
+/*@}*/
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+
+/**
+ * @brief SWITCH module: interface SET handler
+ *
+ * This routine is called by interface_fsm in the BAL core upon
+ * SET request for interface object.
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param opt_type UP/DOWN/RESTART the interface
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if opt_type)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+ ret = bal_sw_util_interface_set(p_interface_inst, opt_type);
+#else
+ BCM_LOG(INFO, log_id_sw_util, "dummy SUCCESS\n");
+#endif
+
+ return ret;
+}
diff --git a/bal_release/src/core/util/switch/bal_switch_interface.h b/bal_release/src/core/util/switch/bal_switch_interface.h
new file mode 100644
index 0000000..75d54b5
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_interface.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_interface.h
+ *
+ * @brief bal switch interface service function header file
+ *
+ * @addtogroup sw_util
+ */
+
+#ifndef _BAL_BCM_INTERFACE_H_
+#define _BAL_BCM_INTERFACE_H_
+
+/*@{*/
+#include "bcmos_errno.h"
+
+
+extern bcmos_errno bal_sw_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if opt_type);
+
+
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/bal_switch_tm_queue.c b/bal_release/src/core/util/switch/bal_switch_tm_queue.c
new file mode 100755
index 0000000..5c4aa09
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_tm_queue.c
@@ -0,0 +1,89 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_tm_queue.c
+ * @brief BAL Switch util functions that handle tm requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+#include "tm_sched_fsm.h"
+
+
+/* sw_util_tm_queue_validate() is called by the Core to validate the attributes of the tm_queue object
+* p_msg a pointer to the object bcmbal_tm_queue_cfg
+*/
+bcmos_errno sw_util_tm_queue_validate(void *p_msg)
+{
+ return BCM_ERR_OK;
+}
+
+/* sw_util_tm_queue_set() is called by the Core to create an instance of TM Queue in the switch
+* p_tm_queue_inst a pointer to the data structure tm_queue_inst that used in the Core to manage
+* the received tm_queue configuration request from the BAL client
+*
+* Required attributes
+* Key - key to unique identify the TM queue and the parent scheduler
+* Max size - queue size
+* Priority - SP priority, if parent scheduler is of type SP
+* Weight - WFQ weight, if parent scheduler is of type WFQ
+*
+* Optional
+* Rate - for rate limit, if not specified default to FULL rate
+*/
+bcmos_errno sw_util_tm_queue_set(tm_queue_inst *p_tm_queue_inst)
+{
+ return BCM_ERR_OK;
+}
+
+/* sw_util_tm_queue_clear() is called by the Core to remove an instance of TM queue in the switch
+* p_tm_queue_inst a pointer to the data structure tm_queue_inst that used in the Core to manage
+* the received tm_queue configuration request from the BAL client
+*
+* Required attributes
+* Key - key to unique identify the TM queue
+*
+* Note: CLEAR request should be rejected if any flow is still referencing it
+*/
+bcmos_errno sw_util_tm_queue_clear(tm_queue_inst *p_tm_queue_inst)
+{
+ return BCM_ERR_OK;
+}
+
+/*@}*/
+
+
diff --git a/bal_release/src/core/util/switch/bal_switch_tm_sched.c b/bal_release/src/core/util/switch/bal_switch_tm_sched.c
new file mode 100644
index 0000000..3412f2e
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_tm_sched.c
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_tm_sched.c
+ * @brief BAL Switch util functions that handle tm requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+
+#include "tm_sched_fsm.h"
+
+
+
+/* sw_util_tm_sched_validate() is called by the Core to validate the attributes of the tm_sched object
+ * p_msg a pointer to the object bcmbal_tm_sched_cfg
+ */
+bcmos_errno sw_util_tm_sched_validate(void *p_msg)
+{
+ return BCM_ERR_OK;
+}
+
+/* sw_util_tm_sched_set() is called by the Core to create an instance of TM scheduler in the switch
+ * p_tm_sched_inst a pointer to the data structure tm_sched_inst that used in the Core to manage
+ * the received tm_sched configuration request from the BAL client
+ *
+ * Required attributes
+ * Key - key to unique identify the TM sched
+ * Owner types - Interface, Subscriber_Terminal
+** Owner id - id of interface or subscriber terminal
+ * Schedule types - SP, WFQ, SP_WFQ
+** Num_of_priority - 1 - 16
+* TM objects in the schedule_level this TM sched can support */
+bcmos_errno sw_util_tm_sched_set(tm_sched_inst *p_tm_sched_inst)
+{
+ return BCM_ERR_OK;
+}
+
+/* sw_util_tm_sched_clear() is called by the Core to remove an instance of TM scheduler in the switch
+* p_tm_sched_inst a pointer to the data structure tm_sched_inst that used in the Core to manage
+* the received tm_sched configuration request from the BAL client
+*
+* Required attributes
+* Key - key to unique identify the TM sched
+*/
+bcmos_errno sw_util_tm_sched_clear(tm_sched_inst *p_tm_sched_inst)
+{
+ return BCM_ERR_OK;
+}
+/*@}*/
+
+
+
diff --git a/bal_release/src/core/util/switch/bal_switch_util.c b/bal_release/src/core/util/switch/bal_switch_util.c
new file mode 100644
index 0000000..696295f
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_util.c
@@ -0,0 +1,89 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_util.c
+ *
+ * @brief Switch App interfaces definition used by Bal Core
+ *
+ * This file provides CmdSet message handler functions with relevant
+ * bal object operations of access terminal and flow.
+ *
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+
+#include <bcm_dev_log.h>
+#include <bal_common.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+
+/*
+ * Logging device id
+ */
+dev_log_id log_id_sw_util;
+
+/**
+* @brief sw_util_init routine to initialize the switch util before any use
+* @return bcmos_errno
+*/
+bcmos_errno sw_util_init(void)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ log_id_sw_util = bcm_dev_log_id_register("SW_UTIL", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_sw_util== DEV_LOG_INVALID_ID);
+
+ return rc;
+}
+
+/**
+* @brief sw_util_finish routine to release any resource used by the switch util before exit
+* @return bcmos_errno
+*/
+bcmos_errno sw_util_finish(void)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ /* release any internal allocated DB - best effort as we are exiting anyway */
+ /* flow */
+ sw_util_flow_finish();
+
+ /* group */
+ sw_util_group_finish();
+
+ return rc;
+}
+
+/*@}*/
+
diff --git a/bal_release/src/core/util/switch/bal_switch_util.h b/bal_release/src/core/util/switch/bal_switch_util.h
new file mode 100644
index 0000000..a33a2ac
--- /dev/null
+++ b/bal_release/src/core/util/switch/bal_switch_util.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_switch_util.h
+ *
+ * @brief Switch App interfaces header file
+ *
+ * This file expose the APIs to the core to configure the switchs
+ * with regarding to the operation of access terminal and flow.
+ *
+ * @defgroup sw_util Switch Util
+ * @ingroup core
+ */
+
+#ifndef _BAL_SWITCH_UTIL_H_
+#define _BAL_SWITCH_UTIL_H_
+
+/*@{*/
+
+#include <acc_term_fsm.h>
+#include <flow_fsm.h>
+#include <group_fsm.h>
+#include <tm_sched_fsm.h>
+#include <tm_queue_fsm.h>
+
+
+#include <bcmcli.h>
+#include <bal_utils_msg.h>
+
+#define BCM_DEVICE_KT2 0xb450
+#define BCM_DEVICE_ARAD_PLUS 0x8660
+#define BCM_DEVICE_ARAD 0x8650
+#define BCM_DEVICE_QAX 0x8470
+
+/* Function Prototypes for external */
+bcmos_errno sw_util_access_terminal_set(acc_term_inst *p_acc_term, bal_util_oper_acc_term opt_type);
+bcmos_errno sw_util_flow_info_validate(void *p_msg);
+bcmos_errno sw_util_flow_set(flow_inst *p_flow, bal_util_oper_flow opt_type);
+bcmos_errno sw_util_flow_finish(void);
+bcmos_errno sw_util_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if opt_type);
+bcmos_errno sw_util_group_info_validate(void *p_msg);
+bcmos_errno sw_util_group_set(group_inst *p_group_inst, bal_util_oper_group opt_type);
+bcmos_errno sw_util_group_finish(void);
+bcmos_errno sw_util_init(void);
+bcmos_errno sw_util_cli_init(bcmcli_entry *top_dir);
+bcmos_errno sw_util_finish(void);
+
+
+bcmos_errno sw_util_tm_sched_validate(void *p_msg);
+bcmos_errno sw_util_tm_sched_set(tm_sched_inst *p_tm_sched_inst);
+bcmos_errno sw_util_tm_sched_clear(tm_sched_inst *p_tm_sched_inst);
+
+bcmos_errno sw_util_tm_queue_validate(void *p_msg);
+bcmos_errno sw_util_tm_queue_set(tm_queue_inst *p_tm_queue_inst);
+bcmos_errno sw_util_tm_queue_clear(tm_queue_inst *p_tm_queue_inst);
+
+
+/* switch util log id */
+extern dev_log_id log_id_sw_util;
+
+/*@}*/
+
+#endif /* _BAL_SWITCH_UTIL_H_ */
+
diff --git a/bal_release/src/core/util/switch/dpp/Makefile b/bal_release/src/core/util/switch/dpp/Makefile
new file mode 100644
index 0000000..5da000b
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/Makefile
@@ -0,0 +1,46 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL Switch Util DPP
+MOD_NAME = switch_util_dpp
+MOD_TYPE = lib
+MOD_DEPS = dev_log utils bal_api bal_app_utils
+srcs = bal_dpp_acc_term.c bal_dpp_flow.c bal_dpp_interface.c bal_dpp_qos.c bal_dpp_qos_map.c bal_dpp_vswitch.c bal_dpp_group.c
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../../main -I$(SRC_DIR)/..
+
+ifeq ("$(TEST_SW_UTIL_LOOPBACK)", "y")
+ MOD_DEFS += -DTEST_SW_UTIL_LOOPBACK
+else
+ MOD_DEPS += switch_sdk
+endif
+
+ifeq ("$(SWITCH)", "qax")
+ MOD_DEFS += -DQAX_SWITCH
+endif
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.c b/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.c
new file mode 100755
index 0000000..42a9e95
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.c
@@ -0,0 +1,624 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+#include "bal_dpp_acc_term.h"
+#include "bal_dpp_qos.h"
+#include "bal_dpp_qos_map.h"
+
+#include <bcm/types.h>
+#include <bcm/port.h>
+#include <bcm/rx.h> /* for dpp rpc rx register callback */
+#include <bcm/switch.h>
+#include <bcm/l2.h>
+
+/**
+ * @file bal_dpp_acc_term.c
+ * @brief BAL Switch util functions that handle access terminal requests on DUNE PACKET PROCESSOR
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+
+ /* @brief L2 Table Operation Control
+ *
+ * This routine set the HW L2 learning and aging
+ *
+ * @param unit The device id
+ * @param flags Operation flags
+ * BCM_L2_LEARN_CPU 0x20
+ * BCM_L2_INGRESS_DIST 0x02
+ * BCM_L2_INGRESS_CENT 0x01
+ * @param age_seconds L2 entry age out time in seconds
+ * @return BCM error code
+ */
+static int sw_util_dpp_l2_entry_control_set(int unit, int flags, int age_seconds)
+{
+ int rv = 0;
+
+ rv = bcm_switch_control_set(unit, bcmSwitchL2LearnMode, flags);
+ if (rv)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " bcm_switch_control_set failed ret = %d\n", rv);
+ return rv;
+ }
+
+ /* set aging time */
+ rv = bcm_l2_age_timer_set(unit, age_seconds);
+ if (rv)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " bcm_l2_age_timer_set failed ret = %d\n", rv);
+ return rv;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, " Set L2 table aging time to %d seconds\n", age_seconds);
+ }
+
+ return rv;
+
+}
+
+
+/**
+ * @brief L2 Table event handler
+ *
+ * This routine is a callback triggered by HW L2 Table events
+ *
+ * @param unit The device id
+ * @param p_l2addr Pointer to the L2 entry where the event is happen
+ * @param operation The type of event
+ * @param userdata Pointer to a user provided data when the handler is registered
+ */
+static void sw_util_dpp_l2_entry_event_handler(int unit, bcm_l2_addr_t *p_l2addr, int operation, void *userdata)
+{
+
+ if (p_l2addr == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " L2 entry callback with NULL L2 address, op = %d\n", operation);
+ return;
+ }
+ if (operation == BCM_L2_CALLBACK_LEARN_EVENT)
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " BCM_L2_CALLBACK_LEARN_EVENT handler\n");
+ }
+ else if (operation == BCM_L2_CALLBACK_MOVE_EVENT)
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " BCM_L2_CALLBACK_MOVE_EVENT handler\n");
+ }
+ else if (operation == BCM_L2_CALLBACK_AGE_EVENT)
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " BCM_L2_CALLBACK_AGE_EVENT handler\n");
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " BCM_L2_CALLBACK_OPERATION %d handler\n", operation);
+ }
+
+ BCM_LOG(DEBUG, log_id_sw_util, " MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (0xff & p_l2addr->mac[0]),
+ (0xff & p_l2addr->mac[1]),
+ (0xff & p_l2addr->mac[2]),
+ (0xff & p_l2addr->mac[3]),
+ (0xff & p_l2addr->mac[4]),
+ (0xff & p_l2addr->mac[5]) );
+
+ if(!(p_l2addr->flags & BCM_L2_MCAST))
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " UC VID=0x%x| PORT=0x%08x\n", p_l2addr->vid, p_l2addr->port);
+ /* print_gport_part - p_l2addr->port */
+ {
+ int a = -1, b = 0;
+ char* type = "";
+ if (a==-1){
+ a=BCM_GPORT_LOCAL_GET(p_l2addr->port);
+ type ="local";
+ }
+ if (a==-1){
+ a=BCM_GPORT_MODPORT_MODID_GET(p_l2addr->port);
+ b=BCM_GPORT_MODPORT_PORT_GET(p_l2addr->port);
+ type ="modport";
+ }
+ if (a==-1){
+ a=BCM_GPORT_TRUNK_GET(p_l2addr->port);
+ type ="trunk";
+ }
+ if (a==-1){
+ a=BCM_GPORT_MCAST_GET(p_l2addr->port);
+ type ="mact";
+ }
+ if (a==-1){
+ a=BCM_GPORT_MPLS_PORT_ID_GET(p_l2addr->port);
+ type ="mpls_port";
+ }
+ if (a==-1){
+ a=BCM_GPORT_VLAN_PORT_ID_GET(p_l2addr->port);
+ type ="vlan_port";
+ }
+ if (a==-1){
+ a=BCM_GPORT_SYSTEM_PORT_ID_GET(p_l2addr->port);
+ type ="sys_port";
+ }
+ if (a==-1){
+ a=BCM_GPORT_MIRROR_GET(p_l2addr->port);
+ }
+ BCM_LOG(DEBUG, log_id_sw_util, " GPORT %s <0x%x,%d>\n", type, a, b);
+ }
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, " MC 0x%08x\n",p_l2addr->l2mc_group);
+ }
+ BCM_LOG(DEBUG, log_id_sw_util, " static %d|\n", (p_l2addr->flags & BCM_L2_STATIC)!=0 );
+
+}
+
+/**
+ * @brief Connect access terminal with DPP as part of the components
+ *
+ * This routine is called by sw_util_access_terminal_connect in the BAL core
+ * to execute DPP specific API for access_terminal_connect request
+ *
+ * @param p_net_map Pointer to the net ports mapping from logical numbrer to physical number
+ * @param p_pon_map Pointer to the pon ports mapping from logical numbrer to physical number
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_dpp_acc_term_connect(bal_swapp_port *p_net_map, bal_swapp_port *p_pon_map )
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ int rc = 0;
+ bal_swapp_port *port;
+
+ BCM_LOG(INFO, log_id_sw_util, " DPP - Got a access terminal CONNECT\n");
+
+ do
+ {
+ /* setup the device ID - This is very hardware specific */
+ port = p_net_map;
+ /* -1 indicate the end of table */
+ while(port->pbm_id != -1)
+ {
+
+ /* the default TPID is 0x8100, add 0x88a8 to the allow TPID */
+
+ rc = bcm_port_tpid_delete_all(port->device_id, port->pbm_id);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to clear the nni TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+ rc = bcm_port_tpid_add(port->device_id, port->pbm_id, 0x8100, 0);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to add 0x8100 to the nni TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+ rc = bcm_port_tpid_add(port->device_id, port->pbm_id, 0x88a8, 0);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to add 0x88a8 to the nni TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ port++;
+ }
+
+ port = p_pon_map;
+ while(port->pbm_id != -1)
+ {
+
+ /* the default TPID is 0x8100, add 0x88a8 to the allow TPID */
+
+ rc = bcm_port_tpid_delete_all(port->device_id, port->pbm_id);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to clear the pon TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+ rc = bcm_port_tpid_add(port->device_id, port->pbm_id, 0x8100, 0);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to add 0x8100 to the pon TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+ rc = bcm_port_tpid_add(port->device_id, port->pbm_id, 0x88a8, 0);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to add 0x88a8 to the pon TPID list on interface %d\n", port->pbm_id);
+ ret = BCM_ERR_INTERNAL;
+ }
+
+ port++;
+ }
+
+ if(ret != BCM_ERR_OK)
+ {
+ /* exit if port init failed */
+ break;
+ }
+
+ /* Remove all ports from VLAN 1, so the L2 broadcast won't send to CPU port by default */
+ bcm_vlan_gport_delete_all(bal_bcm_dft_dev_get(), 1);
+
+ /* configure all qos map tables */
+ ret = bal_sw_dpp_pcp_remark_maps_init(bal_bcm_dft_dev_get());
+ if (ret)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " DPP - fail to init qos map tables\n");
+ break;
+ }
+
+ /* init the DS QOS hierarchical scheduling - ignore error if HW dos not support QOS */
+ ret =bal_sw_dpp_qos_init(bal_bcm_dft_dev_get(), bal_bcm_intf_maptable_get());
+ if (ret)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " DPP - fail to init qos HR scheduler\n");
+ break;
+ }
+
+ rc = bcm_l2_addr_register(bal_bcm_dft_dev_get(), sw_util_dpp_l2_entry_event_handler, NULL);
+ if (rc)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " DPP - fail to register l2_addr callback \n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ rc = sw_util_dpp_l2_entry_control_set(bal_bcm_dft_dev_get(), BCM_L2_LEARN_CPU|BCM_L2_INGRESS_DIST, bal_bcm_l2_age_time_get());
+ if (rc)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " DPP - fail to set l2_addr control \n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }while(0);
+ return ret;
+}
+
+/* internal structure used by the trap receiving thread */
+typedef struct
+{
+ int udp_port;
+ pthread_t threadid;
+ dpp_rx_cb_f callback;
+} trap_context;
+
+static trap_context g_trap_ctx = {0};
+
+/* the adjustment needed for ING trap packet header */
+#define DEFAULT_SOP_ADJ 2
+#define DEFAULT_REASON_ADJ 4
+/* compiler restirct the total local variables size < 16384 */
+#define DEFAULT_TRAP_BUF_SIZE (10 *1024)
+/*
+ the listener thread that wait for the trap packet_in message from the switch
+*/
+static void *trap_receive(void *p_user_data)
+{
+ int rc;
+ int sUDPSocket;
+ unsigned char cBuffer[DEFAULT_TRAP_BUF_SIZE];
+ int nBytesRecv = 0;
+ int nBufSize = DEFAULT_TRAP_BUF_SIZE;
+ socklen_t nReceiveAddrSize = 0;
+ int maxfd;
+ fd_set read_fds;
+ struct timeval tv;
+ uint16_t tmp_src_port, src_port;
+ trap_context *p_trap_ctx = (trap_context *)p_user_data;
+ uint32_t tmp_reason, reason;
+ /* Create a connectionless socket */
+ sUDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ /* Check to see if we have a valid socket */
+ if(sUDPSocket < 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - trap_receive:create socket failed\n");
+ return NULL;
+ }
+
+ // Setup a bind on the socket, telling us what port and
+ // adapter to receive datagrams on.
+ struct sockaddr_in sReceiveFromAddr;
+ memset(&sReceiveFromAddr, 0, sizeof(struct sockaddr_in));
+
+ sReceiveFromAddr.sin_family = AF_INET;
+ sReceiveFromAddr.sin_port = htons(p_trap_ctx->udp_port);
+ sReceiveFromAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ rc = bind(sUDPSocket, (struct sockaddr *)&sReceiveFromAddr,
+ sizeof(struct sockaddr_in));
+ if (rc < 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - trap_receive:bind failed\n");
+ return NULL;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, " DPP - trap_receive start listen at %d\n", p_trap_ctx->udp_port);
+
+ // Receive a datagram from another device
+ while(1)
+ {
+ FD_ZERO(&read_fds);
+ FD_SET(sUDPSocket, &read_fds);
+ maxfd = sUDPSocket;
+ /* Set the timeout */
+ tv.tv_sec = 3;
+ tv.tv_usec = 0; /* 3 seconds */
+ rc = select(maxfd + 1, &read_fds, NULL, NULL, &tv);
+
+ if (rc < 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - trap_receive:select failed err = %d\n", rc);
+ break;
+ }
+ if (rc == 0) /* timeout */
+ {
+ continue;
+ }
+ // Get the datagrama
+ nBytesRecv = recvfrom(sUDPSocket, cBuffer, nBufSize, 0,
+ (struct sockaddr *) &sReceiveFromAddr,
+ &nReceiveAddrSize);
+ BCM_LOG(INFO, log_id_sw_util, " DPP - Got %d bytes message \n", nBytesRecv);
+
+ /* the first 4 bytes are reason */
+ /* compiler generate cast-align warning -> p_reason = (uint32_t *)(cBuffer); */
+ memcpy(&tmp_reason, cBuffer, sizeof(uint32_t) );
+ reason = ntohl(tmp_reason);
+ /* the next 2 bytes are srouce port */
+ /* compiler generate cast-align warning -> p_src_port = (uint16 *)(cBuffer + DEFAULT_REASON_ADJ); */
+ memcpy(&tmp_src_port, cBuffer + DEFAULT_REASON_ADJ, sizeof(uint16_t));
+ src_port = ntohs(tmp_src_port);
+
+ /* call the register callback here - set unit to 0 as it is don't care */
+ if(p_trap_ctx->callback)
+ {
+ p_trap_ctx->callback(0, src_port, reason, cBuffer+DEFAULT_SOP_ADJ+DEFAULT_REASON_ADJ, nBytesRecv-DEFAULT_SOP_ADJ-DEFAULT_REASON_ADJ);
+ }
+ }
+ close(sUDPSocket);
+
+ return NULL;
+}
+
+/**
+ * @brief Start a receiving thread and add the callbck to process CPU trapped packets
+ *
+ * This routine is called by sw_util_access_terminal_connect in the BAL core
+ * to execute DPP specific API for process the trapping packets
+ *
+ * @param unit the switch device number the callback applied
+ * @param cb_f a callback function that process the trapped packets
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_dpp_rx_cb_register(uint32_t unit, dpp_rx_cb_f cb_f)
+{
+ int ret;
+
+ /* if the receiving thread already started, return error */
+ if (g_trap_ctx.threadid)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - There is an existing trap receiving thread\n");
+ return BCM_ERR_INTERNAL;
+ }
+
+ g_trap_ctx.udp_port = bal_bcm_trap_rcv_port_get();
+ g_trap_ctx.callback = cb_f;
+
+ /* use default attribute to create the thread */
+ ret = pthread_create(&g_trap_ctx.threadid, NULL, &trap_receive, &g_trap_ctx);
+
+ if(ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " DPP - fail to create trap receiving thread - %d\n", ret);
+ return BCM_ERR_INTERNAL;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/* To make compiler happy when build with ESW switch only */
+#ifdef ESW_SWITCH
+void dpp_dft_rx_cb(int unit, int dst_port, int reason, unsigned char *payload, int payload_len)
+{
+ return;
+}
+#else
+extern void dpp_dft_rx_cb(int unit, int dst_port, int reason, unsigned char *payload, int payload_len);
+#endif
+
+#define L2_HEADER_SIZE (12) /* bytes */
+
+#define TUNNEL_TAG_TPID_LEN (2) /* bytes - TPID (2 bytes) */
+#define TUNNEL_TAG_PBITS_CFI_VLAN_ID_LEN (2) /* PBITS+CFI+VLAN ID (2 bytes) */
+#define TUNNEL_TAG_SIZE (TUNNEL_TAG_TPID_LEN + TUNNEL_TAG_PBITS_CFI_VLAN_ID_LEN)
+
+bcmos_errno sw_util_dpp_pkt_send(int target_port_id,
+ int reason,
+ unsigned char *p_user_pkt,
+ int user_pkt_len,
+ trap_target target_device,
+ int target_tunnel_id)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ char *p_pktout_msg;
+ uint8_t dst_port_id;
+ int dst_device_id;
+ char *p_pktout_ptr;
+ uint32_t total_msg_size;
+ uint32_t uint32_num;
+ uint16_t uint16_num;
+
+ /*
+ * Allocate a message to be sent to the bcm.user instance. This will contain
+ * the packet to be sent out of the switch, as well has header metadata.
+ */
+ p_pktout_msg = bcmos_calloc(user_pkt_len +
+ DEFAULT_SOP_ADJ +
+ DEFAULT_REASON_ADJ +
+ TUNNEL_TAG_SIZE);
+
+ if(NULL == p_pktout_msg)
+ {
+ return BCM_ERR_NOMEM;
+ }
+
+ /* translate the output port to the bcm.user's mapping */
+ switch(reason)
+ {
+ case REASON_SEND_TO_NNI:
+ dst_port_id = bal_bcm_net_inf_pbm_get(target_port_id);
+ dst_device_id = bal_bcm_net_inf_dev_get(target_port_id);
+ break;
+ case REASON_SEND_TO_PON:
+ dst_port_id = bal_bcm_pon_inf_pbm_get(target_port_id);
+ dst_device_id = bal_bcm_pon_inf_dev_get(target_port_id);
+ break;
+ default:
+ return BCM_ERR_PARM;
+ break;
+ }
+
+ /* Format of the message to the bcm.user instance is:
+ *
+ * reason code: 4 bytes
+ * dst_port: 2 bytes
+ * user packet: pkt_size bytes
+ */
+
+ /* Insert the 4 bytes with reason code */
+ uint32_num = (htonl(reason));
+ memcpy(p_pktout_msg, &uint32_num, sizeof(uint32_num));
+
+ /* Replace 2 bytes with packet_out destination port info. This is the bcm.user's
+ * mapping of output port (NNI or PON) to BCM SDK port mapping */
+ uint16_num = htons(dst_port_id & 0xff); /* dst_port contents is actually only 1 byte */
+ memcpy(&p_pktout_msg[DEFAULT_REASON_ADJ], &uint16_num, sizeof(uint16_num));
+
+ /* Copy in the user packet to send to the bcm.user for transmission out of the switch.
+ * Remember to insert the proper tunnel tag in the message for out_ports that are
+ * associated with the PON
+ */
+ p_pktout_ptr = p_pktout_msg + DEFAULT_REASON_ADJ + DEFAULT_SOP_ADJ;
+ total_msg_size = user_pkt_len + DEFAULT_REASON_ADJ + DEFAULT_SOP_ADJ;
+
+ if(reason == REASON_SEND_TO_NNI)
+ {
+ /* Copy in the entire packet as-is */
+ memcpy(p_pktout_ptr, p_user_pkt, user_pkt_len);
+ }
+ else
+ {
+ uint16_t pktout_offset = 0;
+
+ /* Copy in the L2 header (MAC DA/SA) */
+ memcpy(&p_pktout_ptr[pktout_offset], p_user_pkt, L2_HEADER_SIZE);
+
+ /* Point to the tunnel tag area in the outgoing message */
+ pktout_offset += L2_HEADER_SIZE;
+
+ /* Insert the TPID in the tag for the output destination */
+ uint16_num = htons(0x8100);
+ memcpy(&p_pktout_ptr[pktout_offset], &uint16_num, sizeof(uint16_num));
+
+ /* Point to the remainder of the outgoing message */
+ pktout_offset += TUNNEL_TAG_TPID_LEN;
+ /* Insert the tunnel tag vlan ID for the output destination */
+ uint16_num = htons(target_tunnel_id);
+ memcpy(&p_pktout_ptr[pktout_offset], &uint16_num, sizeof(uint16_num));
+
+ /* Point to the remainder of the outgoing message */
+ pktout_offset += TUNNEL_TAG_PBITS_CFI_VLAN_ID_LEN;
+
+ /* Copy in the rest of the message */
+ memcpy(&p_pktout_ptr[pktout_offset],
+ (p_user_pkt + L2_HEADER_SIZE),
+ (user_pkt_len - L2_HEADER_SIZE));
+
+ total_msg_size += TUNNEL_TAG_SIZE;
+ }
+
+
+ BCM_LOG(DEBUG, log_id_sw_util, "Packet send (user pkt_size:%d) destined for %s port %d\n",
+ user_pkt_len,
+ (reason == REASON_SEND_TO_PON) ? "PON" : "NNI",
+ dst_port_id);
+
+ if(reason == REASON_SEND_TO_PON)
+ {
+ BCM_LOG(DEBUG, log_id_sw_util, "Sending via GEM %d\n", target_tunnel_id);
+ }
+
+ if (bal_bcm_use_rpc_get())
+ {
+ /* On systems where BAL runs remotely from the switch hardware, we
+ * send the packet out message to the remote bcm.user process.
+ * That process then sends the attached user packet to the specified switch port.
+ */
+
+ sendto(target_device.socket,
+ p_pktout_msg,
+ total_msg_size, 0,
+ (struct sockaddr *) &(target_device.addr),
+ sizeof(struct sockaddr_in));
+
+ }
+ else
+ {
+ /* On systems where BAL runs on the CPU co-located with the switch hardware,
+ * we send the attached user packet to the specified switch port directly.
+ */
+
+ total_msg_size = total_msg_size - ( DEFAULT_REASON_ADJ + DEFAULT_SOP_ADJ );
+ dpp_dft_tx_cb(dst_device_id,
+ dst_port_id,
+ reason,
+ (unsigned char *)p_pktout_ptr,
+ total_msg_size);
+ }
+
+ bcmos_free(p_pktout_msg);
+
+ BCM_LOG(INFO, log_id_sw_util, "CPU packet msg sent to bcm.user for packet with msg size of %d (payload size: %d)\n",
+ total_msg_size, user_pkt_len);
+
+ return ret;
+}
+
+/*@}*/
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.h b/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.h
new file mode 100755
index 0000000..4f71549
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_acc_term.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_acc_term.h
+ *
+ * @brief bal switch util access terminal service function header file for DUNE PACKET PROCESSOR
+ *
+ * @addtogroup sw_util
+ */
+
+#ifndef _BAL_DPP_ACC_TERM_H_
+#define _BAL_DPP_ACC_TERM_H_
+
+/*@{*/
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+
+extern bcmos_errno sw_util_dpp_acc_term_connect(bal_swapp_port *p_net_map, bal_swapp_port *p_pon_map);
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/rx.h> /* for dpp rpc rx register callback */
+extern bcmos_errno sw_util_dpp_rx_cb_register(uint32_t unit, dpp_rx_cb_f cb_f);
+
+bcmos_errno sw_util_dpp_pkt_send(int dst_port_id,
+ int reason,
+ unsigned char *payload,
+ int payload_len,
+ trap_target target_device,
+ int target_tunnel_id);
+#endif /* TEST_SW_UTIL_LOOPBACK */
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_flow.c b/bal_release/src/core/util/switch/dpp/bal_dpp_flow.c
new file mode 100755
index 0000000..bf8067c
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_flow.c
@@ -0,0 +1,2618 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_flow.c
+ * @brief BAL Switch util functions that handle flow requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include <bal_utils_msg.h>
+#include "bal_switch_flow.h"
+#include "flow_fsm.h"
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+#include "bal_dpp_qos_map.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#define _SHR_PBMP_WIDTH 567
+ /* match the WIDTH size of bcm_field_group_config_t in bcm/field.h with ARAD */
+ /* we build swich_util without #define created by the sdk make/Make.local */
+#include <bcm/types.h>
+#include <sal/core/libc.h>
+#ifndef sal_memset
+#define sal_memset memset
+#endif
+#include <bcm/port.h>
+#include <bcm/vlan.h>
+#include <bcm/field.h>
+#include <bcm/error.h>
+#include <bcm/vswitch.h>
+#include <bcm/qos.h>
+#include <bcm/l2.h>
+
+#include "bal_switch_acc_term.h"
+#include "bal_dpp_flow.h"
+#include "bal_dpp_qos.h"
+#include "bal_dpp_vswitch.h"
+#include "bal_dpp_group.h"
+
+/** Local routines declarations */
+static bcmos_errno bal_sw_util_reverse_flow_create(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_flow_rev);
+static bcmos_bool bal_sw_util_is_symmetry_flows(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_ref_flow);
+
+/* perform initialization before any dpp flow function calls */
+void bal_sw_util_dpp_flow_init(void)
+{
+ /* nothing to do here yet, place holder */
+ return;
+}
+
+/**
+ * @brief The create trap gport function create a trap port that allow TRAP action to
+ * associate with and perform packet trapping to the CPU port.
+ *
+ * @param unit the switch unit this trap port to be created
+ * @param p_trap_gport a pointer that the created gport will be return
+ * @param p_trap_code a pointer that the created trap code will be return
+ * @return bcm error code
+ */
+static int bal_sw_util_create_trap_gport(int unit, bcm_gport_t *p_trap_gport, uint32_t *p_trap_code)
+{
+ int ret, trap_id;
+ bcm_rx_trap_config_t trap_config;
+
+ ret = bcm_rx_trap_type_create(unit, 0, bcmRxTrapUserDefine, &trap_id);
+ if(ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "create trap type return %d\n", ret);
+ return ret;
+ }
+
+ bcm_rx_trap_config_t_init(&trap_config);
+ trap_config.flags = (BCM_RX_TRAP_UPDATE_DEST | BCM_RX_TRAP_TRAP | BCM_RX_TRAP_REPLACE);
+ trap_config.trap_strength = 0;
+ trap_config.dest_port = BCM_GPORT_LOCAL_CPU;
+ ret = bcm_rx_trap_set(unit, trap_id, &trap_config);
+ if(ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "set rx trap return %d\n", ret);
+ return ret;
+ }
+ BCM_GPORT_TRAP_SET(*p_trap_gport, trap_id, 7 /* trap_strength */, 0);
+ *p_trap_code = trap_id;
+ return ret;
+}
+/* disable the field group (FG) source ip support to restrict the FG size */
+#define BAL_ACL_FG_SRC_IP_ENABLE 0
+/* create a default field group that used by all default ACL.
+ When a FLOW is created,a LIF is created to direct the packets to a VSwitch.
+ The LIF can only match packet with ingress port and VID.
+ If a FLOW needs to be classified with more attributes, an ACL is created to override the LIF.
+ A default ACL has the same packet classification as the LIF but has lower priority than the overlapped ACL.
+ The default ACL dropped packets that match the LIF but do not match the ACL. This enforce the FLOW
+ to only forward packets with exact match */
+static bcm_field_group_t dpp_dft_group_id = 1;
+/* create a field group that used by all ACL */
+static bcm_field_group_t dpp_group_id = 0;
+/**
+ * @brief Create a field group in the switch ICAP,
+ * The field group allow flow classifier to create ACL rules
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_group_id a pointer to a variable that return the created group id
+ * @return error code
+ */
+ static bcmos_errno bal_sw_util_dpp_fg_create(int unit, bcm_field_group_t *p_group_id)
+ {
+ bcm_field_group_status_t fg_status;
+ bcm_field_group_config_t grp;
+ int32_t ret = 0;
+
+ /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
+ /* The DPP resources allow only limit number of qset - indexed by dpp_group_id, create qset when necessary */
+ /* create one if not exist */
+ if (BCM_E_NOT_FOUND == bcm_field_group_status_get(unit, *p_group_id, &fg_status))
+ {
+ bcm_field_group_config_t_init(&grp);
+
+ BCM_FIELD_QSET_INIT(grp.qset);
+ /* TCAM entry limit to 80 bits per slice, but up to 4 slices for a group
+ use ModeAuto to automatically adjust it */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInPort); /* 32 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyDstMac); /* 48 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifySrcMac); /* 48 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyDstIp); /* 32 bits */
+#if (BAL_ACL_FG_SRC_IP_ENABLE == 1)
+ /* save source IP space for other classifier, try to keep total size under 4 slices */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifySrcIp); /* 32 bits */
+#endif
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyEtherType); /* 16 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyIpProtocol); /* 8 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyL4DstPort); /* 16 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyL4SrcPort); /* 16 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyOuterVlanId); /* 16 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyOuterVlanPri); /* 8 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInnerVlanId); /* 16 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInnerVlanPri); /* 8 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInVPort); /* 32 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyPacketRes);
+
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyStageIngress);
+
+ BCM_FIELD_ASET_INIT(grp.aset);
+ BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionTrap);
+ BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionDrop);
+ BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionRedirect);
+ BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionVportNew);
+
+ grp.priority = 12; /* the higher the number the higher the priority */
+ grp.flags = (BCM_FIELD_GROUP_CREATE_WITH_MODE | BCM_FIELD_GROUP_CREATE_WITH_ASET);
+ grp.mode = bcmFieldGroupModeAuto;
+
+ ret = bcm_field_group_config_create(unit, &grp);
+
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to create field - %d\n", ret );
+ return BCM_ERR_INTERNAL;
+ }
+
+ *p_group_id = grp.group;
+ BCM_LOG(INFO, log_id_sw_util, "Field Group %d created\n", *p_group_id);
+ return BCM_ERR_OK;
+ }
+ return BCM_ERR_ALREADY;
+ }
+
+/**
+ * @brief Create a default field group in the switch ICAP,
+ * This field group allow flow classifier to create default ACL rules
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_group_id a pointer to a variable that return the created group id
+ * @return error code
+ */
+ static bcmos_errno bal_sw_util_dpp_dft_fg_create(int unit, bcm_field_group_t *p_group_id)
+ {
+ bcm_field_group_status_t fg_status;
+ bcm_field_group_config_t grp;
+ int32_t ret = 0;
+
+ /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
+ /* The DPP resources allow only limit number of qset - indexed by dpp_group_id, create qset when necessary */
+ /* create one if not exist */
+ if (BCM_E_NOT_FOUND == bcm_field_group_status_get(unit, *p_group_id, &fg_status))
+ {
+ bcm_field_group_config_t_init(&grp);
+
+ BCM_FIELD_QSET_INIT(grp.qset);
+ /* TCAM entry limit to 80 bits per slice, but up to 4 slices for a group
+ use ModeAuto to automatically adjust it */
+
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInVPort); /* 32 bits */
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyPacketRes);
+
+ BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyStageIngress);
+
+ BCM_FIELD_ASET_INIT(grp.aset);
+ BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionDrop);
+
+ grp.priority = 10; /* the higher the number the higher the priority */
+ grp.flags = (BCM_FIELD_GROUP_CREATE_WITH_MODE | BCM_FIELD_GROUP_CREATE_WITH_ASET);
+ grp.mode = bcmFieldGroupModeAuto;
+
+ ret = bcm_field_group_config_create(unit, &grp);
+
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to create default field - %d\n", ret );
+ return BCM_ERR_INTERNAL;
+ }
+
+ *p_group_id = grp.group;
+ BCM_LOG(INFO, log_id_sw_util, "Default Field Group %d created\n", *p_group_id);
+ return BCM_ERR_OK;
+ }
+ return BCM_ERR_ALREADY;
+ }
+
+/**
+ * @brief The acl add function add an Access Control Rule in the switch VCAP/ICAP/ECAP
+ * to perform action based on flow classifier
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @param p_flow_elm a pointer to the switch internal flow list
+ * @param in_gport ingress virtual port (LIF) this acl applied
+ * @param out_gport egress virtual port (LIF) this acl applied
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_dpp_acl_add(int unit, bcmbal_flow_cfg *p_flow, bal_sw_flow *p_flow_elm, uint32_t in_gport, uint32_t out_gport)
+{
+ int32_t ret = 0;
+ uint16_t udp_port, flow_pri;
+ bcm_field_entry_t eid;
+ bcm_gport_t trap_gport;
+ bcm_mac_t dst_mac, src_mac;
+ bcm_mac_t mac_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ uint32_t trap_code = 0;
+ bcmos_errno err;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Add an ACL to a flow w type = %d\n", p_flow->key.flow_type);
+
+ if(p_flow_elm->num_eid >= MAX_FIELD_EID)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Too many ACL rules in flow id %d\n", p_flow_elm->id);
+ return BCM_ERR_NORES;
+ }
+
+ err = bal_sw_util_dpp_fg_create(unit, &dpp_group_id);
+
+ if (BCM_ERR_ALREADY != err && BCM_ERR_OK != err)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Field Group %d create failed\n", dpp_group_id);
+ return err;
+ }
+
+ /* fill in the match fields */
+ do
+ {
+ ret = bcm_field_entry_create(unit, dpp_group_id, &eid);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_entry_create failed - %d\n", ret);
+ break;
+ }
+ /* if upstream, match ingress port */
+ if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM && BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id))
+ {
+ ret = bcm_field_qualify_InPort(unit, eid, bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id), 0xffffffff);
+ if (BCM_E_NONE != ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InPort failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add InPort %d to qualifier\n", bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id));
+ }
+
+ }
+ /* if downstream, match ingress nni port */
+ if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM && BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id))
+ {
+ ret = bcm_field_qualify_InPort(unit, eid, bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id), 0xffffffff);
+ if (BCM_E_NONE != ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InPort failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add network port %d to qualifier\n", bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id));
+ }
+ }
+ /* match ether type */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ether_type))
+ {
+ ret = bcm_field_qualify_EtherType(unit, eid, p_flow->data.classifier.ether_type, 0xffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_EtherType failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add ether type 0x%x to qualifier\n", p_flow->data.classifier.ether_type );
+ }
+ }
+ /* add IP protocol to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ip_proto))
+ {
+ ret = bcm_field_qualify_IpProtocol(unit, eid, p_flow->data.classifier.ip_proto, 0xff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_IpProtocol failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add ip protocol 0x%x to qualifier\n", p_flow->data.classifier.ip_proto );
+ }
+ }
+ /* add L3 source port to match rule - Don't be confused by the API name */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port))
+ {
+ udp_port = p_flow->data.classifier.src_port;
+ ret = bcm_field_qualify_L4SrcPort(unit, eid, udp_port, 0xffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_L4SrcPort failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add src port %d to qualifier\n", udp_port );
+ }
+ }
+ /* add L3 destination port to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port))
+ {
+ udp_port = p_flow->data.classifier.dst_port;
+ ret = bcm_field_qualify_L4DstPort(unit, eid, udp_port, 0xffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_L4DstPort failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add dst port %d to qualifier\n", udp_port );
+ }
+ }
+ /* add Outer vid to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid))
+ {
+ ret = bcm_field_qualify_OuterVlanId(unit, eid, p_flow->data.classifier.o_vid, 0x0fff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_OuterVlanId failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add outer vid 0x%x to qualifier\n", p_flow->data.classifier.o_vid );
+ }
+ }
+ /* add Inner vid to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid))
+ {
+ ret = bcm_field_qualify_InnerVlanId(unit, eid, p_flow->data.classifier.i_vid, 0x0fff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InnerVlanId failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add Inner vid 0x%x to qualifier\n", p_flow->data.classifier.i_vid );
+ }
+ }
+ /* add Outer priority to match rule - only accept 3 bits */
+ /* use ACL for downstream, upstream pbit classification will be done through PON LIF */
+ if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
+ {
+ ret = bcm_field_qualify_OuterVlanPri(unit, eid, p_flow->data.classifier.o_pbits, 0x7);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_OuterVlanPri failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add outer pri 0x%x to qualifier\n", p_flow->data.classifier.o_pbits );
+ }
+ }
+ /* add Inner priority to match rule - only accept 3 bits */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_pbits))
+ {
+ ret = bcm_field_qualify_InnerVlanPri(unit, eid, p_flow->data.classifier.i_pbits, 0x7);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InnerVlanPri failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add inner pri 0x%x to qualifier\n", p_flow->data.classifier.i_pbits );
+ }
+ }
+ /* add Dst Mac to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
+ {
+ memcpy(&dst_mac, &(p_flow->data.classifier.dst_mac), sizeof(bcm_mac_t));
+ ret = bcm_field_qualify_DstMac(unit, eid, dst_mac, mac_mask);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_DstMac failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add DstMac %x:%x:%x:%x:%x:%x to qualifier\n",
+ p_flow->data.classifier.dst_mac.u8[0],
+ p_flow->data.classifier.dst_mac.u8[1],
+ p_flow->data.classifier.dst_mac.u8[2],
+ p_flow->data.classifier.dst_mac.u8[3],
+ p_flow->data.classifier.dst_mac.u8[4],
+ p_flow->data.classifier.dst_mac.u8[5] );
+ }
+ }
+ /* add Src Mac to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac))
+ {
+ memcpy(&src_mac, &(p_flow->data.classifier.src_mac), sizeof(bcm_mac_t));
+ ret = bcm_field_qualify_SrcMac(unit, eid, src_mac, mac_mask);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_SrcMac failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add SrcMac[5] 0x%x to qualifier\n", p_flow->data.classifier.src_mac.u8[5] );
+ }
+ }
+ /* add Dst IP to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip))
+ {
+ ret = bcm_field_qualify_DstIp(unit, eid, p_flow->data.classifier.dst_ip.u32, 0xffffffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_DstIp failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add DstIp 0x%x to qualifier\n", p_flow->data.classifier.dst_ip.u32 );
+ }
+ }
+
+ /* add Src IP to match rule */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip))
+ {
+ ret = bcm_field_qualify_SrcIp(unit, eid, p_flow->data.classifier.src_ip.u32, 0xffffffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_SrcIp failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add SrcIp 0x%x to qualifier\n", p_flow->data.classifier.src_ip.u32 );
+ }
+ }
+ /* set ACL priority */
+ if(BCMBAL_CFG_PROP_IS_SET(p_flow, flow, priority))
+ {
+ flow_pri = p_flow->data.priority;
+ }
+ else /* default to 10, valid range 0 - 65535 */
+ {
+ flow_pri = BAL_FLOW_DEFAULT_PRIORITY;
+ /* set the presence of priority bit in the flow to reflect insertion of DEFAULT_PRIORITY */
+ BCMBAL_CFG_PROP_SET(p_flow, flow, priority, flow_pri);
+ }
+ ret = bcm_field_entry_prio_set(unit, eid, flow_pri);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field entry priority failed - %d\n", ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "field entry priority set to - %d\n", flow_pri);
+ }
+
+ }while(0);
+
+ if (BCM_E_NONE == ret) /* make sure the field qualifier settings are good */
+ {
+ if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action) &&
+ BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST) )
+ {
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a flow action cmd=0x%x \n", p_flow->data.action.cmds_bitmask);
+ do
+ {
+ ret = bal_sw_util_create_trap_gport(unit, &trap_gport, &trap_code);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "create_trap_gport failed - %d\n", ret);
+ break;
+ }
+ /* qualify with in LIF */
+ if(in_gport)
+ {
+ /* add vPort to match rule */
+ ret = bcm_field_qualify_InVPort32(unit, eid, in_gport, 0xffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InVPort failed - %d\n", ret);
+ break;
+ }
+ }
+ ret = bcm_field_action_add(unit, eid, bcmFieldActionTrap, trap_gport, 0);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
+ break;
+ };
+ ret = bcm_field_entry_install(unit, eid);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", eid, ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add rule %d Success\n", eid);
+ }
+
+ }while(0);
+ }
+ /* regular forwarding ACL */
+ else
+ {
+ do
+ {
+ /* redirect to the egress LIF */
+ ret = bcm_field_action_add(unit, eid, bcmFieldActionRedirect, 0, out_gport);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
+ break;
+ };
+ /* trigger vlan translation at the egress LIF */
+ ret = bcm_field_action_add(unit, eid, bcmFieldActionVportNew, out_gport, 0);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field action add new vport failed - %d\n", ret);
+ break;
+ };
+
+ ret = bcm_field_entry_install(unit, eid);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", eid, ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add rule %d to gport 0x%x Success\n", eid, out_gport);
+ }
+ }while(0);
+ }
+ }
+
+ if (ret != BCM_E_NONE)
+ {
+ /* TBD - release the eid and trap port resource */
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ /* add flow info into the internal link list */
+ p_flow_elm->trap_code = trap_code;
+ p_flow_elm->trap_port = trap_gport;
+ p_flow_elm->field_entry_id[p_flow_elm->num_eid] = eid;
+ p_flow_elm->num_eid += 1;
+ p_flow_elm->valid = 1;
+ return BCM_ERR_OK;
+ }
+}
+
+/**
+ * @brief The default acl add function add a DROP Access Control Rule on the ingress LIF
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @param p_flow_elm a pointer to the switch internal flow list
+ * @param in_gport ingress virtual port (LIF) this acl applied
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_dpp_dft_acl_add(int unit, bcmbal_flow_cfg *p_flow, bal_sw_flow *p_flow_elm, uint32_t in_gport)
+{
+ bcmos_errno err;
+ bcm_field_entry_t dft_eid = 0;
+ int32_t ret = 0;
+
+ if(p_flow_elm->num_eid >= MAX_FIELD_EID)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Too many dft ACL rules in flow id %d\n", p_flow_elm->id);
+ return BCM_ERR_NORES;
+ }
+
+ err = bal_sw_util_dpp_dft_fg_create(unit, &dpp_group_id);
+
+ if (BCM_ERR_ALREADY != err && BCM_ERR_OK != err)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Field Default Group %d create failed\n", dpp_dft_group_id);
+ return err;
+ }
+ do
+ {
+ /* Install a default drop ACL at lowest priority(0).
+ This will drop unmatch packets received on the same ingress LIF
+ */
+
+ ret = bcm_field_entry_create(unit, dpp_group_id, &dft_eid);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_entry_create failed - %d\n", ret);
+ break;
+ }
+
+ /* add vPort to match rule */
+ ret = bcm_field_qualify_InVPort32(unit, dft_eid, in_gport, 0xffff);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InVPort failed - %d\n", ret);
+ break;
+ }
+
+ /* add Packet type to match rule, drop only unicast */
+ ret = bcm_field_qualify_PacketRes(unit, dft_eid, BCM_FIELD_PKT_RES_L2UC, 0);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_qualify_PacketRes failed - %d\n", ret);
+ break;
+ }
+
+
+ /* set to lowest priority 0 */
+ ret = bcm_field_entry_prio_set(unit, dft_eid, 0);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field entry priority failed - %d\n", ret);
+ break;
+ };
+
+ /* Drop the packet */
+ ret = bcm_field_action_add(unit, dft_eid, bcmFieldActionDrop, 0, 0);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
+ break;
+ };
+ ret = bcm_field_entry_install(unit, dft_eid);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", dft_eid, ret);
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Add default rule %d Success\n", dft_eid);
+ }
+ }while(0);
+ if (ret != BCM_E_NONE)
+ {
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ p_flow_elm->field_entry_id[p_flow_elm->num_eid] = dft_eid;
+ p_flow_elm->num_eid += 1;
+ return BCM_ERR_OK;
+ }
+}
+
+/**
+ * @brief The ingress vlan translation function modified the packet VLAN tag
+ * before sending it out
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @param ingport the gport the translation will be applied
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_dpp_invlanx(int unit, bcmbal_flow_cfg *p_flow, uint32_t ingport)
+{
+ int rv = 0;
+ bcm_vlan_action_set_t action;
+ bcm_vlan_action_set_t_init(&action);
+ bcmos_errno ret;
+
+ if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS))
+ {
+ int qos_map_id, i_pri, o_pri;
+
+ do
+ {
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* should be
+ action.dt_outer_pkt_prio = bcmVlanActionReplace;
+ action.new_outer_vlan = p_flow->data.classifier.o_vid;;
+ action.dt_outer = bcmVlanActionReplace;
+ but it does not seems to work. Using ot_outer seems to also work for double tagged packets
+ */
+ action.ot_outer_pkt_prio = bcmVlanActionReplace;
+ action.new_outer_vlan = p_flow->data.classifier.o_vid;
+ action.ot_outer = bcmVlanActionReplace;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ action.ot_outer_pkt_prio = bcmVlanActionReplace;
+ action.new_outer_vlan = p_flow->data.classifier.o_vid;
+ action.ot_outer = bcmVlanActionReplace;
+
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, pbits translation on untagged packets\n");
+ return BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+
+ /* perform o_pbits translation */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
+ {
+ i_pri = p_flow->data.classifier.o_pbits;
+ }
+ else
+ {
+ /* mark the source pcp DONTCARE */
+ i_pri = -1;
+ }
+ /* flow validation already make sure the action.o_pbits is set for REMARK_PBITS */
+ o_pri = p_flow->data.action.o_pbits;
+
+ ret = bal_sw_dpp_pcp_remark_map_get(i_pri, o_pri, &qos_map_id);
+
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, faile to obtain pcp map id, ret = %d\n", ret);
+ rv = BCM_E_UNAVAIL;
+ break;
+ }
+
+ rv = bcm_qos_port_map_set(unit, ingport, qos_map_id, -1);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, pbits translation bcm_qos_port_map_set ret = %d\n", rv);
+ break;
+ }
+
+ /* set the action priority profile */
+ action.priority = qos_map_id;
+ action.new_inner_pkt_prio = qos_map_id;
+ }while(0);
+ }
+ else
+ {
+ /* nothing to do, return OK */
+ return BCM_ERR_OK;
+ }
+ if(rv != BCM_E_NONE)
+ {
+ return BCM_ERR_INTERNAL;
+ }
+
+ rv = bcm_vlan_translate_action_create(unit, ingport, bcmVlanTranslateKeyPortOuter, BCM_VLAN_INVALID, BCM_VLAN_NONE, &action);
+ if( rv )
+ {
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Perform ingress vlan translation w %s action on gport 0x%x\n",
+ (p_flow->data.classifier.pkt_tag_type == BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)? "DT": "ST",
+ ingport);
+ return BCM_ERR_OK;
+ }
+}
+/**
+ * @brief The egress vlan translation function modified the packet VLAN tag
+ * before sending it out
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @param egport the gport the translation will be applied
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_dpp_evlanx(int unit, bcmbal_flow_cfg *p_flow, uint32_t egport)
+{
+ int rv = 0;
+ bcm_vlan_action_set_t action;
+ bcm_vlan_action_set_t_init(&action);
+
+ if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))
+ {
+ action.new_outer_vlan = p_flow->data.action.o_vid;
+ action.priority = 0;
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ action.ut_outer = bcmVlanActionAdd;
+ action.ut_outer_pkt_prio = bcmVlanActionAdd;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ action.ot_outer = bcmVlanActionAdd;
+ action.ot_outer_pkt_prio = bcmVlanActionAdd;
+ break;
+ default:
+ action.new_outer_vlan = 0;
+ action.ot_outer = bcmVlanActionNone;
+ break;
+ }
+
+ if( p_flow->data.action.o_tpid )
+ {
+ action.outer_tpid_action = bcmVlanTpidActionModify;
+ action.outer_tpid = p_flow->data.action.o_tpid;
+ }
+
+ }
+ else if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG))
+ {
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* should be action.dt_outer = bcmVlanActionDelete,
+ but it does not seems to work. Using ot_outer seems to also work for double tagged packets */
+ action.ot_outer = bcmVlanActionDelete;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ action.ot_outer = bcmVlanActionDelete;
+ break;
+ default:
+ action.ut_outer = bcmVlanActionNone;
+ break;
+ }
+ }
+ else if (BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG))
+ {
+ action.new_outer_vlan = p_flow->data.action.o_vid;
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* should be action.dt_outer = bcmVlanActionReplace,
+ but it does not seems to work. Using ot_outer seems to also work for double tagged packets */
+ action.ot_outer = bcmVlanActionReplace;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ action.ot_outer = bcmVlanActionReplace;
+ break;
+ default:
+ action.ut_outer = bcmVlanActionNone;
+ break;
+ }
+
+ /** @todo tpid is not translated for now */
+ /** @note the vid translated from is passed as a parameter to the api call */
+
+ }
+ else
+ {
+ /* nothing to do, return OK */
+ return BCM_ERR_OK;
+ }
+
+ rv = bcm_vlan_translate_egress_action_add(unit, egport, BCM_VLAN_NONE, BCM_VLAN_NONE, &action);
+ if( rv )
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "bcm_vlan_translate_egress_action_add failed %d on gport 0x%x\n", rv, egport);
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Perform egress vlan translation on gport 0x%x\n", egport);
+ return BCM_ERR_OK;
+ }
+}
+/**
+ * @brief Multicast flow add function forward the specified multicast packets to a multicast group.
+ * The multicast group has to be created prio to the mc_flow add operation
+ *
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @param service_type id this multicast flow is for multicast or downstream N:1 service
+ * @return error code
+ */
+static bcmos_errno bal_sw_util_dpp_mc_flow_add(bcmbal_flow_cfg *p_flow, uint32_t service_type)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcm_gport_t nni_gport;
+ int ii, unit, rv;
+ int nni;
+ bcm_vlan_t vsi;
+ bal_sw_flow *p_flow_elm;
+ bal_sw_flow flow_elm;
+ bal_sw_vsi_service *p_vsi_svc;
+ bal_sw_group_list *p_group_list;
+ uint32_t svc_tag_indx;
+
+ /* get a pointer to the specified group instance */
+ p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow->data.group_id);
+
+ if ( p_group_list == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: group %d not found\n", p_flow->data.group_id);
+ return BCM_ERR_INTERNAL;
+ }
+
+ unit = p_group_list->device;
+
+ /* make sure this flow id does not already exist */
+ p_flow_elm = bal_sw_util_flow_list_get_by_id(p_flow->key.flow_id);
+ if (p_flow_elm)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: flow id %d type %d already exist\n",p_flow->key.flow_id, p_flow->key.flow_type);
+ return BCM_ERR_INTERNAL;
+ }
+
+ do
+ {
+ /* initialize link list flow element */
+ memset(&flow_elm, 0, sizeof (bal_sw_flow));
+ /* fill in the basic info */
+ flow_elm.id = p_flow->key.flow_id;
+ flow_elm.device = unit;
+ flow_elm.group_id = p_flow->data.group_id;
+ flow_elm.flow_cookie = p_flow->data.cookie;
+
+ /* packet tag type are required fields when create NNI LIF */
+ /* Here make sure it is the supported type */
+ if(p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_UNTAGGED &&
+ p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_SINGLE_TAG &&
+ p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: MC classifier packet tag type 0x%x is invalid\n", p_flow->data.classifier.pkt_tag_type);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /* retrieve the vswitch instance */
+ p_vsi_svc = p_group_list->p_vsi;
+ if(p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, MC: vsi not created\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ vsi = p_vsi_svc->vswitch;
+
+ /* add flow to the vsi service tag list */
+ ret = bal_sw_util_dpp_vsi_service_tag_add(unit, p_vsi_svc, p_flow, &svc_tag_indx);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add flow to vsi service tag list\n");
+ break;
+ }
+
+ ii = 0; /* Start with the first NNI logical interface */
+ /* loop through all nni port, add them to vswitch, -1 indicate end of table */
+ /* Configure the switch nni LIF based on classifier in the flow. */
+ while(-1 != (nni = bal_bcm_net_inf_pbm_get(ii)))
+ {
+ /* skip nni port that is not in the same device or not valid */
+ if ( bal_bcm_net_inf_dev_get(ii) != unit ||
+ BCMOS_FALSE == bcm_topo_nni_is_valid(ii))
+ {
+ ii++;
+ continue;
+ }
+
+ /* if nni port is specified in the flow, skip the other nni ports */
+ if ( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) &&
+ ii != p_flow->data.network_int_id
+ )
+ {
+ ii++;
+ continue;
+ }
+
+ /* create gport based on nni physical port number */
+ ret = bal_sw_util_dpp_vsi_service_port_add(unit, p_vsi_svc, svc_tag_indx, nni, &nni_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add nni %d to vsi\n", nni);
+ break;
+ }
+
+ /* if DMAC is set, create a L2 entry, otherwise flood unknown to the group */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
+ {
+ /* add static MC 01:00:5E:00:00:start_mc to the dowstream MC group */
+ bcm_l2_addr_t l2addr;
+ bcm_mac_t mc_mac;
+
+ /* Add mc mac address */
+ memcpy(&mc_mac, &(p_flow->data.classifier.dst_mac), sizeof(bcm_mac_t));
+
+ bcm_l2_addr_t_init(&l2addr, mc_mac, vsi);
+ l2addr.flags = BCM_L2_STATIC | BCM_L2_MCAST;
+ /* direct output to the MC group */
+ l2addr.l2mc_group = p_group_list->l2_grp_id;
+
+ rv = bcm_l2_addr_add(unit, &l2addr);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,"Error: bcm_l2_addr_add MC returned %s \n",
+ bcm_errmsg(rv));
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ else
+ {
+ rv = bcm_port_control_set(unit, nni_gport, bcmPortControlFloodUnknownMcastGroup, BAL_DPP_MC_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, MC: bcm_port_control_set for nni failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ flow_elm.num_net++;
+ flow_elm.net_port[ii] = nni_gport;
+
+ ii++; /* Next NNI */
+ }
+ /* skip the rest if anything goes wrong */
+ if( ret != BCM_ERR_OK)
+ {
+ break;
+ }
+ /* perform vlan translation on nni port */
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "Warning, action for multicast flow not supported\n");
+ }
+
+ } while(0);
+
+ if( ret == BCM_ERR_OK)
+ {
+ /* increase the group reference count */
+ p_group_list->use_count++;
+ /* increase the vsi reference count */
+ p_vsi_svc->use_count++;
+ /* add the flow info to the flow link list */
+ flow_elm.p_vsi_svc = p_vsi_svc;
+ flow_elm.num_pon = 0;
+ flow_elm.type = service_type;
+ /* nni ports are done in the nni loop */
+ flow_elm.valid = 1;
+ bal_sw_util_flow_list_insert(flow_elm);
+
+ BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d type %d, vswitch 0x%x, group_id %d Success\n", flow_elm.id, flow_elm.type, p_vsi_svc->vswitch, flow_elm.group_id);
+ }
+ return ret;
+}
+
+/* HW limitation on max burst rate - bps */
+#define BAL_MAX_BURST_RATE (1 << 16)
+
+/**
+ * @brief The flow add function program DPP to forward packets that have
+ * specified attributes to the designated ports.
+ * The packets is modified before egress
+ * In case IWF is in DIRECT MODE,
+ * On the downstream, a tunnel id (outer vlan tag) is added to the packets
+ * On the upstream, outer vlan tag (tunnel id) is removed from the packets
+ * In case IWF is in PER_FLOW_MODE, currently not supported
+ *
+ * @note a flow can be created which does VID translation between V & U (refer to TR156) interfaces.
+ *
+ * @note This routine adds flow for both upstream and downstream direction i.e. create PON & NNI LIFs
+ * for both directions in a same call to this routine - and all this as part of a single call to this function
+ * from the application module or CLI.
+ * It also programs the egress vlan translation modules for both upstream and downstream.
+ *
+ * @note The general sequence is:
+ * \li create PON LIF with matching ingress tunnel id (and vlan id, if upstream pkts are vlan tagged)
+ * \li next, configure egress vlan translation on PON side (for downstream pkts)
+ * \li create NNI LIF with matching ingress vlan id (currently by default it assumes downstream packets are tagged)
+ * \li next, configure egress vlan translation on NNI side (for upstream pkts)
+ *
+ * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
+ * @param p_flow A pointer to the requested add flow info
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_flow_add(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcm_gport_t pon_gport, nni_gport;
+ bcm_vlan_t tunnel_id;
+ int ii, unit, rv;
+ bcm_vlan_port_t vp;
+ int pon, nni, sys_pon;
+ bcm_vlan_t vsi;
+ int pon_encap_id;
+ bal_sw_flow *p_flow_elm;
+ uint32_t flow_type, max_burst, svc_tag_indx;
+ bal_sw_flow flow_elm;
+ bal_sw_dpp_qos_service_cfg *p_service_cfg = NULL;
+ bcmbal_flow_cfg flow_rev; /* used for configuration in opposite direction */
+ bcmbal_flow_cfg *p_us_flow, *p_ds_flow;
+ bal_sw_vsi_service *p_vsi_svc;
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got an DPP flow request - iwf_mode=%d flow_id=%d flow_type=%d, sub_port=%d svc_id=%d\n",
+ iwf_mode,
+ p_flow->key.flow_id, p_flow->key.flow_type, p_flow->data.access_int_id, p_flow->data.svc_port_id);
+ BCM_LOG(DEBUG, log_id_sw_util,
+ " classifier - mask=0x%x otpid=%x itpid=%x ovid=%x ivid=%x\n",
+ p_flow->data.classifier.presence_mask,
+ p_flow->data.classifier.o_tpid, p_flow->data.classifier.i_tpid,
+ p_flow->data.classifier.o_vid, p_flow->data.classifier.i_vid);
+
+
+ if ( iwf_mode != BCMBAL_IWF_MODE_DIRECT_MAPPING)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: not supported IWF mode - %d\n", iwf_mode);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
+ {
+ BCM_LOG(DEBUG, log_id_sw_util,
+ " action.params: .cmds_bitmask=0x%x, .input_pkt_tag_type=0x%x\n",
+ p_flow->data.action.cmds_bitmask,
+ p_flow->data.classifier.pkt_tag_type);
+ }
+
+ if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla) &&
+ p_flow->data.sla.max_rate < p_flow->data.sla.min_rate)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: Max rate %d kbps is not >= Min rate %d kbps\n", p_flow->data.sla.max_rate, p_flow->data.sla.min_rate );
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ switch(p_flow->key.flow_type)
+ {
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ flow_type = BAL_SW_FLOW_TYPE_DOWNSTREAM;
+ /* for downstream N:1 service, same flood settings as multicast flow */
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id))
+ {
+ return bal_sw_util_dpp_mc_flow_add(p_flow, BAL_SW_FLOW_TYPE_DOWNSTREAM);
+ }
+ break;
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ flow_type = BAL_SW_FLOW_TYPE_UPSTREAM;
+ break;
+ case BCMBAL_FLOW_TYPE_MULTICAST:
+ return bal_sw_util_dpp_mc_flow_add(p_flow, BCMBAL_FLOW_TYPE_MULTICAST);
+ default:
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id);
+ /* We program a flow with 3 switch components, inLIF, vSwitch and outLIF.
+ LIF is always bi-directional operation, so for uni-directional flow we programmed an ingress or egress DROP
+ on PON based on the BAL flow direction. Later, when the BAL flow from the other direction is SET, we
+ remove the DROP from the PON.
+ This imply that two BAL flows with same id must have symmetry vlan manipulation operations.
+ */
+ p_flow_elm = bal_sw_util_flow_list_get_by_id(p_flow->key.flow_id);
+ if (p_flow_elm)
+ {
+ /* Check if flow with same id and type exist or not.
+ If downstream exist, remove the DISCARD_INGRESS from PON port by set it to DISCARD_NONE.
+ If upstream exist, remove the DISCARD_EGRESS from PON port by set it to DISCARD_NONE.
+ Asymmetry operations need two flows with different ID - each flow in uni-direction */
+ if(!(p_flow_elm->type & flow_type))
+ {
+ bcmbal_flow_cfg *p_ref_flow = NULL;
+ bcmbal_flow_key key;
+ /* retrieve the classifier on the other flow direction */
+ key.flow_id = p_flow->key.flow_id;
+ key.flow_type = (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)? BCMBAL_FLOW_TYPE_UPSTREAM : BCMBAL_FLOW_TYPE_DOWNSTREAM;
+ p_ref_flow = flow_get_current_info_by_key(key);
+ if(NULL == p_ref_flow)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: Can't locate flow %d type %d info from main DB\n", key.flow_id, key.flow_type);
+ return BCM_ERR_INTERNAL;
+ }
+ /* check the symmetrical properties between two flows */
+ if (BCMOS_FALSE == bal_sw_util_is_symmetry_flows(p_flow, p_ref_flow))
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: Flow %d does not have symmetry classifiers\n", key.flow_id);
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* if there is SLA in downstream, remove the US flow ( LIFs & VSWITCH) and build a new bi-direction flow.
+ This is because LIF is always bi-directional and when the US flow is created the PON LIF has no downstream VOQ.
+ One needs to create a new PON LIF with VOQ for SLA. There is no easy way to add VOQ to an existing LIF. */
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla) )
+ {
+ /* remove the existing US flow */
+ ret = bal_sw_util_dpp_flow_remove_int(p_flow_elm);
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: fail to remove flow %d from the list\n", p_flow->key.flow_id);
+
+ return BCM_ERR_INTERNAL;
+ }
+ flow_type = BAL_SW_FLOW_TYPE_DOWNSTREAM | BAL_SW_FLOW_TYPE_UPSTREAM;
+ /* goto regular path to create bi-directional flow */
+ }
+ /* if no SLA and the classifier is more than just port + VLAN tags, add ACL rule to re-direct packet to egress port.
+ This bypass the ingress LIF as LIF check VID only.
+ Upstream classification is expected to be done in ONU (onu add GEM based on classifiers for upstream),
+ return success after complete as there is no other changes needed for existing flow.
+ */
+ else
+ {
+ int i;
+ bcmos_bool is_nni_set = BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id);
+
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ bal_sw_util_flow_ds_acl_cls_chk(p_flow) == BCMOS_TRUE )
+ {
+ for(i=0; i < p_flow_elm->num_pon; i++)
+ {
+ for(ii=0; ii < p_flow_elm->num_net; ii++)
+ {
+ /*first get the ING logical port from gport */
+ bcm_vlan_port_t tmp_vp;
+ bcm_vlan_port_t_init(&tmp_vp);
+ tmp_vp.vlan_port_id = p_flow_elm->net_port[ii];
+ ret = bcm_vlan_port_find(unit, &tmp_vp);
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(WARNING, log_id_sw_util,
+ " Warning: fail to retrieve logical port from gport 0x%x\n", p_flow_elm->net_port[ii]);
+ continue;
+ }
+ /* if nni port is specified in the flow, skip the other nni ports */
+ if ( BCMOS_TRUE == is_nni_set && tmp_vp.port != bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id))
+ {
+ ii++;
+ /* if nni is set, it has to be in the nni list of the opposit FLOW */
+ /* set the return to BCM_ERR_INTERNAL, in case it reach the end of for-loop. */
+ ret = BCM_ERR_INTERNAL;
+ continue;
+ }
+ /* Rule need to match the ingress port, otherwise, it will apply to all ports - nni and pon */
+ if ( BCMOS_TRUE != is_nni_set)
+ {
+ BCMBAL_CFG_PROP_SET(p_flow, flow, network_int_id, bal_bcm_net_inf_idx_get(tmp_vp.port));
+ }
+ ret = bal_sw_util_dpp_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->net_port[ii], p_flow_elm->pon_port[i]);
+ if ( BCMOS_TRUE != is_nni_set)
+ {
+ BCMBAL_CFG_PROP_CLEAR(p_flow, flow, network_int_id);
+ }
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on nni %d, ret = %d\n", ret, ii);
+ break;
+ }
+ /* add a dft drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
+ ret = bal_sw_util_dpp_dft_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->net_port[ii]);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on nni=0x%x, ret = %d\n", p_flow_elm->net_port[ii], ret);
+ break;
+ }
+ }
+ if (ret != BCM_ERR_OK)
+ {
+ break;
+ }
+ }
+
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: fail to add DS ACL to nni_%d in flow id %d from the list\n", ii,p_flow->key.flow_id);
+
+ return BCM_ERR_INTERNAL;
+ }
+ }
+ /* If the US and DS has asymmetrical nature, we only program common part (VID) when create the LIF
+ We need an ACL rule to perform upstream specific classification and forwarding.
+ In addition, ACL allow upstream flows to be prioritized based on priority field.*/
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM &&
+ bal_sw_util_flow_us_acl_cls_chk(p_flow) == BCMOS_TRUE &&
+ /* there are issues using traditional API for PON application when egress vlan translation and ingress ACL are both active.
+ Enable the ACL only when there is no vlan action - TBD */
+ BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
+ {
+ if ( BCMOS_FALSE == is_nni_set)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: Upstream classifier in addition to VID without setting NNI is not supported\n");
+ return BCM_ERR_INTERNAL;
+ }
+
+ for(i=0; i < p_flow_elm->num_pon; i++)
+ {
+ ret = bal_sw_util_dpp_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->pon_port[i], p_flow_elm->net_port[p_flow->data.network_int_id]);
+
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on pon %d, ret = %d\n", ret, i);
+ break;
+ }
+ /* add a default drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
+ ret = bal_sw_util_dpp_dft_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->pon_port[i]);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on pon=0x%x, ret = %d\n", p_flow_elm->pon_port[i], ret);
+ break;
+ }
+ }
+
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: fail to add US ACL to pon_%d in flow id %d from the list\n", i, p_flow->key.flow_id);
+ return BCM_ERR_INTERNAL;
+ }
+ }
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " remove packet discard function from PON in flow id %d \n",p_flow->key.flow_id);
+ /* remove the PON ports from DISCARD_XXX mode */
+ for(ii=0; ii<p_flow_elm->num_pon; ii++)
+ {
+ if(p_flow_elm->pon_port[ii] == 0)
+ {
+ /* if PON LIF is deleted, then continue to the next one */
+ continue;
+ }
+ ret = bcm_port_discard_set(p_flow_elm->device, p_flow_elm->pon_port[ii], BCM_PORT_DISCARD_NONE);
+ if (ret != BCM_ERR_OK)
+ {
+ break;
+ }
+ }
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: fail to remove packet discard from pon_%d in flow id %d from the list\n", ii,p_flow->key.flow_id);
+
+ ret = BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ /* add flow type to the exist list */
+ p_flow_elm->type |= flow_type;
+ ret = BCM_ERR_OK;
+ }
+ return ret;
+ }
+ }
+ else /* same id and type is an error - we do not check if contents are the same or not */
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: flow id %d type %d already exist\n",p_flow->key.flow_id, p_flow->key.flow_type);
+ return BCM_ERR_INTERNAL;
+ }
+ }
+
+ /*
+ * First, validate that the specified PON has at least one NNI port on the same device.
+ * If not, return an error, as this is not supported.
+ */
+ ii = 0;
+ ret = BCM_ERR_NOT_SUPPORTED;
+ /* walk through the entire mapping table */
+ while(-1 != bal_bcm_net_inf_pbm_get(ii))
+ {
+ if(bal_bcm_net_inf_dev_get(ii) == unit)
+ {
+ ret = BCM_ERR_OK;
+ break;
+ }
+ ii++; /* Next NNI */
+ }
+
+ do
+ {
+ /*
+ * Check return code from device check above. Return if there was no local PON .
+ */
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: no network port is on the same device as access port %d\n", p_flow->data.access_int_id);
+ break;
+ }
+
+ /* initialize link list flow element */
+ memset(&flow_elm, 0, sizeof (bal_sw_flow));
+ /* fill in the basic info */
+ flow_elm.id = p_flow->key.flow_id;
+ flow_elm.device = unit;
+ flow_elm.type = flow_type;
+ flow_elm.svc_port = p_flow->data.svc_port_id;
+ flow_elm.flow_cookie = p_flow->data.cookie;
+
+ tunnel_id = (bcm_vlan_t)p_flow->data.svc_port_id;
+ pon = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
+
+ /* Map the tunnel ID to a PON channel OTM port */
+ rv = bcm_port_pon_tunnel_map_set(unit,
+ pon,
+ tunnel_id,
+ pon);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, bcm_port_pon_tunnel_map_set on pon %d failed %d"
+ " (have you chosen the correct intf_maptable?)\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* For TRAP to HOST action, it can be either upstream or downsteram,
+ There is no packet manipulation, just insert an ACL and return.
+ For flow action equal TRAP_TO_HOST, DS flow has to use different flow id even if the classifier is the same as the US.
+ This is to simplify the REMOVE/DELETE operation in the switch.
+ */
+ if ((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) &&
+ (p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)
+ )
+ {
+ /* For US, create an in LIF for matching, this allow trapping of different tunnel_id on the same PON.
+ Tunnel_id is stripped before packets are forwarding to the host */
+ if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ if(BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow->data.classifier, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_UNTAGGED);
+ BCM_LOG(WARNING, log_id_sw_util, "Tag Type for Upstream Packet Trapping is not set, default to UNTAGGED\n");
+ }
+
+ bcm_vlan_port_t_init(&vp);
+
+ /* preserve any incoming packet vlan tags */
+ vp.flags = BCM_VLAN_PORT_OUTER_VLAN_PRESERVE | BCM_VLAN_PORT_INNER_VLAN_PRESERVE | BCM_VLAN_PORT_FORWARD_GROUP;
+
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ /* match both tunnel and outer tag on ingress PON */
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* match tunnel and both outer and inner tags on ingress PON */
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN_STACKED;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ default: /* just to make compiler happy */
+ /* match tunnel tag on ingress PON */
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
+ break;
+ }
+
+ vp.port = pon;
+ vp.match_tunnel_value = tunnel_id;
+ vp.egress_tunnel_value = tunnel_id;
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid))
+ {
+ vp.match_vlan = p_flow->data.classifier.o_vid;
+ }
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid))
+ {
+ vp.match_inner_vlan = p_flow->data.classifier.i_vid;
+ }
+ vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
+
+ /* Create the vlan port (i.e., PON LIF) */
+ rv = bcm_vlan_port_create(unit, &vp);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vlan_port_create pon %d failed %d\n", pon, rv);
+ return BCM_ERR_INTERNAL;
+ }
+ ret = bal_sw_util_dpp_acl_add(unit, p_flow, &flow_elm, vp.vlan_port_id, 0);
+ }
+ else
+ {
+ ret = bal_sw_util_dpp_acl_add(unit, p_flow, &flow_elm, 0, 0);
+ }
+
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " ERROR: fail to add %s acl rule on trap\n", (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)? "US":"DS" );
+ }
+ else
+ {
+ ret = bal_sw_util_flow_list_insert(flow_elm);
+ BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d type %d, trap_code 0x%x, eid=%d Success\n", flow_elm.id, flow_elm.type, flow_elm.trap_code, flow_elm.field_entry_id[0]);
+ }
+ return ret;
+ } /* endif TRAP_TO_HOST ACTION */
+
+ /* For TR-156 1:1, single tagged on V and R/S interface.
+ The vswitch will push a tunnel tag on the down stream packets.
+ The vswitch will pop the tunnel tag from the upstream packets.
+
+ TBD For TR-156 1:1, double tagged on V interface and single tagged on R/S interface.
+ The vswitch will replace the outer tag with tunnel tag on the down stream packets.
+ The vswitch will replace the tunnel tag with outer vid on upstream packets.
+
+ For TR-156 N:1, single tagged on V and R/S interface.
+ The vswitch will learn the upstream source MAC for downstream forwarding
+ */
+
+ /* packet tag type and service port id are required fields when there is no action - checked in validation stage */
+ /* Here make sure it is the supported type */
+ if(p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_UNTAGGED &&
+ p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_SINGLE_TAG &&
+ p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: classifier packet tag type 0x%x is invalid\n", p_flow->data.classifier.pkt_tag_type);
+ ret = BCM_ERR_PARM;
+ break;
+ }
+
+ /* create a local reverse flow for symmetry configurations */
+ ret = bal_sw_util_reverse_flow_create(p_flow, &flow_rev);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, (internal failure): fail to reverse flow\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ p_us_flow = p_flow;
+ p_ds_flow = &flow_rev;
+ }
+ else
+ {
+ p_us_flow = &flow_rev;
+ p_ds_flow = p_flow;
+ }
+
+
+ /* create the vswitch */
+ /* if flow is associated with a GROUP, use the vswitch from the GROUP */
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id))
+ {
+ bal_sw_group_list *p_group_list;
+ /* get a pointer to the specified group instance */
+ p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow->data.group_id);
+
+ if ( p_group_list == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: group %d not found\n", p_flow->data.group_id);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* retrieve the vswitch instance */
+ p_vsi_svc = p_group_list->p_vsi;
+ vsi = (p_group_list->p_vsi)->vswitch;
+ /* add flow to the vsi service tag list */
+ ret = bal_sw_util_dpp_vsi_service_tag_add(unit, p_vsi_svc, p_flow, &svc_tag_indx);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, flow fail to add service to vsi service tag list\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* set the mac learning distribution list */
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, resolve_mac) &&
+ BCMOS_TRUE == p_flow->data.resolve_mac)
+ {
+ bcm_l2_addr_distribute_t dist;
+
+ bcm_l2_addr_distribute_t_init(&dist);
+ dist.vid = vsi;
+ dist.flags = BCM_L2_ADDR_DIST_SET_CPU_DMA_DISTRIBUTER | BCM_L2_ADDR_DIST_SET_LEARN_DISTRIBUTER;
+ dist.flags |= BCM_L2_ADDR_DIST_LEARN_EVENT | BCM_L2_ADDR_DIST_AGED_OUT_EVENT | BCM_L2_ADDR_DIST_STATION_MOVE_EVENT;
+ rv = bcm_l2_addr_msg_distribute_set(unit, &dist);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_l2_addr_msg_distribute_set");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* vsi service needs down stream info for in LIF VLAN info */
+ p_vsi_svc = bal_sw_util_dpp_vsi_service_create(unit, p_ds_flow, &svc_tag_indx);
+ if(p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, vsi create failed\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ vsi = p_vsi_svc->vswitch;
+ }
+ /* === create a PON LIF === */
+
+ /* if DS SLA is set, create a VOQ id, otherwise use local port id */
+ /** @note QoS from the Downstream flow config is taken to configure SLA in the switch. Upstream is done in MAC.
+ */
+ if ((p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) && (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla)))
+ {
+ p_service_cfg = bcmos_calloc(sizeof(bal_sw_dpp_qos_service_cfg));
+ if (p_service_cfg == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to alloc a bal_sw_dpp_qos_service_cfg_t\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ p_service_cfg->service_type = BAL_BCM_SVC_TYPE_IP;
+ p_service_cfg->bal_flow_id = p_flow->key.flow_id;
+ p_service_cfg->pon_port = p_flow->data.access_int_id;
+ p_service_cfg->tunnel_id = tunnel_id;
+ /* TBD - channelize port config */
+ p_service_cfg->ds_qos.pon_chan = 0;
+ p_service_cfg->ds_qos.min.rate = p_flow->data.sla.min_rate;
+ /* burst - set it to twice the rate */
+ max_burst = ( (2*p_service_cfg->ds_qos.min.rate) < BAL_MAX_BURST_RATE )? (2*p_service_cfg->ds_qos.min.rate): BAL_MAX_BURST_RATE;
+ p_service_cfg->ds_qos.min.burst = max_burst;
+ /* TBD priority */
+ p_service_cfg->ds_qos.min.traffic_priority = 2;
+
+ p_service_cfg->ds_qos.max.rate = p_flow->data.sla.max_rate - p_flow->data.sla.min_rate;
+ /* burst - set it to twice the rate */
+ max_burst = ( (2*p_service_cfg->ds_qos.max.rate) < BAL_MAX_BURST_RATE )? (2*p_service_cfg->ds_qos.max.rate): BAL_MAX_BURST_RATE;
+ p_service_cfg->ds_qos.max.burst = max_burst;
+ /* TBD priority */
+ p_service_cfg->ds_qos.max.traffic_priority = 2;
+ ret = bal_sw_dpp_llid_qos_config(unit, p_service_cfg);
+ /* Check for errors */
+ if (ret != BCM_ERR_OK)
+ {
+ /* Failure */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "Downstream QoS configuration failed for pon %u tid %u\n",
+ p_flow->data.access_int_id, tunnel_id);
+ break;
+ }
+ BCM_GPORT_UNICAST_QUEUE_GROUP_SET(pon, p_service_cfg->ds_qos.voq_flow_id);
+ sys_pon = p_service_cfg->ds_qos.voq_gport;
+ BCM_LOG(INFO, log_id_sw_util, " use voq_id 0x%x queue group 0x%x, voq_gport 0x%x to create PON LIFT\n", p_service_cfg->ds_qos.voq_flow_id, pon, sys_pon);
+
+ /* clear the VOQ stats here */
+ bal_sw_dpp_qos_clear_voq_stats(unit, sys_pon);
+ }
+ else
+ {
+ sys_pon = pon;
+ BCM_LOG(INFO, log_id_sw_util, " use pp port 0x%x to create PON LIFT\n", pon);
+ }
+
+ /* Configure the switch pon LIF based on classifier in the flow.
+ The pon LIF filter the ingress packets from PON, so use the classifier in the US direction.
+ This means, if the original flow configuration is for Downstream, use the reverse flow that locally created */
+
+ bcm_vlan_port_t_init(&vp);
+
+ /* preserve any incoming packet vlan tags, if vlan actions are required, do it using egress translation */
+ vp.flags = BCM_VLAN_PORT_OUTER_VLAN_PRESERVE | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;
+ /* It is required to set the FEC flag so that the egress redirection action from the DS classification can
+ select the correct PON LIF to forward the packet */
+ vp.flags |= BCM_VLAN_PORT_FORWARD_GROUP;
+
+
+ switch(p_us_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ /* match both tunnel and outer tag on ingress PON */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_pbits))
+ {
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_PCP_VLAN;
+ vp.match_pcp = p_us_flow->data.classifier.o_pbits;
+ }
+ else
+ {
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN;
+ }
+ break;
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* Otherwise match both tunnel and both outer and inner tags on ingress PON */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_pbits))
+ {
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_PCP_VLAN_STACKED;
+ vp.match_pcp = p_us_flow->data.classifier.o_pbits;
+ }
+ else
+ {
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN_STACKED;
+ }
+ break;
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ /* Otherwise match tunnel tag on ingress PON */
+ {
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
+ }
+ break;
+ default:
+ /* should not reach here */
+ BCM_LOG(ERROR, log_id_sw_util, "Error, Unsupported packet type %d for pon LIF\n",p_us_flow->data.classifier.pkt_tag_type );
+ return BCM_ERR_INTERNAL;
+ }
+
+
+ vp.port = pon;
+ vp.match_tunnel_value = tunnel_id;
+ vp.egress_tunnel_value = tunnel_id;
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_vid))
+ {
+ vp.match_vlan = p_us_flow->data.classifier.o_vid;
+ }
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, i_vid))
+ {
+ vp.match_inner_vlan = p_us_flow->data.classifier.i_vid;
+ }
+ vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
+
+ /* Create the vlan port (i.e., PON LIF) */
+ rv = bcm_vlan_port_create(unit, &vp);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vlan_port_create pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ pon_gport = vp.vlan_port_id;
+ /* set pon gport to first element of the array */
+ flow_elm.pon_port[0] = pon_gport;
+
+ /* set PON port DISCARD mode to reflect the flow direction. When two BAL flows with same id and different directions
+ are configured, the DISCARD mode will be set back to NONE */
+ if (flow_elm.type == BAL_SW_FLOW_TYPE_DOWNSTREAM)
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Info, bcm_port_discard_set pon 0x%x to DISCARD_INGRESS\n", pon_gport);
+ rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_INGRESS);
+ }
+ else if (flow_elm.type == BAL_SW_FLOW_TYPE_UPSTREAM)
+ {
+ /* allow bi-direction for N:1 service */
+ if( BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, group_id) &&
+ BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, resolve_mac) &&
+ BCMOS_TRUE == p_us_flow->data.resolve_mac)
+ {
+ rv = BCM_E_NONE;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Info, bcm_port_discard_set pon 0x%x to DISCARD_EGRESS\n", pon_gport);
+ rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_EGRESS);
+ }
+ }
+ else
+ {
+ rv = BCM_E_NONE;
+ }
+
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_discard_set failed %d\n", rv);
+ /* ARAD does not support the DISCARD function as of 6.5.4 */
+#ifdef QAX_SWITCH
+ ret = BCM_ERR_INTERNAL;
+ break;
+#endif
+ }
+
+ // add pon gport to vswitch
+ rv = bcm_vswitch_port_add(unit, vsi, pon_gport);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vswitch_port_add for pon 0x%x failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Info, bcm_vswitch_port_add for pon 0x%x, gport 0x%x\n", pon, pon_gport);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id) &&
+ BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, resolve_mac) &&
+ BCMOS_TRUE == p_flow->data.resolve_mac)
+ {
+ /* for flows that need to resolve mac, don't forward unknown traffics */
+ BCM_LOG(DEBUG, log_id_sw_util, "pon %d:0x%x bypass downstream MC group join\n", pon, pon_gport);
+ }
+ else
+ {
+ // obtain encapsulation ID for legacy reason, used in ADD API */
+ rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->ds_flood_grp_id, sys_pon, pon_gport, &pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for pon failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* join the downstream multicast group as a member of replication list */
+ rv = bcm_multicast_ingress_add(unit, p_vsi_svc->ds_flood_grp_id, sys_pon, pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_add for pon failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* now set the type of packets that goes to the upstream flooding group (offset 0) */
+ rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodUnknownUcastGroup, BAL_DPP_US_FLOOD_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set ucast for pon failed %d\n", rv);
+ }
+ }
+ rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodUnknownMcastGroup, BAL_DPP_US_FLOOD_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set mcast for pon failed %d\n", rv);
+ break;
+ }
+ rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodBroadcastGroup, BAL_DPP_US_FLOOD_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set bcast for pon failed %d\n", rv);
+ break;
+ }
+ /* perform vlan translation on pon port, pon egress info is in the Downstream configuration */
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, action))
+ {
+ ret = bal_sw_util_dpp_invlanx(unit, p_us_flow, pon_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform ingress vlan translation on pon %d\n", pon);
+ break;
+ }
+ ret = bal_sw_util_dpp_evlanx(unit, p_ds_flow, pon_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform egress vlan translation on pon %d\n", pon);
+ break;
+ }
+ }
+ /* === PON LIF created === */
+
+ ii = 0; /* Start with the first NNI logical interface */
+ /* loop through all nni port, add them to vswitch, -1 indicate end of table */
+ /* Configure the switch nni LIF based on classifier in the flow.
+ The nni LIF filter the ingress packets from Network, so use the classifier in the DS direction.
+ This means, if the original flow configuration is for Upstream, use the reverse flow that locally created */
+ while(-1 != (nni = bal_bcm_net_inf_pbm_get(ii)))
+ {
+ /* skip nni port that is not in the same device or not valid */
+ if ( bal_bcm_net_inf_dev_get(ii) != unit ||
+ BCMOS_FALSE == bcm_topo_nni_is_valid(ii))
+ {
+ ii++;
+ continue;
+ }
+
+ /* if nni port is specified in the flow, skip the other nni ports */
+ if ( BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, network_int_id) &&
+ ii != p_ds_flow->data.network_int_id
+ )
+ {
+ ii++;
+ continue;
+ }
+
+ /* create gport based on nni physical port number */
+
+ ret = bal_sw_util_dpp_vsi_service_port_add(unit, p_vsi_svc, svc_tag_indx, nni, &nni_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add nni %d to vsi\n", nni);
+ break;
+ }
+
+ flow_elm.net_port[flow_elm.num_net] = nni_gport;
+ flow_elm.num_net++;
+
+ /* perform vlan translation on nni port, nni egress info is in the Upstream configuration */
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, action))
+ {
+ rv = bcm_vlan_control_port_set(unit, nni_gport, bcmVlanPortTranslateKeyFirst, bcmVlanTranslateKeyPortOuter);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform vlan control port set on nni %d\n", nni);
+ break;
+ }
+ ret = bal_sw_util_dpp_invlanx(unit, p_ds_flow, nni_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform ingress vlan translation on nni %d\n", nni);
+ break;
+ }
+
+ ret = bal_sw_util_dpp_evlanx(unit, p_us_flow, nni_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perfrom egress vlan translation on nni %d\n", nni);
+ break;
+ }
+ }
+ /* if classifier is more than just port + VLAN tags, add ACL rule to re-direct packet to egress port.
+ This bypass the ingress LIF as LIF check VID only.
+ Upstream classification is expected to be done in ONU (onu add GEM based on classifiers for upstream) */
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
+ bal_sw_util_flow_ds_acl_cls_chk(p_ds_flow) == BCMOS_TRUE )
+ {
+ /* add re-direct rule */
+ if( BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, network_int_id))
+ {
+ ret = bal_sw_util_dpp_acl_add(unit, p_ds_flow, &flow_elm, nni_gport, pon_gport);
+ }
+ else /* Rule need to match the network port, otherwise, it will apply to all ports - nni and pon */
+ {
+ BCMBAL_CFG_PROP_SET(p_ds_flow, flow, network_int_id, ii);
+ ret = bal_sw_util_dpp_acl_add(unit, p_ds_flow, &flow_elm, nni_gport, pon_gport);
+ BCMBAL_CFG_PROP_CLEAR(p_ds_flow, flow, network_int_id);
+ }
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on nni %d, ret = %d\n", ret, ii);
+ break;
+ }
+ /* add a dft drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
+ ret = bal_sw_util_dpp_dft_acl_add(unit, p_ds_flow, &flow_elm, nni_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on nni=0x%x, ret = %d\n", nni_gport, ret);
+ break;
+ }
+ }
+ /* If the user needs to perfrom upstream classification (in addition to VID),
+ Add an ACL rule to re-direct packets. The ACL also allow upstream flows to be prioritized based on priority field */
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM &&
+ bal_sw_util_flow_us_acl_cls_chk(p_us_flow) == BCMOS_TRUE &&
+ /* there are issues using traditional API for PON application when egress vlan translation and ingress ACL are both active.
+ Enable the ACL only when there is no vlan action - TBD */
+ BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
+ {
+ /* ACL requires an action, currently support trap or re-direct the flow.
+ TRAP has been handle in other path, here we require user to specify which port to re-direct.
+ Other options will be adding multiple ACL to cover all possible egress ports - TBD */
+ if( BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, network_int_id))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, Upstream classifier in addition to VID without NNI port set is not suppotred\n");
+ break;
+ }
+ else
+ {
+ ret = bal_sw_util_dpp_acl_add(unit, p_us_flow, &flow_elm, pon_gport, nni_gport);
+ }
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on pon %d, ret = %d\n", ret, pon);
+ break;
+ }
+ /* add a default drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
+ ret = bal_sw_util_dpp_dft_acl_add(unit, p_us_flow, &flow_elm, pon_gport);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on pon=0x%x, ret = %d\n", pon_gport, ret);
+ break;
+ }
+ }
+
+ ii++; /* Next NNI */
+ }
+ /* skip the rest if anything goes wrong */
+ if( ret != BCM_ERR_OK)
+ {
+ break;
+ }
+ /* Configure PCP/Cos to Traffic Class mapping. This has to be done after the NNI LIFs are created */
+ if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM && BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla))
+ {
+ p_service_cfg->num_nni_gport = flow_elm.num_net;
+ for( ii = 0; ii < p_service_cfg->num_nni_gport; ii++)
+ {
+ p_service_cfg->nni_gport[ii] = flow_elm.net_port[ii];
+ }
+ ret = bal_sw_dpp_llid_set_qos_port_map(unit, p_service_cfg);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perfrom nni qos port map, ret = %d\n", ret);
+ break;
+ }
+ }
+
+ } while(0);
+
+ if( ret == BCM_ERR_OK)
+ {
+ /* add the flow info to the link list */
+ flow_elm.p_vsi_svc = p_vsi_svc;
+ flow_elm.vsi_svc_indx = svc_tag_indx;
+ flow_elm.num_pon = 1;
+ flow_elm.p_service_cfg = p_service_cfg;
+
+ /* nni ports are done in the nni loop */
+ flow_elm.valid = 1;
+ bal_sw_util_flow_list_insert(flow_elm);
+
+ BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d type %d, vswitch 0x%x, Success\n", flow_elm.id, flow_elm.type, p_vsi_svc->vswitch);
+ }
+ return ret;
+}
+
+
+/**
+ * @brief The internal flow remove function program DPP to release resource that
+ * were allocated during the ADD operation
+ *
+ * @param p_flow_elm a pointer to the internal flow list
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_flow_remove_int(bal_sw_flow *p_flow_elm)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ int rv, i, flow_id;
+ bal_sw_vsi_service *p_vsi_svc;
+ bal_sw_group_list *p_group_list;
+
+ if(p_flow_elm == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " invalid pointer to the internal flow list\n");
+ return BCM_ERR_INTERNAL;
+ }
+ p_vsi_svc = (bal_sw_vsi_service *) p_flow_elm->p_vsi_svc;
+ /* if anything go wrong, log a warning and continue release resources */
+ for(i = 0; i <p_flow_elm->num_pon; i++)
+ {
+ rv = bcm_vswitch_port_delete(p_flow_elm->device, p_vsi_svc->vswitch, p_flow_elm->pon_port[i]);
+ if(rv)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " vswitch pon port 0x%x delete failed %d\n", p_flow_elm->pon_port[i], rv);
+ }
+ rv = bcm_vlan_port_destroy(p_flow_elm->device, p_flow_elm->pon_port[i]);
+ if(rv)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " vswitch pon port 0x%x destroy failed %d\n", p_flow_elm->pon_port[i], rv);
+ }
+ p_flow_elm->pon_port[i] = 0;
+ }
+ p_flow_elm->num_pon = 0;
+
+ for(i = 0; i <p_flow_elm->num_net; i++)
+ {
+ ret = bal_sw_util_dpp_vsi_service_port_rem(p_flow_elm->device, p_flow_elm->p_vsi_svc, p_flow_elm->vsi_svc_indx, p_flow_elm->net_port[i]);
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " vsi service port 0x%x remove failed %d\n", p_flow_elm->net_port[i], ret);
+ }
+
+ p_flow_elm->net_port[i] = 0;
+ }
+ p_flow_elm->num_net = 0;
+
+ /* release vswitch */
+ if (p_vsi_svc)
+ {
+ /* remove the vsi if no more service, destroy function will do the counting */
+ ret = bal_sw_util_dpp_vsi_service_destroy(p_flow_elm->device, p_vsi_svc);
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " vsi service destroy failed %d\n", ret);
+ }
+ }
+ /* decrement the group reference counter in the group list */
+ if (p_flow_elm->group_id)
+ {
+ p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow_elm->group_id);
+ if ( p_group_list == NULL)
+ {
+ BCM_LOG(WARNING, log_id_sw_util,
+ " WARNING: MC flow remove can't find the mc group %d in the list\n", p_flow_elm->group_id);
+ }
+ else
+ {
+ if(p_group_list->use_count)
+ {
+ p_group_list->use_count--;
+ }
+ else
+ {
+ BCM_LOG(WARNING, log_id_sw_util,
+ " WARNING: MC flow remove find the mc group %d in the list has no use_count\n", p_flow_elm->group_id);
+ }
+ }
+ }
+
+ /* relese trap */
+ if (p_flow_elm->trap_code)
+ {
+ rv = bcm_rx_trap_type_destroy(p_flow_elm->device, p_flow_elm->trap_code);
+ if(rv)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " rx trap %d destroy failed %d\n", p_flow_elm->trap_code, rv);
+ }
+ p_flow_elm->trap_code = 0;
+ p_flow_elm->trap_port = 0;
+ }
+
+ /* release acl, if any */
+ for(i = 0; i <p_flow_elm->num_eid; i++)
+ {
+ if (p_flow_elm->field_entry_id[i])
+ {
+ rv = bcm_field_entry_remove(p_flow_elm->device, p_flow_elm->field_entry_id[i]);
+ if(rv)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " field entry %d remove failed %d\n", p_flow_elm->field_entry_id[i], rv);
+ }
+ rv = bcm_field_entry_destroy(p_flow_elm->device, p_flow_elm->field_entry_id[i]);
+ if(rv)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " field entry %d destroy failed %d\n", p_flow_elm->field_entry_id[i], rv);
+ }
+ p_flow_elm->field_entry_id[i] = 0;
+ }
+ }
+ p_flow_elm->num_eid = 0;
+
+ /* release llid qos, if any */
+ if (p_flow_elm->p_service_cfg)
+ {
+ /* any error during cleanup will be reported, but continue anyway */
+ bal_sw_dpp_llid_qos_cleanup(p_flow_elm->device, (bal_sw_dpp_qos_service_cfg *)p_flow_elm->p_service_cfg);
+ bcmos_free(p_flow_elm->p_service_cfg);
+ p_flow_elm->p_service_cfg = NULL;
+ }
+
+ /* remove from the internal link list */
+ flow_id = p_flow_elm->id;
+ ret = bal_sw_util_flow_list_remove(p_flow_elm);
+ if(ret == BCM_ERR_OK)
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d is removed\n", flow_id);
+ ret = BCM_ERR_OK;
+ }
+ else
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " fail to remove flow %d w ret = %d\n", flow_id, ret);
+ ret = BCM_ERR_INTERNAL;
+ }
+ return ret;
+}
+
+/**
+ * @brief The flow remove function program DPP to release resource that
+ * were allocated during the ADD operation
+ *
+ * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
+ * @param p_flow A pointer to the requested add flow info
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_flow_remove(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bal_sw_flow *p_flow_elm;
+ int ii, rv;
+ bcm_port_discard_t discard_type = BCM_PORT_DISCARD_NONE;
+
+ if(p_flow == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " invalid pointer to the bal flow\n");
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* make sure the flow id is in the link list, if not return success anyway (probably clearing a DOWN flow) */
+ p_flow_elm = bal_sw_util_flow_list_get_by_id (p_flow->key.flow_id);
+ if(p_flow_elm == NULL)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, " flow %d not exist the link list\n", p_flow->key.flow_id);
+ return BCM_ERR_OK;
+ }
+
+ /* if flow_elm has the requested direction, set switch to discard packets from the requested direction. */
+ if( (p_flow_elm->type & BAL_SW_FLOW_TYPE_DOWNSTREAM) &&
+ (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)
+ )
+ {
+ discard_type = BCM_PORT_DISCARD_EGRESS;
+ }
+ else if ((p_flow_elm->type & BAL_SW_FLOW_TYPE_UPSTREAM) &&
+ (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ )
+ {
+ discard_type = BCM_PORT_DISCARD_INGRESS;
+ }
+ else if (p_flow_elm->type & BAL_SW_FLOW_TYPE_MULTICAST)
+ {
+ /* clear rhe type so that it can remove the flow below */
+ p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_MULTICAST;
+ }
+
+ if (discard_type != BCM_PORT_DISCARD_NONE)
+ {
+ for(ii=0; ii<p_flow_elm->num_pon; ii++)
+ {
+ if(p_flow_elm->pon_port[ii] == 0)
+ {
+ /* if PON LIF is deleted, then continue to the next pon */
+ continue;
+ }
+ rv = bcm_port_discard_set(p_flow_elm->device, p_flow_elm->pon_port[ii], discard_type);
+ if (rv != BCM_E_NONE)
+ {
+ /* mark an error, but continue */
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_discard_set failed %d on pon 0x%x\n", rv, p_flow_elm->pon_port[ii]);
+ ret = BCM_ERR_INTERNAL;
+ }
+ }
+ if (BCM_ERR_OK == ret)
+ {
+ if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)
+ {
+ p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_DOWNSTREAM;
+ }
+ else if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
+ {
+ p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_UPSTREAM;
+ }
+ BCM_LOG(INFO, log_id_sw_util, " Success remove flow %d with type %d\n", p_flow->key.flow_id, p_flow->key.flow_type);
+ }
+ }
+ /* remove the flow from the list if everything is cleanup */
+ if(BAL_SW_FLOW_TYPE_NONE == p_flow_elm->type)
+ {
+ ret = bal_sw_util_dpp_flow_remove_int(p_flow_elm);
+ }
+
+ return ret;
+}
+
+
+
+/*******************************
+ * Helper routines below
+ *******************************/
+/**
+ * @brief Helper routine to reverse a flow i.e. an upstream flow is made a downstream flow
+ * and vice versa
+ *
+ * @param p_flow A pointer to the original flow
+ * @param p_flow_rev A pointer to the reversed flow
+ * @return error code
+ *
+ * @note for now it assumes an untagged or single tagged vlan flow with single vlan tag classificiation
+ */
+static bcmos_errno bal_sw_util_reverse_flow_create(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_flow_rev)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ if ((p_flow == NULL) || (p_flow_rev == NULL))
+ {
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* reverse parameters in flow */
+ memcpy(p_flow_rev, p_flow, sizeof(bcmbal_flow_cfg));
+
+ p_flow_rev->key.flow_type = (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ?
+ BCMBAL_FLOW_TYPE_DOWNSTREAM : BCMBAL_FLOW_TYPE_UPSTREAM);
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_mac, p_flow->data.classifier.dst_mac);
+ }
+ else /* clear the src_mac presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_mac);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_mac, p_flow->data.classifier.src_mac);
+ }
+ else /* clear the dst_mac presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_mac);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_port, p_flow->data.classifier.dst_port);
+ }
+ else /* clear the src_port presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_port);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_port, p_flow->data.classifier.src_port);
+ }
+ else /* clear the dst_port presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_port);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_ip, p_flow->data.classifier.dst_ip);
+ }
+ else /* clear the src_ip presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_ip);
+ }
+
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_ip, p_flow->data.classifier.src_ip);
+ }
+ else /* clear the dst_ip presence mask in the reverse flow */
+ {
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_ip);
+ }
+
+
+ if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))
+ {
+ BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
+ BCMBAL_ACTION_CMD_ID_SET(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
+
+ /* remove o_vid from action */
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.action, action, o_vid);
+
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ /* ADD on untagged packet result to single tagged on revert direction */
+ p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG;
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, o_vid, p_flow->data.action.o_vid);
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ /* ADD on single tagged packet result to double tagged on revert direction */
+ p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG;
+ p_flow_rev->data.classifier.o_vid = p_flow->data.action.o_vid;
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, i_vid, p_flow->data.classifier.o_vid);
+ break;
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ default:
+ /* should not reach here */
+ break;
+ }
+ }
+ else if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG))
+ {
+ BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
+ BCMBAL_ACTION_CMD_ID_SET(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
+
+ /* add o_vid to action */
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_vid, p_flow->data.classifier.o_vid);
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ /* REMOVE on double tagged packet result to single tagged on revert direction */
+ p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG;
+ p_flow_rev->data.classifier.o_vid = p_flow->data.classifier.i_vid;
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, i_vid);
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ /* REMOVE on single tagged packet result to untagged on revert direction */
+ p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_UNTAGGED;
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, o_vid);
+ break;
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ default:
+ /* should not reach here */
+ break;
+ }
+ /* if the remove classifier has tpid attribute, set it when ADD in reverse direction */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_tpid))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_tpid, p_flow->data.classifier.o_tpid);
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, o_tpid);
+ }
+ }
+ else if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG))
+ {
+ /* swap output vid and classifier parameters */
+ p_flow_rev->data.action.o_vid = p_flow->data.classifier.o_vid;
+ p_flow_rev->data.classifier.o_vid = p_flow->data.action.o_vid;
+ }
+
+ if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS))
+ {
+ /* swap output pbits and classifier parameters */
+ if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
+ {
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_pbits, p_flow->data.classifier.o_pbits);
+ }
+ else
+ {
+ /* if the pbits remark is for packets with any o_pibts, then there is no clear REVERSE operation.
+ Set the reverse to NO pbits action. i.e pbits is a passthrough
+ */
+ BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.action, action, o_pbits);
+ BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS);
+ }
+
+ BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, o_pbits, p_flow->data.action.o_pbits);
+ }
+ //else tbd
+
+
+ return ret;
+}
+
+/**
+ * @brief Helper routine to compare two flows for symmetry
+ *
+ * @param p_flow A pointer to the original flow
+ * @param p_ref_flow A pointer to the reference flow
+ * @return TRUE or FALSE
+ */
+bcmos_bool bal_sw_util_is_symmetry_flows(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_ref_flow)
+{
+ bcmos_bool ret = BCMOS_TRUE;
+
+ /* compare the access interface */
+ if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id) !=
+ BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, access_int_id) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " access interface SET not the same for flow %d\n", p_flow->key.flow_id);
+ ret = BCMOS_FALSE;
+ }
+ else
+ {
+ if( (BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id) || BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, access_int_id)) &&
+ (p_flow->data.access_int_id != p_ref_flow->data.access_int_id) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream access interface %d != %d \n",
+ p_flow->key.flow_id, p_flow->data.access_int_id, p_ref_flow->data.access_int_id );
+ ret = BCMOS_FALSE;
+ }
+ }
+ /* compare the network interface */
+ if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) !=
+ BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, network_int_id) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " network interface SET not the same for flow %d\n", p_flow->key.flow_id);
+ ret = BCMOS_FALSE;
+ }
+ else
+ {
+ if( (BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) ||BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, network_int_id)) &&
+ (p_flow->data.network_int_id != p_ref_flow->data.network_int_id) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream access interface %d != %d \n",
+ p_flow->key.flow_id, p_flow->data.network_int_id, p_ref_flow->data.network_int_id );
+ ret = BCMOS_FALSE;
+ }
+ }
+
+ /* if there is no action for the flow, packet type and VIDs should be the same */
+ /* compare the IPv4 addresses */
+ if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action) &&
+ BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, action))
+ {
+ /* check packet type */
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type) !=
+ BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, pkt_tag_type) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " packet type SET not the same for flow %d\n", p_flow->key.flow_id);
+ ret = BCMOS_FALSE;
+ }
+ else
+ {
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type) &&
+ (p_flow->data.classifier.pkt_tag_type != p_ref_flow->data.classifier.pkt_tag_type) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream packet type %d != %d \n",
+ p_flow->key.flow_id, p_flow->data.classifier.pkt_tag_type, p_ref_flow->data.classifier.pkt_tag_type );
+ ret = BCMOS_FALSE;
+ }
+ }
+
+ /* check the outer VID */
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid) !=
+ BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, o_vid) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " outer vid SET not the same for flow %d\n", p_flow->key.flow_id);
+ ret = BCMOS_FALSE;
+ }
+ else
+ {
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid) &&
+ (p_flow->data.classifier.o_vid != p_ref_flow->data.classifier.o_vid) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream outer vid %d != %d \n",
+ p_flow->key.flow_id, p_flow->data.classifier.o_vid, p_ref_flow->data.classifier.o_vid );
+ ret = BCMOS_FALSE;
+ }
+ }
+ /* check the inner VID */
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid) !=
+ BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, i_vid) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " inner vid SET not the same for flow %d\n", p_flow->key.flow_id);
+ ret = BCMOS_FALSE;
+ }
+ else
+ {
+ if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid) &&
+ (p_flow->data.classifier.i_vid != p_ref_flow->data.classifier.i_vid) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream inner vid %d != %d \n",
+ p_flow->key.flow_id, p_flow->data.classifier.i_vid, p_ref_flow->data.classifier.i_vid );
+ ret = BCMOS_FALSE;
+ }
+ }
+
+ }
+ else /* if there is an action - action for VID must be symmetrical */
+ {
+ if(BCMOS_TRUE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG) &&
+ BCMOS_FALSE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) )
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream outer vlan action not symmetrical \n", p_flow->key.flow_id );
+ ret = BCMOS_FALSE;
+ }
+ if(BCMOS_TRUE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) &&
+ BCMOS_FALSE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d upstream/downstream outer vlan action not symmetrical \n", p_flow->key.flow_id );
+ ret = BCMOS_FALSE;
+ }
+ if(BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG) !=
+ BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG))
+ {
+ BCM_LOG(INFO, log_id_sw_util, " flow %d upstream/downstream outer vlan translation not symmetrical \n", p_flow->key.flow_id );
+ ret = BCMOS_FALSE;
+ }
+
+ }
+
+ return ret;
+}
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+
+/*@}*/
+
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_flow.h b/bal_release/src/core/util/switch/dpp/bal_dpp_flow.h
new file mode 100755
index 0000000..09bd8e5
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_flow.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_flow.h
+ *
+ * @brief Function Prototype for switch app flow functions for DPP
+ *
+ * @ingroup switch_app
+ */
+
+#ifndef _BAL_DPP_FLOW_H_
+#define _BAL_DPP_FLOW_H_
+
+#include "bal_switch_util.h"
+#include "bal_switch_flow.h"
+
+/*@{*/
+
+bcmos_errno bal_sw_util_dpp_flow_add(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow);
+bcmos_errno bal_sw_util_dpp_flow_remove(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow);
+bcmos_errno bal_sw_util_dpp_flow_remove_int(bal_sw_flow *p_flow_elm);
+void bal_sw_util_dpp_flow_init(void);
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_group.c b/bal_release/src/core/util/switch/dpp/bal_dpp_group.c
new file mode 100644
index 0000000..05894fd
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_group.c
@@ -0,0 +1,706 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+ /**
+ * @file bal_dpp_group.c
+ * @brief BAL Switch util helper functions that handle group requests
+ * @addtogroup sw_util
+ */
+
+/*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include <bal_utils_msg.h>
+#include "bcmos_errno.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/types.h>
+#include <sal/core/libc.h>
+#ifndef sal_memset
+#define sal_memset memset
+#endif
+#include <bcm/port.h>
+#include <bcm/vlan.h>
+#include <bcm/error.h>
+#include <bcm/multicast.h>
+
+#include "bal_dpp_group.h"
+#include "bal_switch_acc_term.h"
+#include "bal_dpp_vswitch.h"
+
+
+
+/* A local link list to keep track of group list */
+TAILQ_HEAD(bal_sw_group_list_head, bal_sw_group_list) g_swutil_group_list;
+
+/**
+ * @brief The group list init function prepare a link list to keep track of
+ * multicast group in the switch util
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_group_list_init(void)
+{
+ TAILQ_INIT(&g_swutil_group_list);
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The group list finish function release all resources allocated in the list
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_group_list_finish(void)
+{
+ bal_sw_group_list *current_entry, *p_temp_entry;
+
+ /* Free all the entries in the list */
+ TAILQ_FOREACH_SAFE(current_entry,
+ &g_swutil_group_list,
+ next_grp,
+ p_temp_entry)
+ {
+ /* Remove it from the list */
+ TAILQ_REMOVE(&g_swutil_group_list, current_entry, next_grp);
+
+ bcmos_free(current_entry);
+ }
+
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The group list search function by BAL group id
+ *
+ * @param grp_id the group id that need to match the entry in the list
+ * @return pointer to an element in the list, NULL if search failed
+ */
+bal_sw_group_list *bal_sw_util_dpp_group_list_get_by_id(uint32_t grp_id)
+{
+ bal_sw_group_list *p_entry, *p_temp;
+
+ TAILQ_FOREACH_SAFE(p_entry, &g_swutil_group_list, next_grp, p_temp)
+ {
+ if( p_entry->bal_grp_id == grp_id)
+ {
+ break;
+ }
+ }
+ /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
+ return p_entry;
+
+}
+
+/*
+ * @brief The group list insert function
+ *
+ * @param entry the group element to be added in the link list
+ * @return pointer to the newly inserted group in the list, NULL if operation failed
+*/
+static bal_sw_group_list *bal_sw_util_group_list_insert(bal_sw_group_list entry)
+{
+ bal_sw_group_list *p_new_entry;
+
+ p_new_entry = bcmos_calloc(sizeof(bal_sw_group_list));
+ if(NULL == p_new_entry)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "GROUP list insert out of memory\n");
+ return NULL;
+ }
+ *p_new_entry = entry;
+ TAILQ_INSERT_TAIL(&g_swutil_group_list, p_new_entry, next_grp);
+ return p_new_entry;
+}
+
+/*
+ * @brief The group list remove function
+ *
+ * @param p_entry Pointer to the group element in the link list result from the search functions
+ * @return error code
+*/
+static bcmos_errno bal_sw_util_group_list_remove(bal_sw_group_list *p_entry)
+{
+ TAILQ_REMOVE(&g_swutil_group_list, p_entry, next_grp);
+ bcmos_free(p_entry);
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The group list membership check function by port
+ * Validate if interface/svervice_port is already a member
+ *
+ * @param p_grp_port the interface that need to be matched in the list
+ * @param p_entry pointer to an entry in the group list
+ * @return index to the port member, -1 if not found
+ */
+static int bal_sw_util_dpp_group_list_membership_check(bal_sw_group_list *p_entry, bal_sw_group_port *p_grp_port)
+{
+ int i;
+
+ if(p_entry == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group membership check with NULL parameter\n");
+ return BCMOS_FALSE;
+ }
+
+ for(i=0; i<p_entry->num_port; i++)
+ {
+ if(p_entry->port[i].port == p_grp_port->port &&
+ p_entry->port[i].svc_port == p_grp_port->svc_port)
+ {
+ p_grp_port->gport = p_entry->port[i].gport;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/**
+ * @brief The group list membership remove function by port
+ * remove interface/svervice_port from the group membership
+ *
+ * @param grp_port the interface that need to be matched in the list
+ * @param p_entry pointer to an entry in the group list
+ * @return boolen TRUE or FALSE
+ */
+static bcmos_bool bal_sw_util_dpp_group_list_membership_rem(bal_sw_group_list *p_entry, bal_sw_group_port grp_port)
+{
+ int i, rv;
+
+ if(p_entry == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group membership remove with NULL parameter\n");
+ return BCMOS_FALSE;
+ }
+
+ for(i=0; i<p_entry->num_port; i++)
+ {
+ if(p_entry->port[i].port == grp_port.port &&
+ p_entry->port[i].svc_port == grp_port.svc_port)
+ {
+ /* destroy the vlan port (i.e., PON LIF) */
+ if(p_entry->port[i].gport)
+ {
+ rv = bcm_vlan_port_destroy(p_entry->device, p_entry->port[i].gport);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "Warning, GROUP:bcm_vlan_port_destroy pon %d failed %d\n", p_entry->port[i].gport, rv);
+ /* Likely a bug in the 6.5.4 release, ignore for now
+ return BCMOS_FALSE;
+ */
+ }
+ p_entry->port[i].gport = 0;
+ }
+ break;
+ }
+ }
+
+ /* if can't find the port, just return OK */
+ if(i != p_entry->num_port)
+ {
+ /* pack the list */
+ bal_sw_group_port null_port={0};
+ for(; i<p_entry->num_port-1; i++)
+ {
+ p_entry->port[i] = p_entry->port[i+1];
+ }
+ p_entry->port[i] = null_port;
+ p_entry->num_port--;
+ }
+
+ return BCMOS_TRUE;
+}
+
+
+/**
+ * @brief The group create function create a multicast group that contains egress LIF.
+ * This group can later connects to virtual switch in multiple FLOWs.
+ *
+ * The pointer of the created group will be returned
+ *
+ * @param unit switch device id
+ * @param p_grp a pointer to the multicast group definition
+ *
+ * @return pointer to the group list entry, NULL if operation failed
+ */
+
+bal_sw_group_list *bal_sw_util_dpp_group_create(int unit, bcmbal_group_cfg *p_grp)
+{
+ bal_sw_group_list *p_grp_list, grp_list_elm;
+ int32_t multicast_id;
+ uint32_t svc_indx;
+ int rv, flags;
+ bal_sw_vsi_service *p_vsi_service;
+
+ if(p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group create with NULL parameter\n");
+ return NULL;
+ }
+ /* check group list */
+ p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
+ if(p_grp_list)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group create with group id %d already existed\n", p_grp->key.group_id);
+ return NULL;
+ }
+ /* alloc an entry in the group list*/
+ memset(&grp_list_elm, 0, sizeof(bal_sw_group_list));
+ grp_list_elm.device = unit;
+ grp_list_elm.bal_grp_id = p_grp->key.group_id;
+ p_grp_list = bal_sw_util_group_list_insert(grp_list_elm);
+ if(p_grp_list == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group create failed insert to group list\n");
+ return NULL;
+ }
+
+ /* create a vswitch with empty service, we need vsi to create the MC flooding group for egress */
+ p_vsi_service = bal_sw_util_dpp_vsi_service_create(unit, NULL, &svc_indx);
+ if(NULL == p_vsi_service)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "create vsi service for group failed \n");
+ bal_sw_util_group_list_remove(p_grp_list);
+ return NULL;
+ }
+
+ p_grp_list->p_vsi = p_vsi_service;
+
+ multicast_id = p_vsi_service->vswitch + BAL_DPP_MC_OFFSET;
+
+ rv = bcm_multicast_group_is_free(unit, multicast_id);
+ if (rv == BCM_E_EXISTS)
+ {
+ rv = bcm_multicast_destroy(unit, multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "MC: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
+ bal_sw_util_group_list_remove(p_grp_list);
+ return NULL;
+ }
+ }
+ flags = BCM_MULTICAST_INGRESS_GROUP | BCM_MULTICAST_WITH_ID | BCM_MULTICAST_TYPE_L2;
+ rv = bcm_multicast_create(unit, flags, &multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "MC: in bcm_multicast_create 0x%x w ingress failed %d \n", multicast_id, rv);
+ bal_sw_util_group_list_remove(p_grp_list);
+
+ return NULL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "MC: vswitch flood group 0x%x created\n", multicast_id);
+ }
+
+ /* update the group list info */
+ p_grp_list->l2_grp_id = multicast_id;
+ return p_grp_list;
+}
+
+/**
+ * @brief The group add function add members to the multicast group.
+ * In this function, gourp members are PON interfaces
+ *
+ * @param unit switch device id
+ * @param p_grp a pointer to the multicast group definition
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_group_add(int unit, bcmbal_group_cfg *p_grp)
+{
+ bal_sw_group_list *p_grp_list;
+ int i, pon, rv, indx;
+ bcm_gport_t pon_gport;
+ bcmos_errno ret;
+ int pon_encap_id;
+ bcm_vlan_port_t vp;
+ uint32_t flood_grp;
+
+ if(p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group add with NULL parameter\n");
+ return BCM_ERR_PARM;
+ }
+ /* check if L2 group has been created */
+ p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
+ if(!p_grp_list)
+ {
+ BCM_LOG(INFO, log_id_sw_util, "group add will alloc a L2 MC group, group id %d \n", p_grp->key.group_id);
+ p_grp_list = bal_sw_util_dpp_group_create(unit, p_grp);
+ if(p_grp_list == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group add failed create L2 Mc group\n");
+ return BCM_ERR_NORES;
+ }
+ }
+
+
+ ret = BCM_ERR_OK;
+
+ for(i=0; i<p_grp->data.members.len; i++)
+ {
+ bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
+ bal_sw_group_port port_member;
+
+ /* find the L2 logical interface number */
+ pon = bal_bcm_pon_inf_pbm_get(p_member->intf_id);
+
+ /* check if interface is already a member in the group list */
+ port_member.port = pon;
+ port_member.svc_port = p_member->svc_port_id;
+ if( -1 != bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member))
+ {
+ BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d already a member\n",p_member->intf_id, p_member->svc_port_id);
+ continue;
+ }
+
+ /* check if interface already has an entry in the group list */
+ port_member.port = pon;
+ port_member.svc_port = 0;
+ indx = bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member);
+ if( -1 == indx)
+ {
+ /* make sure there is still room in the group list for new member */
+ if(p_grp_list->num_port >= MAX_PON_PORT)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, GROUP: Reach maximum number of membership in the group list\n");
+ ret = BCM_ERR_NORES;
+ break;
+ }
+ }
+ /* if group has a owner, create a LIF for each member */
+ if(p_grp->data.owner != BCMBAL_GROUP_OWNER_NONE)
+ {
+ /* Map the tunnel ID to a PON channel OTM port */
+ rv = bcm_port_pon_tunnel_map_set(unit,
+ pon,
+ p_member->svc_port_id,
+ pon);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Error, GROUP:bcm_port_pon_tunnel_map_set on pon %d failed %d"
+ " (have you chosen the correct intf_maptable?)\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Create the pon LIF to be DS only */
+ bcm_vlan_port_t_init(&vp);
+
+ /* preserve any incoming packet vlan tags, if vlan actions are required, do it using egress translation */
+ vp.flags = BCM_VLAN_PORT_OUTER_VLAN_PRESERVE | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;
+ /* It is required to set the FEC flag so that the egress redirection action from the DS classification can
+ select the correct PON LIF to forward the packet */
+ vp.flags |= BCM_VLAN_PORT_FORWARD_GROUP;
+
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
+
+ vp.port = pon;
+ vp.match_tunnel_value = p_member->svc_port_id;
+ vp.egress_tunnel_value = p_member->svc_port_id;
+
+ vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
+
+ /* Create the vlan port (i.e., PON LIF) */
+ rv = bcm_vlan_port_create(unit, &vp);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_port_create pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "Info, GROUP:bcm_vlan_port_create pon %d with tunnel %d success\n", pon, p_member->svc_port_id);
+ }
+
+ pon_gport = vp.vlan_port_id;
+ rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_INGRESS);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_port_discard_set on pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* select the flooding group */
+ if(p_grp->data.owner == BCMBAL_GROUP_OWNER_MULTICAST)
+ {
+ flood_grp = p_grp_list->l2_grp_id;
+ }
+ else
+ {
+ flood_grp = (p_grp_list->p_vsi)->ds_flood_grp_id;
+ }
+ /* join the L2 multicast group */
+ rv = bcm_multicast_vlan_encap_get(unit, flood_grp, pon, pon_gport, &pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ rv = bcm_multicast_ingress_add(unit, flood_grp, pon, pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_add on pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ BCM_LOG(INFO, log_id_sw_util, "Info, GROUP:pon %d join l2 mc group 0x%x success\n", pon, flood_grp);
+ /* update the group list membership */
+ port_member.gport = pon_gport;
+ }
+ else
+ {
+ port_member.gport = 0;
+ }
+ p_grp_list->port[p_grp_list->num_port] = port_member;
+ p_grp_list->num_port++;
+
+ }
+
+
+ return ret;
+}
+
+
+/**
+ * @brief The group remove function remove members from the multicast group.
+ * In this function, group members are PON interfaces
+ *
+ * @param unit switch device id
+ * @param p_grp a pointer to the multicast group definition
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_group_rem(int unit, bcmbal_group_cfg *p_grp)
+{
+ bal_sw_group_list *p_grp_list;
+ int i, pon, rv;
+ bcmos_errno ret;
+ int pon_encap_id;
+
+ if(p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group remove with NULL parameter\n");
+ return BCM_ERR_PARM;
+ }
+ /* check if L2 group has been created */
+ p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
+ if(!p_grp_list)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group remove can not find L2 Mc group %d\n", p_grp->key.group_id);
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* remove LIF for each member */
+ ret = BCM_ERR_OK;
+ for(i=0; i<p_grp->data.members.len; i++)
+ {
+ bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
+ bal_sw_group_port port_member;
+
+ /* find the L2 logical interface number */
+ pon = bal_bcm_pon_inf_pbm_get(p_member->intf_id);
+
+ /* check if interface is already removed from the group list */
+ port_member.port = pon;
+ port_member.svc_port = p_member->svc_port_id;
+ if( -1 == bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member))
+ {
+ BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d is not a member\n",p_member->intf_id, p_member->svc_port_id);
+ continue;
+ }
+
+ /* if the member has a LIF assigned, remove it from the switch multicast group */
+ if(port_member.gport)
+ {
+ /* leave the L2 multicast group */
+ rv = bcm_multicast_vlan_encap_get(unit, p_grp_list->l2_grp_id, pon, port_member.gport, &pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ rv = bcm_multicast_ingress_delete(unit, p_grp_list->l2_grp_id, pon, pon_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_delete on pon %d failed %d\n", pon, rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ if( BCMOS_FALSE == bal_sw_util_dpp_group_list_membership_rem(p_grp_list, port_member))
+ {
+ BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d membership remove failed\n",p_member->intf_id, p_member->svc_port_id);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief The group set function replace members from the multicast group.
+ * In this function, group members are PON interfaces
+ *
+ * @param unit switch device id
+ * @param p_grp a pointer to the multicast group definition
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_group_set(int unit, bcmbal_group_cfg *p_grp)
+{
+ bal_sw_group_list *p_grp_list;
+ bcmos_errno ret = BCM_ERR_OK;
+ int pon_encap_id;
+
+ if(p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group replace with NULL parameter\n");
+ return BCM_ERR_PARM;
+ }
+ /* check if L2 group has been created */
+ p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
+ if(!p_grp_list)
+ {
+ /* mark it OK to create group at the end */
+ ret = BCM_ERR_OK;
+ }
+ else if(p_grp_list->num_port)
+ {
+ /* remove all members from the group */
+ do
+ {
+ if( p_grp_list->port[0].gport)
+ {
+ /* leave the L2 multicast group */
+ if (BCM_E_NONE != bcm_multicast_vlan_encap_get(unit, p_grp_list->l2_grp_id, p_grp_list->port[0].port, p_grp_list->port[0].gport, &pon_encap_id))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed\n", p_grp_list->port[0].port);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ if (BCM_E_NONE != bcm_multicast_ingress_delete(unit, p_grp_list->l2_grp_id, p_grp_list->port[0].port, pon_encap_id))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_delete on pon %d failed\n", p_grp_list->port[0].port);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ if( BCMOS_FALSE == bal_sw_util_dpp_group_list_membership_rem(p_grp_list, p_grp_list->port[0]))
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group set fail to remove existing member interface %d\n",p_grp_list->port[0].port );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }while(p_grp_list->num_port);
+ }
+
+ if(ret == BCM_ERR_OK)
+ {
+ /* create/add the group */
+ return bal_sw_util_dpp_group_add(unit, p_grp);
+ }
+ return ret;
+}
+
+/**
+ * @brief The group destroy function free up a multicast group.
+ * The group will be removed from the group list.
+ * All L2 resources accociated with the group will be free.
+ *
+ * @param unit switch device id
+ * @param p_grp a pointer to the multicast group definition
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_group_destroy(int unit, bcmbal_group_cfg *p_grp)
+{
+ bal_sw_group_list *p_grp_list;
+ int rv;
+ bcmos_errno ret;
+
+ if(p_grp == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "group destroy with NULL parameter\n");
+ return BCM_ERR_PARM;
+ }
+ /* check group list */
+ p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
+ if(!p_grp_list)
+ {
+ BCM_LOG(INFO, log_id_sw_util, "group destroy with group id %d does not existed\n", p_grp->key.group_id);
+ return BCM_ERR_OK;
+ }
+ /* can't destroy if any flow is still reference it */
+ if(p_grp_list->use_count)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "group destroy with group id %d is busy\n", p_grp->key.group_id);
+ return BCM_ERR_INVALID_OP;
+ }
+
+ /* Do our best to clean up */
+ /* free resources used by all members */
+ ret = bal_sw_util_dpp_group_rem(unit, p_grp);
+ if (ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "MC: destroy group 0x%x failed to free members \n", p_grp_list->l2_grp_id);
+ }
+
+ /* free the L2 multicast group */
+ rv = bcm_multicast_destroy(unit, p_grp_list->l2_grp_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "MC: in bcm_multicast_destroy 0x%x failed %d \n", p_grp_list->l2_grp_id, rv);
+ }
+
+ /* clean up the vsi */
+ bal_sw_util_dpp_vsi_service_destroy(unit, p_grp_list->p_vsi);
+ /* remove from the list */
+ bal_sw_util_group_list_remove(p_grp_list);
+
+ return BCM_ERR_OK;
+}
+
+#endif /* LOOPBACK */
+/*@}*/
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_group.h b/bal_release/src/core/util/switch/dpp/bal_dpp_group.h
new file mode 100644
index 0000000..9d557fe
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_group.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+ /**
+ * @file bal_dpp_group.h
+ * @brief BAL Switch util helper functions prototype
+ * @addtogroup sw_util
+ */
+#ifndef _BAL_DPP_GROUP_H_
+#define _BAL_DPP_GROUP_H_
+
+#include "bal_dpp_vswitch.h"
+#include "bal_switch_util.h"
+
+/*@{*/
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+typedef struct bal_sw_group_port bal_sw_group_port;
+struct bal_sw_group_port
+{
+ uint32_t port; /* group member physical port number */
+ uint32_t gport; /* group member gport id, i.e resource reference in the switch */
+ uint32_t svc_port; /* group member GEM id, in the PON world */
+};
+
+
+typedef struct bal_sw_group_list bal_sw_group_list;
+struct bal_sw_group_list
+{
+ uint32_t device; /* switch device id where the group applied */
+ uint32_t bal_grp_id; /* id reference in BAL */
+ uint32_t num_port; /* number of the member */
+ bal_sw_group_port port[MAX_PON_PORT]; /* member info structure */
+ uint32_t l2_grp_id; /* multicast id in L2 table */
+ uint32_t use_count; /* number of flows that reference this group */
+ bal_sw_vsi_service *p_vsi; /* vswitch service used by this GROUP */
+ TAILQ_ENTRY(bal_sw_group_list) next_grp;
+};
+
+
+extern bcmos_errno bal_sw_util_dpp_group_list_init(void);
+extern bcmos_errno bal_sw_util_dpp_group_list_finish(void);
+extern bal_sw_group_list *bal_sw_util_dpp_group_list_get_by_id(uint32_t grp_id);
+extern bal_sw_group_list *bal_sw_util_dpp_group_create(int unit, bcmbal_group_cfg *p_grp);
+extern bcmos_errno bal_sw_util_dpp_group_destroy(int unit, bcmbal_group_cfg *p_grp);
+extern bcmos_errno bal_sw_util_dpp_group_set(int unit, bcmbal_group_cfg *p_grp);
+extern bcmos_errno bal_sw_util_dpp_group_rem(int unit, bcmbal_group_cfg *p_grp);
+extern bcmos_errno bal_sw_util_dpp_group_add(int unit, bcmbal_group_cfg *p_grp);
+
+#endif /* TEST_SW_UTIL_LOOPBACK */
+/*@}*/
+#endif
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_interface.c b/bal_release/src/core/util/switch/dpp/bal_dpp_interface.c
new file mode 100644
index 0000000..f1433a3
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_interface.c
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#include <bal_common.h>
+#include <bal_core.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_acc_term.h"
+#include "bal_switch_util.h"
+#include "bal_dpp_interface.h"
+
+#include <bcm/types.h>
+#include <bcm/port.h>
+
+/**
+ * @file bal_dpp_interface.c
+ * @brief BAL Switch util functions that handle interface requests on DUNE PACKET PROCESSOR
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+
+
+/**
+ * @brief Set up pon interface with DPP
+ *
+ * This routine is called by sw_util_interface_set in the BAL core
+ * to execute DPP specific API for pon interface request
+ *
+ * @param p_interface_inst Pointer to interface instance
+ * @param opt_type UP/DOWN/RESTART the interface
+ * @return bcmos_errno
+ */
+bcmos_errno bal_sw_util_dpp_interface_set(acc_term_interface *p_interface_inst, bal_util_oper_if opt_type )
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ int rc = 0;
+ bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
+ int unit, port;
+
+ BCM_LOG(INFO, log_id_sw_util, " DPP - Got a interface SET: intf_type: %s, intf_id: %d, opt_type: %s\n",
+ (intf_key.intf_type == BCMBAL_INTF_TYPE_PON ? "PON":"NNI"),
+ intf_key.intf_id,
+ (opt_type == BAL_UTIL_OPER_IF_DOWN ? "DOWN":"UP"));
+
+ /* based on interface type get the device number and physical port number from associated table */
+ switch(intf_key.intf_type)
+ {
+ case BCMBAL_INTF_TYPE_PON:
+ unit = bal_bcm_pon_inf_dev_get(intf_key.intf_id);
+ port = bal_bcm_pon_inf_pbm_get(intf_key.intf_id);
+ break;
+ case BCMBAL_INTF_TYPE_NNI:
+ unit = bal_bcm_net_inf_dev_get(intf_key.intf_id);
+ port = bal_bcm_net_inf_pbm_get(intf_key.intf_id);
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_sw_util, "Error, Unrecognized interface type %d\n", intf_key.intf_type);
+ return BCM_ERR_INTERNAL;
+ break;
+ }
+
+ switch (opt_type)
+ {
+ case BAL_UTIL_OPER_IF_DOWN:
+ rc = bcm_port_enable_set(unit, port, 0);
+ break;
+ case BAL_UTIL_OPER_IF_UP:
+ default:
+ /* disable */
+ rc = bcm_port_enable_set(unit, port, 0);
+ /* sleep 300 ms */
+ usleep(300000);
+ /* enable */
+ rc = bcm_port_enable_set(unit, port, 1);
+ /* Enable auto-negotiation if necessary */
+ if (intf_key.intf_type == BCMBAL_INTF_TYPE_NNI &&
+ bcmbal_is_nni_autoneg_on(intf_key.intf_id))
+ {
+ /* sleep 400 ms */
+ usleep(400000);
+ rc = rc ? rc : bcm_port_autoneg_set(unit, port, 1);
+ BCM_LOG(INFO, log_id_sw_util, "Enabled autoneg on NNI unit:port %d:%d. rc=%d\n", unit, port, rc);
+ }
+ break;
+ }
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_enable_set for pon failed %d\n", rc);
+ ret = BCM_ERR_INTERNAL;
+ }
+ return ret;
+}
+
+/*@}*/
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_interface.h b/bal_release/src/core/util/switch/dpp/bal_dpp_interface.h
new file mode 100644
index 0000000..36ae5f5
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_interface.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_interface.h
+ *
+ * @brief Function Prototype for switch app interface functions for DPP
+ *
+ * @ingroup switch_app
+ */
+
+#ifndef _BAL_DPP_INTERFACE_H_
+#define _BAL_DPP_INTERFACE_H_
+
+#include "bal_switch_util.h"
+
+/*@{*/
+
+extern bcmos_errno bal_sw_util_dpp_interface_set(acc_term_interface *p_interface_inst,
+ bal_util_oper_if opt_type);
+
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_qos.c b/bal_release/src/core/util/switch/dpp/bal_dpp_qos.c
new file mode 100644
index 0000000..d667f2e
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_qos.c
@@ -0,0 +1,2390 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_qos.c
+ * @brief BAL Switch Util QoS configuration API
+ *
+ * This file contains the data structures and functions for
+ * configuring and managing Quality of Service (QoS) for services on
+ * DUNE Pack Processor (DPP).
+ *
+ * The scheduler setup is presented below. In addition to setting up
+ * the scheduling elements (SEs), the BAL_DPP_QOS configures an egress
+ * port shaper on each PON-side port, as well as a per-Access Link (GEMID/LLID)
+ * shaper to implement the downstream SLA for the subscriber service.
+ *
+ * Currently the BAL_DPP_QOS configures downstream QoS only (over the
+ * PON). Maple PON Link SLAs are used to implement upstream SLAs for
+ * the subscriber service in the BAL+Maple+DPP
+ * architecture. Additional upstream QoS for TM within DPP (over the
+ * NNIs) are considered an OEM System vendor responsibility. No
+ * implementation for upstream QoS is provided by the BAL_DPP_QOS.
+ *
+ *
+ * ********************************************************************************
+ *
+ */
+
+/*@{*/
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#define BCM_PETRA_SUPPORT 1 /* TBD - this should be define in the Makefile of the ~/dpp directory */
+#define LINK_ARAD_LIBRARIES 1 /* SDK Make.config - BCM_88650_A0 */
+#define LINK_PPD_LIBRARIES 1 /* SDK Make.config - BCM_88650_A0 */
+#define INCLUDE_L3 1 /* bcm/l3.h support */
+
+#include <stdint.h> /* for compiler defined int64_t and uint64_t */
+
+#include "phymod_custom_config.h" /* resolve PHYMOD_xxx in phymod_system.h */
+#include "bcm/debug.h"
+#include "bcm/error.h"
+#include "bcm/l2.h"
+#include "bcm/mpls.h"
+#include "bcm/qos.h"
+#include "bcm/vlan.h"
+#include "bcm/vswitch.h"
+#include <soc/mcm/allenum.h>
+#include "bcm/field.h"
+#include <bcm/cosq.h>
+#include <bcm/stack.h>
+#include <bcm_int/dpp/alloc_mngr.h>
+#include <bcm_int/dpp/qos.h>
+#include <bcm_int/dpp/error.h>
+#include <bcm_int/dpp/utils.h>
+#include <bcm_int/dpp/qos.h>
+#include <soc/dpp/PPD/ppd_api_eg_vlan_edit.h>
+
+#include "bcm_dev_log.h"
+#include "bcmos_errno.h"
+#include "bal_switch_acc_term.h"
+#include "bal_switch_flow.h"
+#include "bal_switch_util.h"
+#include "bal_dpp_qos.h"
+
+/** @brief A global QoS configuration context */
+bal_sw_qos_cfg g_bal_bcm_qos_cfg = {0};
+
+/** @brief Pointer to global QoS configuration context */
+bal_sw_qos_cfg *gp_bal_bcm_qos_cfg = &g_bal_bcm_qos_cfg;
+
+/**
+ * @brief Number of traffic classes
+ */
+#define BAL_BCM_QOS_TC_NUM 8
+
+/**
+ * @brief PCP/CoS mapping to internal Traffic Class (TC)
+ *
+ * The mapping is as follows, where TC 0 maps to the lowest priority
+ * and TC 3 maps to the highest priority.
+ *
+ * PCP/DEI TC
+ * ------- --
+ * 0/0 0
+ * 0/1 0
+ * 1/0 0
+ * 1/1 0
+ * 2/0 1
+ * 2/1 1
+ * 3/0 1
+ * 3/1 1
+ * 4/0 2
+ * 4/1 2
+ * 5/0 2
+ * 5/1 2
+ * 6/0 3
+ * 6/1 3
+ * 7/0 3
+ * 7/1 3
+ *
+ * PCP values: 0 1 2 3 4 5 6 7
+ */
+const int g_bal_bcm_qos_tc_map[BAL_BCM_QOS_TC_NUM] = {0, 0, 1, 1, 2, 2, 3, 3};
+
+/**************************************************************************/
+/**
+ // * @brief Initialize the QOS Flow/VOQ ID resource pool
+ *
+ * This function initializes the QOS Flow/VOQ ID resource pool, which
+ * consists of an attribute representing the next ID value to allocate
+ * and a table containing free voq ID values.
+ *
+ * The BAL_DPP_QOS assumes four queues are assigned to each access port (GEMID/LLID) in
+ * the downstream direction. Four queues per access port is the smallest
+ * value of queues per access port supported by the DPP device.
+ *
+ * Note, in the BAL_DPP_QOS, the qos Flow and VOQ ID are set to the
+ * same value.
+ *
+ * @param p_pool Pointer to a voq ID pool
+ * @param init_value The initial value to use during voq ID allocation
+ * @param max_value The maximum value assigned by this pool
+ *
+ **************************************************************************/
+static void bal_sw_dpp_init_flow_id_pool(bal_sw_dpp_qos_flowid_pool *p_pool, uint32_t init_value, uint32_t max_value)
+{
+ /* Parameter checks */
+ BUG_ON(p_pool == NULL);
+
+ /* Initialize the data structure */
+ memset(p_pool, 0, sizeof(bal_sw_dpp_qos_flowid_pool));
+
+ /* Store the first value to be used as the voq ID */
+ p_pool->next_flow_id_value = init_value;
+
+ /* Store the maximum value assigned by the pool */
+ p_pool->max_value = max_value;
+
+ /* Initialize the free pool table */
+ TAILQ_INIT(&p_pool->free_table);
+}
+
+/**************************************************************************/
+/**
+ * @brief Clean up the qos Flow/VOQ ID resource pool
+ *
+ * This function cleans up the qos Flow/VOQ ID resource pool. It frees all
+ * of the memory used for bal_sw_dpp_qos_flowid_pool_entry_t's
+ *
+ * @param p_pool Pointer to a voq ID pool
+ *
+ **************************************************************************/
+static void bal_sw_dpp_cleanup_flow_id_pool(bal_sw_dpp_qos_flowid_pool *p_pool)
+{
+ bal_sw_dpp_qos_flowid_pool_entry *p_pool_entry = NULL;
+
+ /* Parameter checks */
+ BUG_ON(p_pool == NULL);
+
+ while ((p_pool_entry = TAILQ_FIRST(&p_pool->free_table)) != NULL)
+ {
+ /* Remove the entry from the free pool table. */
+ TAILQ_REMOVE(&p_pool->free_table, p_pool_entry, entry);
+
+ /* Free the entry */
+ sal_free(p_pool_entry);
+ }
+}
+
+/**************************************************************************/
+/**
+ * @brief Allocate a qos Flow/VOQ ID from the pool
+ *
+ * This function allocates a Flow/VOQ ID from the resource pool. If
+ * there is a free voq ID entry in the free pool, the voq ID from
+ * the entry is used (i.e., returned to the caller) and the entry is
+ * freed. Otherwise, a new voq ID value is allocated and
+ * returned. This function returns an error if there are no voq IDs
+ * available.
+ *
+ * @param p_pool Pointer to a voq ID pool
+ * @param p_flow_id Pointer to the voq ID (value returned to caller)
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+static bcmos_errno bal_sw_dpp_qos_alloc_flow_id(bal_sw_dpp_qos_flowid_pool *p_pool, int *p_flow_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bal_sw_dpp_qos_flowid_pool_entry *p_pool_entry = NULL;
+ uint32_t flow_id = 0;
+
+ /* Parameter checks */
+ BUG_ON(p_pool == NULL);
+ BUG_ON(p_flow_id == NULL);
+
+ /* Get an entry from the free pool */
+ p_pool_entry = TAILQ_FIRST(&p_pool->free_table);
+
+ /* If an entry exists from the free pool, use the voq ID from the
+ * entry.
+ */
+ if (p_pool_entry != NULL)
+ {
+ /* Remove the entry from the free pool. */
+ TAILQ_REMOVE(&p_pool->free_table, p_pool_entry, entry);
+
+ /* Use the voq ID from the entry */
+ flow_id = p_pool_entry->flow_id;
+
+ /* Free the entry */
+ sal_free(p_pool_entry);
+ }
+ else
+ {
+ /* Otherwise, use the next voq ID value (if available) */
+ if (p_pool->next_flow_id_value <= p_pool->max_value)
+ {
+ /* Use the next available voq ID value */
+ flow_id = p_pool->next_flow_id_value;
+
+ /* Increment the next_flow_id_value parameter */
+ p_pool->next_flow_id_value += BAL_BCM_QOS_QUEUES_PER_LLID;
+ }
+ }
+
+ /* Check to see if a voq ID value was available. */
+ if (flow_id == 0)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util, "%s(): No voq IDs available\n",
+ __FUNCTION__);
+ *p_flow_id = 0;
+ rc = BCM_ERR_NORES;
+ }
+ else
+ {
+ *p_flow_id = flow_id;
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Free a qos Flow/VOQ ID and return it to the resource pool
+ *
+ * This function "frees" a Flow/VOQ ID and returns it to the free
+ * pool. The free pool consists of a linked list of voq ID values
+ * that are available for reuse. When a voq ID is freed, memory is
+ * allocated to store the free voq ID value, which is appended to the
+ * link list used to implement the free pool.
+ *
+ * @param p_pool Pointer to a voq ID pool
+ * @param p_flow_id Pointer to the voq ID to free
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+static bcmos_errno bal_sw_dpp_qos_free_flow_id(bal_sw_dpp_qos_flowid_pool *p_pool, int *p_flow_id)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bal_sw_dpp_qos_flowid_pool_entry *p_pool_entry = NULL;
+
+ /* Parameter checks */
+ BUG_ON(p_pool == NULL);
+ BUG_ON(p_flow_id == NULL);
+
+ /* Make sure there is something to free */
+ if (*p_flow_id == 0)
+ {
+ /* Nothing to free - just return */
+ return BCM_ERR_OK;
+ }
+
+ /* Allocate memory for a free pool entry */
+ p_pool_entry = sal_alloc(sizeof(bal_sw_dpp_qos_flowid_pool_entry), "voq ID Free Pool Entry");
+ if (p_pool_entry == NULL)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): No memory for bal_sw_dpp_qos_flowid_pool_entry_t for voq ID %u\n",
+ __FUNCTION__, *p_flow_id);
+
+ rc = BCM_ERR_NORES;
+ }
+ else
+ {
+ /* Initialize the entry */
+ memset(p_pool_entry, 0, sizeof(bal_sw_dpp_qos_flowid_pool_entry));
+
+ /* Store the voq ID */
+ p_pool_entry->flow_id = *p_flow_id;
+
+ /* Add the service entry to the table */
+ TAILQ_INSERT_TAIL(&p_pool->free_table, p_pool_entry, entry);
+
+ /* Clear the voq ID entry */
+ *p_flow_id = 0;
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Create the PCP and DEI to Traffic Class (TC) mapping
+ *
+ * This function creates the mapping from PCP/CoS and DEI bits in the
+ * frames received by DPP to the internal traffic class (TC) in
+ * DPP. The TC is used to determine the destination VOQ for the
+ * frame.
+ *
+ * Please see comments for @ref g_bal_bcm_qos_tc_map for a description of
+ * mapping.
+ *
+ * @param unit SDK unit number
+ * @param p_tc_map Pointer to PCP/DEI to TC map array
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+static bcmos_errno bal_sw_dpp_qos_tc_map_create(int unit, const int *p_tc_map)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_qos_map_t l2_in_map;
+ int pcp = 0;
+ int dei = 0;
+ int32_t qos_map_id;
+
+ /* Parameter checks */
+ BUG_ON(p_tc_map == NULL);
+
+ /* Create the TC map object */
+ sdk_rc = bcm_qos_map_create(unit, BCM_QOS_MAP_INGRESS, &qos_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_qos_map_create failed with %s\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc));
+
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* Create a mapping for each PCP/CoS and DEI bit value. */
+ for (pcp = 0; pcp < BAL_BCM_QOS_TC_NUM; pcp++)
+ {
+ for (dei = 0; dei < 2; dei++)
+ {
+ bcm_qos_map_t_init(&l2_in_map);
+
+ /* Ingress PCP/CoS value */
+ l2_in_map.pkt_pri = pcp;
+
+ /* DEI Bit */
+ l2_in_map.pkt_cfi = dei;
+
+ /* Set internal priority for this ingress pri */
+ l2_in_map.int_pri = p_tc_map[pcp];
+
+ /* Set color for this ingress Priority */
+ l2_in_map.color = bcmColorGreen;
+
+ sdk_rc = bcm_qos_map_add(unit, BCM_QOS_MAP_L2, &l2_in_map, qos_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_qos_map_add failed with %s, for pcp %d, dei %d\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pcp, dei);
+
+ return BCM_ERR_INTERNAL;
+ }
+ }
+ }
+
+ gp_bal_bcm_qos_cfg->qos_port_map_id = qos_map_id;
+
+ return BCM_ERR_OK;
+}
+
+/**************************************************************************/
+/**
+ * @brief Clean up the PCP and DEI to Traffic Class (TC) map
+ *
+ * @param unit SDK unit number
+ *
+ **************************************************************************/
+static void bal_sw_dpp_qos_tc_map_cleanup(int unit)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_qos_map_t l2_in_map;
+ int pcp = 0;
+ int dei = 0;
+
+ /* Delete all mapping entries */
+ for (pcp = 0; pcp < BAL_BCM_QOS_TC_NUM; pcp++)
+ {
+ for (dei = 0; dei < 2; dei++)
+ {
+ bcm_qos_map_t_init(&l2_in_map);
+
+ /* Ingress PCP/CoS value */
+ l2_in_map.pkt_pri = pcp;
+
+ /* DEI Bit */
+ l2_in_map.pkt_cfi = dei;
+
+ sdk_rc = bcm_qos_map_delete(unit, BCM_QOS_MAP_L2, &l2_in_map, gp_bal_bcm_qos_cfg->qos_port_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_qos_map_delete failed with %s, for pcp %d, dei %d\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pcp, dei);
+
+ /* Continue processing - don't halt because of errors during clearn up */
+ }
+ }
+ }
+
+ /* Delete the TC map object */
+ sdk_rc = bcm_qos_map_destroy(unit, gp_bal_bcm_qos_cfg->qos_port_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_qos_map_destroy failed with %s\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc));
+
+ /* Continue processing - don't halt because of errors during clearn up */
+ }
+}
+
+/**************************************************************************/
+/**
+ * @brief Initialize the BAL DPP QoS Module
+ *
+ * This function initializes the QoS module for the BAL BCM Switch Util.
+ * This function initializes the global QoS context, and
+ * sets up downstream scheduling hierarchy on each channelized
+ * PON-side port. Scheduling/QoS is applied to packets that egress the
+ * port.
+ *
+ * @param unit SDK unit number
+ * @param pon_mode pon interface mode
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_qos_init(int unit, bal_swapp_port_map_indx pon_mode)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bal_sw_dpp_qos_sched_pon_chan pon_chan;
+ uint32_t port_rate, pri_channel_rate, sec_channel_rate;
+ int ii, port_num;
+
+ /* Initialization */
+ memset(gp_bal_bcm_qos_cfg, 0, sizeof(*gp_bal_bcm_qos_cfg));
+
+ do /* Exception Block Start */
+ {
+ rc = bal_sw_dpp_qos_tc_map_create(unit, g_bal_bcm_qos_tc_map);
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "Failed to create the default QoS TC map\n");
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Get this module ID for this ARAD device. This is used by
+ * several of the bcm API calls during QoS setups.
+ */
+ sdk_rc = bcm_stk_modid_get(unit, &gp_bal_bcm_qos_cfg->mod_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_stk_modid_get failed with %s\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc));
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* set the port rate based on board type */
+ switch(pon_mode)
+ {
+ case BAL_SWAPP_PORT_MAP_GPON:
+ case BAL_SWAPP_PORT_MAP_GPON_V3:
+ port_rate = 2500000; /* 2.5G */
+ pri_channel_rate = 2500000; /* 2.5G */
+ sec_channel_rate = 0;
+ gp_bal_bcm_qos_cfg->num_channels_per_pon = 1;
+ break;
+ case BAL_SWAPP_PORT_MAP_EXP:
+ case BAL_SWAPP_PORT_MAP_EXP2:
+ case BAL_SWAPP_PORT_MAP_SVK4:
+ port_rate = 10000000; /* 10G */
+ pri_channel_rate = 10000000; /* 10G */
+ sec_channel_rate = 0;
+ gp_bal_bcm_qos_cfg->num_channels_per_pon = 1;
+ break;
+ case BAL_SWAPP_PORT_MAP_EPON_TDMA:
+ port_rate = BAL_BCM_QOS_DEFAULT_PORT_RATE; /* 12.5G */
+ pri_channel_rate = BAL_BCM_QOS_DEFAULT_10G_CHAN_RATE; /* 10.25G */
+ sec_channel_rate = BAL_BCM_QOS_DEFAULT_1G_CHAN_RATE; /* 2.25G */
+ gp_bal_bcm_qos_cfg->num_channels_per_pon = 2;
+ break;
+ case BAL_SWAPP_PORT_MAP_EPON_1G:
+ port_rate = 2500000; /* 2.5G */
+ pri_channel_rate = BAL_BCM_QOS_DEFAULT_1G_CHAN_RATE; /* 2.25G */
+ sec_channel_rate = 0;
+ gp_bal_bcm_qos_cfg->num_channels_per_pon = 1;
+ break;
+ case BAL_SWAPP_PORT_MAP_EPON_10G:
+ port_rate = BAL_BCM_QOS_DEFAULT_PORT_RATE; /* 12.5G */
+ pri_channel_rate = BAL_BCM_QOS_DEFAULT_10G_CHAN_RATE; /* 10.25G */
+ sec_channel_rate = 0;
+ gp_bal_bcm_qos_cfg->num_channels_per_pon = 1;
+ break;
+ default:
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): pon mode %d not supported\n",
+ __FUNCTION__, pon_mode);
+
+ return BCM_ERR_INTERNAL;
+ }
+ /*
+ * Initialize the egress scheduling for downstream QoS on each
+ * PON-side port.
+ */
+ ii = 0; /* Start with the first PON logical interface */
+ /* loop through all pon port, -1 indicate end of table */
+ while(-1 != (port_num = bal_bcm_pon_inf_pbm_get(ii)))
+ {
+ /*
+ * Default port settings
+ *
+ * Set the port shaper to rate based on physical layout on each board.
+ * On Epon, there are 2 channels on each port.
+ * The channel interface shapers are set to 10G and 2G for the 10G and 1G
+ * channels respectively. DPP will rely on flow control from
+ * Maple for back pressure.
+ */
+ bal_sw_dpp_qos_set_port_bandwidth(unit, port_num,
+ port_rate, BAL_BCM_QOS_DEFAULT_MAX_BURST);
+ bal_sw_dpp_qos_set_portchan_bandwidth(unit, port_num, BAL_BCM_SCHED_PON_CHAN_10G,
+ pri_channel_rate, BAL_BCM_QOS_DEFAULT_MAX_BURST);
+ if(gp_bal_bcm_qos_cfg->num_channels_per_pon > 1)
+ {
+ bal_sw_dpp_qos_set_portchan_bandwidth(unit, port_num, BAL_BCM_SCHED_PON_CHAN_1G,
+ sec_channel_rate, BAL_BCM_QOS_DEFAULT_MAX_BURST);
+ }
+ for (pon_chan = 0; pon_chan < gp_bal_bcm_qos_cfg->num_channels_per_pon; pon_chan++)
+ {
+ /* pass the logical port number - ii, to the port qos init function,
+ * the logical port number and the channel number will be mapped to
+ * packet process port number that used in qos configuration
+ */
+ rc = bal_sw_dpp_port_qos_init(unit, ii, pon_chan);
+
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "QoS setup failed for port %u pon_chan %u\n",
+ port_num, pon_chan);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ /* Exception Block - check for errors from the previous loop */
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ break;
+ }
+ ii++;
+ }
+
+ /* Check for errors */
+ if (rc != BCM_ERR_OK)
+ {
+ break;
+ }
+
+ /* Initialize the Flow/VOQ ID pools */
+ bal_sw_dpp_init_flow_id_pool(&gp_bal_bcm_qos_cfg->flow_id_pool_10g,
+ DEFAULT_QOS_VOQ_BASE_10G,
+ DEFAULT_QOS_VOQ_MAX_10G);
+
+ bal_sw_dpp_init_flow_id_pool(&gp_bal_bcm_qos_cfg->flow_id_pool_1g,
+ DEFAULT_QOS_VOQ_BASE_1G,
+ DEFAULT_QOS_VOQ_MAX_1G);
+
+ } while(0); /* Exception Block - End */
+
+ /* Check for errors */
+ if (rc != BCM_ERR_OK)
+ {
+ /* Failure */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "BAL BCM App not initialized, failed setting up the QoS module\n");
+
+ /* Cleanup */
+ bal_sw_dpp_qos_cleanup(unit);
+ }
+ else
+ {
+ /* Success */
+ BCM_LOG(INFO, log_id_sw_util,
+ "Successfully initialized the QoS module\n");
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Cleanup the BAL BCM APP QoS Module
+ *
+ * @param unit SDK unit number
+ *
+ **************************************************************************/
+void bal_sw_dpp_qos_cleanup(int unit)
+{
+ bcm_port_t port_num;
+ bal_sw_dpp_qos_sched_pon_chan pon_chan;
+ int ii;
+ /*
+ * Cleanup the egress scheduling for downstream QoS on each
+ * PON-side port.
+ */
+ ii = 0; /* Start with the first PON logical interface */
+ /* loop through all pon port, -1 indicate end of table */
+ while(-1 != (port_num = bal_bcm_pon_inf_pbm_get(ii)))
+ {
+ /* Clean up each channelized port */
+ for (pon_chan = 0; pon_chan < gp_bal_bcm_qos_cfg->num_channels_per_pon; pon_chan++)
+ {
+ bal_sw_dpp_port_qos_cleanup(unit, ii, pon_chan);
+ }
+ ii++;
+ }
+
+ /* Clean up the TC map */
+ bal_sw_dpp_qos_tc_map_cleanup(unit);
+
+ /* Free memory that was used for the Flow/VOQ ID pools */
+ bal_sw_dpp_cleanup_flow_id_pool(&gp_bal_bcm_qos_cfg->flow_id_pool_10g);
+ bal_sw_dpp_cleanup_flow_id_pool(&gp_bal_bcm_qos_cfg->flow_id_pool_1g);
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure the rate shaper for a PON port
+ *
+ * This function configures the rate shaper (i.e., rate limit) for a
+ * PON side port. The rate limit and maximum burst size is set to the
+ * value specified in the function call. The maximum burst size is
+ * only set for max_burst values greater than '0'.
+ *
+ * @param unit SDK unit number
+ * @param pon_port PON port number
+ * @param bandwidth Shaper data rate in kbps
+ * @param max_burst Shaper maximum burst size in bytes
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_qos_set_port_bandwidth(int unit, bcm_port_t pon_port,
+ uint32_t bandwidth, uint32_t max_burst)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_gport_t e2e_pon_gport;
+ bcm_gport_t e2e_parent_gport;
+
+ /* Parameter checks */
+ BUG_ON(pon_port > BAL_BCM_MAX_PON_NUM);
+
+ /* Get the gport object for the E2E interface for the specified
+ * pon_port
+ */
+ BCM_COSQ_GPORT_E2E_PORT_SET(e2e_pon_gport, pon_port);
+
+ do /* Exception Block Start */
+ {
+ /*
+ * Get the gport for the E2E Interface
+ */
+ sdk_rc = bcm_fabric_port_get(unit,
+ e2e_pon_gport,
+ 0,
+ &e2e_parent_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_fabric_port_get for Egress Port failed with %s for pon %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /*
+ * Set rate on the E2E Interface
+ */
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit,
+ e2e_parent_gport,
+ 0,
+ 0,
+ bandwidth,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set for Egress Port failed with %s for pon %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Set the Burst */
+ if (max_burst > 0)
+ {
+ sdk_rc = bcm_cosq_control_set(unit,
+ e2e_parent_gport,
+ 0,
+ bcmCosqControlBandwidthBurstMax,
+ max_burst);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_control_set for MaxBurst failed with %s for pon %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ } while(0); /* Exception Block - End */
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure the rate shaper for a PON channel
+ *
+ * This function configures the rate shaper (i.e., rate limit) for a
+ * PON channel 10G. vs. 1G. The rate limit and maximum burst size is
+ * set to the value specified in the function call. The maximum burst
+ * size is only set for max_burst values greater than '0'.
+ *
+ * @param unit SDK unit number
+ * @param pon_port PON port number
+ * @param pon_chan PON channel (10G vs. 1G)
+ * @param bandwidth Shaper data rate in kbps
+ * @param max_burst Shaper maximum burst size in bytes
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_qos_set_portchan_bandwidth(int unit, bcm_port_t pon_port,
+ bal_sw_dpp_qos_sched_pon_chan pon_chan,
+ uint32_t bandwidth, uint32_t max_burst)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_port_t pp_port;
+ bcm_gport_t e2e_gport;
+ bcm_gport_t local_gport;
+ bcm_gport_t e2e_tc_gport;
+ bcm_gport_t local_tc_gport;
+ uint32_t adj_bandwidth;
+
+ /* Parameter checks */
+ BUG_ON(pon_port > BAL_BCM_MAX_PON_NUM);
+ BUG_ON(pon_chan >= BAL_BCM_SCHED_PON_CHAN_NUM);
+
+ /* Get the local port number for the specified device PON port number and channel */
+ pp_port = BAL_BCM_GET_PP_PORT(pon_port, pon_chan);
+
+ do /* Exception Block Start */
+ {
+ /* Apply a rate adjustment to the credit generator */
+ adj_bandwidth = bandwidth + ((uint32_t)(bandwidth * BAL_BCM_QOS_CREDIT_RATE_ADJ));
+
+ BCM_COSQ_GPORT_E2E_PORT_SET(e2e_gport, pp_port);
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit, e2e_gport, 0, 0, adj_bandwidth, 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set for e2e_gport failed with %s for pon %u chan %u pp_port %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, pp_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Apply a rate adjustment to the shaper */
+ adj_bandwidth = bandwidth + ((uint32_t)(bandwidth * BAL_BCM_QOS_SHAPER_RATE_ADJ));
+
+ BCM_GPORT_LOCAL_SET(local_gport, pp_port);
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit, local_gport, 0, 0, adj_bandwidth, 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set for local_gport failed with %s for pon %u chan %u pp_port %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, pp_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ BCM_COSQ_GPORT_E2E_PORT_TC_SET(e2e_tc_gport, pp_port);
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit, e2e_tc_gport, 0, 0, bandwidth, 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set for e2e_tc_gport failed with %s for pon %u chan %u pp_port %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, pp_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ BCM_COSQ_GPORT_PORT_TC_SET(local_tc_gport, pp_port);
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit, local_tc_gport, 0, 0, bandwidth, 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set for local_tc_gport failed with %s for pon %u chan %u pp_port %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, pp_port);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ } while(0); /* Exception Block - End */
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure SP or WFQ scheduling for a PON channel
+ *
+ * This function configures scheduling for a PON channel (10G
+ * vs. 1G). If all of the specified weight values are non-zero, then
+ * WFQ is enabled on the PON channel. Otherwise, if one or more of the
+ * weight values is zero, strict priority (SP) scheduling will be used
+ * on this port.
+ *
+ * @param unit SDK unit number
+ * @param pon_port PON port number
+ * @param pon_chan PON channel (10G vs. 1G)
+ * @param p_wfq_cfg Pointer to the WFQ scheduler configuration
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_qos_set_ponchan_wfq_cfg(int unit, bcm_port_t pon_port,
+ bal_sw_dpp_qos_sched_pon_chan pon_chan, bal_sw_dpp_qos_wfq_cfg *p_wfq_cfg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bal_sw_dpp_port_qos_cfg *p_port_qos = NULL;
+ uint8_t wfq_lvl;
+ uint32_t weight;
+
+ /* Parameter checks */
+ BUG_ON(pon_port >= BAL_BCM_QOS_NUM_PON_PORTS);
+ BUG_ON(pon_chan >= BAL_BCM_SCHED_PON_CHAN_NUM);
+
+ /* Get the scheduler configuration for the port. */
+ p_port_qos = &gp_bal_bcm_qos_cfg->pon[pon_port][pon_chan];
+
+ /* Assume WFQ is used until a zero weight value is encountered. */
+ p_port_qos->sched_type = BAL_BCM_SCHED_TYPE_WFQ;
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ if (p_wfq_cfg->weights[wfq_lvl] == 0)
+ {
+ /* Use strict priority */
+ memset(&p_port_qos->pon_chan_weight_cfg, 0, sizeof(p_port_qos->pon_chan_weight_cfg));
+ p_port_qos->sched_type = BAL_BCM_SCHED_TYPE_SP;
+ break;
+ }
+ else
+ {
+ p_port_qos->pon_chan_weight_cfg[wfq_lvl] = p_wfq_cfg->weights[wfq_lvl];
+ }
+ }
+
+ /* If WFQ is being used, update the weight values in the PON
+ * channel's SE. Otherwise, the scheduling type is SP and there is
+ * nothing else to do.
+ */
+ if (p_port_qos->sched_type == BAL_BCM_SCHED_TYPE_WFQ)
+ {
+ /* Apply the weight configuration for each WFQ scheduling
+ * level to the hardware.
+ */
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ /* The weight cannot exceed 4K on ARAD */
+ weight = p_port_qos->pon_chan_weight_cfg[wfq_lvl];
+ if (weight > BAL_BCM_SCHED_WFQ_MAX_WEIGHT)
+ {
+ BCM_LOG(WARNING, log_id_sw_util,
+ "Configured weight value %u is larger than the maximum supported by ARAD, capping value to %u, pon %u, chan %u, wfq_lvl %u\n",
+ weight, BAL_BCM_SCHED_WFQ_MAX_WEIGHT, pon_port, pon_chan, wfq_lvl);
+
+ /* If the weight value exceeds max, cap that value at 4K. */
+ weight = BAL_BCM_SCHED_WFQ_MAX_WEIGHT;
+ }
+
+ /* Configure the hardware */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_port_qos->wfq_scheduler[wfq_lvl],
+ 0,
+ BCM_COSQ_SP3,
+ weight);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for PON Channel WFQ SE failed with %s for pon %u, chan %u, wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Initialize downstream QoS for a channelized PON port
+ *
+ * This function initializes downstream QoS for a channelized PON
+ * port, where scheduling/QoS is applied to packets that egress the
+ * port. Please refer to the "SCHEDULER MODEL" diagram at the top of
+ * this file.
+ *
+ * This function configures the Port-related scheduling elements
+ * (SEs), including the PON channel (10G vs. 1G) High Resolution
+ * Diff-serve (HR) SE. CIR flows are attached directly to the channel
+ * HR. Strict Priority (SP) and Weighted-Fair Queue (WFQ) SEs are
+ * created to implement DOCSIS Traffic Priority for EIR flows. After
+ * creating the SEs, each SE is connected to the hierarchy as shown in
+ * the diagram.
+ *
+ * @param unit SDK unit number
+ * @param log_pon logical PON port number
+ * @param pon_chan PON channel (10G vs. 1G)
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_port_qos_init(int unit, bcm_port_t log_pon, bal_sw_dpp_qos_sched_pon_chan pon_chan)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bal_sw_dpp_port_qos_cfg *p_port_qos = NULL;
+ bcm_gport_t mod_gport;
+ int flags = 0;
+ int wfq_lvl;
+ bcm_port_t pp_port, pon_port;
+
+ /* Parameter checks */
+ BUG_ON(log_pon >= BAL_BCM_QOS_NUM_PON_PORTS);
+ BUG_ON(pon_chan >= BAL_BCM_SCHED_PON_CHAN_NUM);
+
+ BCM_LOG(DEBUG, log_id_sw_util,
+ "%s(): initializing QoS on port %d, %s channel w sche mode %s\n",
+ __FUNCTION__, log_pon, (pon_chan == BAL_BCM_SCHED_PON_CHAN_10G) ? "10G" : "1G",
+ (bal_bcm_ds_sched_mode_get()) ? "WFQ" : "SP");
+
+ /* Retrieve the QoS configuration for the specified channel, index by logical pon number */
+ p_port_qos = &gp_bal_bcm_qos_cfg->pon[log_pon][pon_chan];
+
+ /* Get Max rate scheduling mode from global setting */
+ /* TBD - the scheduling mode can be different for each port */
+ p_port_qos->sched_type = bal_bcm_ds_sched_mode_get();
+
+ /* get the pp port from the device port number */
+ pon_port = bal_bcm_pon_inf_pbm_get(log_pon);
+ pp_port = BAL_BCM_GET_PP_PORT(pon_port, pon_chan);
+
+ /*
+ * Setup downstream scheduling this channelized port
+ */
+
+ do /* Exception Block Start */
+ {
+ /*
+ * Get the mod port for this channel.
+ */
+ BCM_GPORT_MODPORT_SET(mod_gport, gp_bal_bcm_qos_cfg->mod_id, pp_port);
+ p_port_qos->mod_gport = mod_gport;
+
+ /* Initialize the channel weights to defaults values.
+ *
+ * By default strict priority is used, so these weight values
+ * are not "active". However, we need to set the weights to
+ * something non-zero during initialization.
+ *
+ * The default channel weights are...
+ * 32, 64, 128, 256, 512, 1024, 2048, 4096
+ */
+ p_port_qos->pon_chan_weight_cfg[0] = 32;
+ for (wfq_lvl=1; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ p_port_qos->pon_chan_weight_cfg[wfq_lvl] = 2 * p_port_qos->pon_chan_weight_cfg[wfq_lvl-1];
+ }
+
+ /*
+ * Channel HR (level 1)
+ *
+ * Get the OTM port HR for this PON channel. The rest of
+ * the downstream scheduling hierarchy is attached to this
+ * HR.
+ *
+ * The 'BCM_COSQ_GPORT_REPLACE' flag is passed into the
+ * bcm_cosq_gport_add() function call, which changes the
+ * scheduling type from the default mode to a SINGLE_WFQ
+ * mode.
+ */
+ BCM_COSQ_GPORT_E2E_PORT_SET(p_port_qos->pon_chan_scheduler, pp_port);
+ flags = BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_HR_SINGLE_WFQ | BCM_COSQ_GPORT_REPLACE;
+ sdk_rc = bcm_cosq_gport_add(unit, pp_port, 1, flags, &p_port_qos->pon_chan_scheduler);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add (with REPLACE) for PON Channel HR failed with %s for pon %u chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ else
+ {
+
+ BCM_LOG(DEBUG, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add (with REPLACE) for PON Channel HR - gport 0x%x\n",
+ __FUNCTION__, p_port_qos->pon_chan_scheduler);
+ }
+ /*
+ * Strict Priority HR (level 2)
+ *
+ * Set up a Strict Priority HR scheduler for EIR (MAX Rate)
+ * flows. This SE is only used when the PON channel is running
+ * in Strict Priority mode.
+ */
+
+ /* Create the scheduler object */
+ flags = BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_HR_ENHANCED;
+ sdk_rc = bcm_cosq_gport_add(unit, 0, 1, flags, &p_port_qos->sp_scheduler);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for MAX Rate SP HR failed with %s for pon %u chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ else
+ {
+
+ BCM_LOG(DEBUG, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for MAX Rate SP HR - gport 0x%x\n",
+ __FUNCTION__, p_port_qos->sp_scheduler);
+ }
+
+ /* Configure the priority for this scheduler. The SP SE is
+ * attached at priority '2'.
+ */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_port_qos->sp_scheduler,
+ 0,
+ BCM_COSQ_SP2,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for MAX Rate SP HR failed with %s for pon %u chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the SP scheduler to the Channel HR. */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ p_port_qos->pon_chan_scheduler,
+ p_port_qos->sp_scheduler,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for MAX Rate SP HR failed with %s for pon %u chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /*
+ * WFQ (level 2)
+ *
+ * Create FQ scheduling elements and attach one to each
+ * WFQ level. This is used to schedule EIR (MAX Rate)
+ * flows when the PON channel is running in WFQ mode.
+ */
+
+ /* Create a FQ scheduler for each WFQ level */
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ /* Create the scheduler object */
+ flags = BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_FQ;
+ sdk_rc = bcm_cosq_gport_add(unit, 0, 1, flags, &p_port_qos->wfq_scheduler[wfq_lvl]);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for MAX Rate WFQ failed with %s for pon %u chan %u wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Configure the priority for this SE. (WFQ is SP3 on
+ * the Channel HR.)
+ */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_port_qos->wfq_scheduler[wfq_lvl],
+ 0,
+ BCM_COSQ_SP3,
+ p_port_qos->pon_chan_weight_cfg[wfq_lvl]);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for MAX Rate WFQ failed with %s for pon %u chan %u wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the FQ scheduler the WFQ on the Channel HR. */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ p_port_qos->pon_chan_scheduler,
+ p_port_qos->wfq_scheduler[wfq_lvl],
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for MAX Rate WFQ failed with %s for pon %u chan %u wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ } while(0); /* Exception Block - End */
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Clean up QoS for a PON-side port
+ *
+ * Each SE must be disconnected from the hierarchy before freeing the
+ * SE.
+ *
+ * @param unit SDK unit number
+ * @param pon_port PON port number
+ * @param pon_chan PON channel (10G vs. 1G)
+ *
+ **************************************************************************/
+void bal_sw_dpp_port_qos_cleanup(int unit, bcm_port_t pon_port, bal_sw_dpp_qos_sched_pon_chan pon_chan)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bal_sw_dpp_port_qos_cfg *p_port_qos = NULL;
+ int wfq_lvl;
+
+ /* Parameter checks */
+ BUG_ON(pon_port >= BAL_BCM_QOS_NUM_PON_PORTS);
+ BUG_ON(pon_chan >= BAL_BCM_SCHED_PON_CHAN_NUM);
+
+ /* Retrieve the QoS configuration for the specified port */
+ p_port_qos = &gp_bal_bcm_qos_cfg->pon[pon_port][pon_chan];
+
+ /*
+ * Clean up WFQ
+ */
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ /* Disconnect the scheduler from the one above */
+ sdk_rc = bcm_cosq_gport_detach(unit,
+ p_port_qos->pon_chan_scheduler,
+ p_port_qos->wfq_scheduler[wfq_lvl],
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_detach for MAX Rate WFQ failed with %s for pon %u pon_chan %u wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ sdk_rc = bcm_cosq_gport_delete(unit, p_port_qos->wfq_scheduler[wfq_lvl]);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_delete for MAX Rate WFQ failed with %s for pon %u pon_chan %u wfq_lvl %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan, wfq_lvl);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+ }
+
+ /*
+ * Clean up SP HR
+ */
+
+ /* Disconnect the scheduler from the one above */
+ sdk_rc = bcm_cosq_gport_detach(unit,
+ p_port_qos->pon_chan_scheduler,
+ p_port_qos->sp_scheduler,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_detach for MAX Rate SP HR failed with %s for pon %u pon_chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ sdk_rc = bcm_cosq_gport_delete(unit, p_port_qos->sp_scheduler);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_delete for MAX Rate SP HR failed with %s for pon %u pon_chan %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), pon_port, pon_chan);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure a rate shaper and maximum burst size for a PON Link
+ *
+ * This function configures the rate and maximum burst size for the
+ * specified shaper (MIN Rate vs. MAX Rate) for a PON Link (LLID).
+ *
+ * @param unit SDK unit number
+ * @param p_service_cfg Pointer to the service configuration entry
+ * @param sla_type Shaper type (MIN vs. MAX)
+ * @param bandwidth Data rate in Kbps (i.e., token bucket fill rate)
+ * @param max_burst Maximum burst size in bytes (i.e., token bucket size)
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_qos_set_llid_bandwidth(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg,
+ bal_sw_dpp_qos_sched_sla_type sla_type, uint32_t bandwidth, uint32_t max_burst)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_gport_t scheduler_gport;
+
+ /* Parameter checks */
+ BUG_ON(p_service_cfg == NULL);
+
+ /* Get the scheduler gport that the VOQs are attached to (MIN vs. MAX) */
+ if (sla_type == BAL_BCM_SCHED_SLA_MIN_RATE)
+ {
+ scheduler_gport = p_service_cfg->ds_qos.min.scheduler_gport;
+ }
+ else
+ {
+ scheduler_gport = p_service_cfg->ds_qos.max.scheduler_gport;
+ }
+
+ /* Set the Rate - drain rate */
+ sdk_rc = bcm_cosq_gport_bandwidth_set(unit,
+ scheduler_gport,
+ 0,
+ 0,
+ bandwidth,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_bandwidth_set failed with %s for %s gport 0x%x\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), (sla_type == BAL_BCM_SCHED_SLA_MIN_RATE)? "SLA_MIN_RATE":"SLA_MAX_RATE", scheduler_gport);
+
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util,
+ "%s() set gport 0x%x with %s of %d\n",
+ __FUNCTION__, scheduler_gport,(sla_type == BAL_BCM_SCHED_SLA_MIN_RATE)? "SLA_MIN_RATE":"SLA_MAX_RATE", bandwidth);
+ }
+
+ /* Set the Burst - bucket size that hold the incoming frames */
+ sdk_rc = bcm_cosq_control_set(unit,
+ scheduler_gport,
+ 0,
+ bcmCosqControlBandwidthBurstMax,
+ max_burst);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_control_set for MaxBurst failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ return BCM_ERR_INTERNAL;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure downstream QoS for a PON Link (LLID)
+ *
+ * This function configures downstream QoS for a PON Link (LLID),
+ * which is represented by a tunnel ID in ARAD. Please refer to the
+ * "SCHEDULER MODEL" diagram at the top of this file. This function
+ * configures the PON Link SE and queues (VOQ + VOQ Connector) for the
+ * Link. The PON Link scheduler processes queues using strict
+ * priority. This function configures four queues for the Link, which
+ * is the smallest number of queues per LLID supported by
+ * ARAD. However, the BAL BCM App currently only makes use of a single
+ * queue.
+ *
+ * This function configures MIN (CIR) and MAX (EIR) rate shapers. If
+ * the MIN rate is disabled (i.e., bandwidth configured with a value
+ * of '0' kbps), the shaper is not "connected" to the port's MIN Rate
+ * SE.
+ *
+ * @param unit SDK unit number
+ * @param p_service_cfg Pointer to the service configuration entry
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_llid_qos_config(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bal_sw_dpp_port_qos_cfg *p_port_qos = NULL;
+ int flags = 0;
+ int cosq;
+ bcm_cosq_gport_connection_t connection;
+ bal_sw_dpp_qos_sched_pon_chan ds_pon_chan;
+ bcm_gport_t scheduler_gport;
+
+ /* Parameter checks */
+ BUG_ON(p_service_cfg == NULL);
+
+ /* Store the downstream PON rate, which will be used in several
+ * places throughout this function.
+ */
+ ds_pon_chan = p_service_cfg->ds_qos.pon_chan;
+
+ /* Retrieve the QoS configuration for the specified port */
+ p_port_qos = &gp_bal_bcm_qos_cfg->pon[p_service_cfg->pon_port][ds_pon_chan];
+
+ do /* Exception Block Start */
+ {
+ /* Allocate the voq ID from the free pool */
+ if (ds_pon_chan == BAL_BCM_SCHED_PON_CHAN_10G)
+ {
+ rc = bal_sw_dpp_qos_alloc_flow_id(&gp_bal_bcm_qos_cfg->flow_id_pool_10g, &p_service_cfg->ds_qos.voq_flow_id);
+ }
+ else
+ {
+ rc = bal_sw_dpp_qos_alloc_flow_id(&gp_bal_bcm_qos_cfg->flow_id_pool_1g, &p_service_cfg->ds_qos.voq_flow_id);
+ }
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): Unable to allocate voq ID for pon %u tid %u\n",
+ __FUNCTION__, p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* In the BAL BCM App, the VOQ ID is equal to the voq ID */
+ p_service_cfg->ds_qos.voq_id = p_service_cfg->ds_qos.voq_flow_id;
+
+ /*
+ * PON Link scheduler (level 2)
+ */
+ if (p_service_cfg->ds_qos.min.rate > 0)
+ {
+ /* Create a composite, strict priority scheduler for this PON
+ * Link. This is used to schedule between the queues assigned to
+ * this PON Link.
+ */
+ flags = BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_CLASS_MODE1_4SP | BCM_COSQ_GPORT_COMPOSITE;
+ sdk_rc = bcm_cosq_gport_add(unit,
+ 0,
+ 1, /* Number of CoS levels */
+ flags,
+ &p_service_cfg->ds_qos.min.scheduler_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for PON Link SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* A single priority on the Channel HR handles all MIN Rates (CIRs). */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_service_cfg->ds_qos.min.scheduler_gport,
+ 0,
+ BCM_COSQ_SP1,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for Min Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the PON Link scheduler to the Channel HR. */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ p_port_qos->pon_chan_scheduler,
+ p_service_cfg->ds_qos.min.scheduler_gport,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for Min Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Save the gport of the parent SE (used for cleanup) */
+ p_service_cfg->ds_qos.min.parent_gport = p_port_qos->pon_chan_scheduler;
+
+ /* Configure the MIN Rate shaper */
+ rc = bal_sw_dpp_qos_set_llid_bandwidth(unit,
+ p_service_cfg,
+ BAL_BCM_SCHED_SLA_MIN_RATE,
+ p_service_cfg->ds_qos.min.rate,
+ p_service_cfg->ds_qos.min.burst);
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): Set MIN Rate shaper failed for pon %u tid %u\n",
+ __FUNCTION__, p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Set the gport for the MAX Rate scheduler */
+ BCM_COSQ_GPORT_COMPOSITE_SF2_SET(p_service_cfg->ds_qos.max.scheduler_gport, p_service_cfg->ds_qos.min.scheduler_gport);
+
+ /* Set the scheduler gport that the VOQs are attached to */
+ scheduler_gport = p_service_cfg->ds_qos.min.scheduler_gport;
+ }
+ else
+ {
+ /*
+ * MAX Rate only (level 2)
+ */
+ flags = BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_CLASS_MODE1_4SP;
+ sdk_rc = bcm_cosq_gport_add(unit,
+ 0,
+ 1, /* Number of CoS levels */
+ flags,
+ &p_service_cfg->ds_qos.max.scheduler_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for PON Link SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Set the scheduler gport that the VOQs are attached to */
+ scheduler_gport = p_service_cfg->ds_qos.max.scheduler_gport;
+ }
+
+ /* The type of MAX Rate scheduling depends on what scheduling
+ * mode is configured on the PON channel (SP vs. WFQ).
+ */
+ if (p_port_qos->sched_type == BAL_BCM_SCHED_TYPE_SP)
+ {
+ /*
+ * Strict Priority (SP) scheduling is being used
+ */
+
+ /* Set the priority used for the attachment to the SP HR */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_service_cfg->ds_qos.max.scheduler_gport,
+ 0,
+ BCM_COSQ_SP0 + p_service_cfg->ds_qos.max.traffic_priority,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for Max Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the PON Link scheduler to the SP HR. */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ p_port_qos->sp_scheduler,
+ p_service_cfg->ds_qos.max.scheduler_gport,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for Max Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Save the gport of the parent SE (used for cleanup) */
+ p_service_cfg->ds_qos.max.parent_gport = p_port_qos->sp_scheduler;
+ }
+ else
+ {
+ /*
+ * Weighted Fair Queuing (WFQ) scheduling is being used
+ */
+
+ /* Set the priority used for the attachment to the FQ. */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_service_cfg->ds_qos.max.scheduler_gport,
+ 0,
+ BCM_COSQ_SP0,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for Max Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the PON Link scheduler to the FQ. */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ p_port_qos->wfq_scheduler[p_service_cfg->ds_qos.max.traffic_priority],
+ p_service_cfg->ds_qos.max.scheduler_gport,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for Max Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Save the gport of the parent SE (used for cleanup) */
+ p_service_cfg->ds_qos.max.parent_gport = p_port_qos->wfq_scheduler[p_service_cfg->ds_qos.max.traffic_priority];
+ }
+
+ /* Configure the MAX Rate shaper */
+ rc = bal_sw_dpp_qos_set_llid_bandwidth(unit,
+ p_service_cfg,
+ BAL_BCM_SCHED_SLA_MAX_RATE,
+ p_service_cfg->ds_qos.max.rate,
+ p_service_cfg->ds_qos.max.burst);
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): Set MAX Rate shaper failed for pon %u tid %u\n",
+ __FUNCTION__, p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ break;
+ }
+
+ /*
+ * Create a VOQ connector (level 3)
+ */
+
+ /* Create the VOQ connector object for a bundle of four queues */
+ flags = BCM_COSQ_GPORT_VOQ_CONNECTOR | BCM_COSQ_GPORT_WITH_ID;
+ BCM_COSQ_GPORT_VOQ_CONNECTOR_SET(p_service_cfg->ds_qos.voq_connector_gport, p_service_cfg->ds_qos.voq_flow_id);
+ sdk_rc = bcm_cosq_gport_add(unit,
+ p_port_qos->mod_gport,
+ BAL_BCM_QOS_QUEUES_PER_LLID,
+ flags,
+ &p_service_cfg->ds_qos.voq_connector_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for VOQ Connector failed with %s for pon %u tid %u voq ID %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc),
+ p_service_cfg->pon_port,
+ p_service_cfg->tunnel_id,
+ p_service_cfg->ds_qos.voq_flow_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Set the traffic class for each queue and attach the VOQ
+ * connector to the PON Link scheduler.
+ */
+ for (cosq = 0; cosq < BAL_BCM_QOS_QUEUES_PER_LLID; cosq++)
+ {
+ /* Set the traffic class for the queue */
+ sdk_rc = bcm_cosq_gport_sched_set(unit,
+ p_service_cfg->ds_qos.voq_connector_gport,
+ cosq,
+ BCM_COSQ_SP3 - cosq,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_sched_set for VOQ Connector failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Attach the connection for each queue to the PON Link
+ * scheduler, based on the traffic class.
+ */
+ sdk_rc = bcm_cosq_gport_attach(unit,
+ scheduler_gport,
+ p_service_cfg->ds_qos.voq_connector_gport,
+ cosq);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_attach for VOQ Connector failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ /* Exception Block - check for errors from the previous loop */
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ break;
+ }
+
+ /*
+ * Create a VOQ (level 3)
+ */
+ flags = BCM_COSQ_GPORT_UCAST_QUEUE_GROUP | BCM_COSQ_GPORT_TM_FLOW_ID | BCM_COSQ_GPORT_WITH_ID;
+ BCM_GPORT_UNICAST_QUEUE_GROUP_SET(p_service_cfg->ds_qos.voq_gport, p_service_cfg->ds_qos.voq_id);
+ sdk_rc = bcm_cosq_gport_add(unit,
+ p_port_qos->mod_gport,
+ BAL_BCM_QOS_QUEUES_PER_LLID,
+ flags,
+ &p_service_cfg->ds_qos.voq_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_add for VOQ failed with %s for voq id %u, voq gport 0x%x, pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->ds_qos.voq_id, p_service_cfg->ds_qos.voq_gport,
+ p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* QAX not support per Queue compensation */
+#ifndef QAX_SWITCH
+ /* Start - header adjust */
+ {
+ /*
+ * If necessary, adjust the packet header overhead to match
+ * the configured value.
+ */
+ int32_t val = 0;
+ int32_t cfg_dpp_hdr_size = 0;
+
+ /* Calculate the expected DPP header size, which depends on
+ * whether or not traffic is untagged, PB tagged, ICT
+ * tagged, or Shared Vlan tagged. If the traffic is tagged
+ * (either PB, ICT, or Shared Vlan), there are five fewer
+ * bytes in the DPP header.
+ */
+ cfg_dpp_hdr_size = DEFAULT_QOS_DPP_PKT_HDR_SIZE;
+ if (p_service_cfg->service_type != BAL_BCM_SVC_TYPE_IP)
+ {
+ cfg_dpp_hdr_size -= BAL_BCM_DPP_FLOWID_HDR_SIZE;
+ }
+
+ /* If the traffic is ICT stack mode or Shared Vlan tagged, we
+ * need to exclude the Vlan tag overhead from the bandwidth
+ * calculation (i.e., add four bytes of overhead).
+ */
+ if (((p_service_cfg->service_type == BAL_BCM_SVC_TYPE_ICT) /*&& (p_service_cfg->ictStkType != BAL_BCM_ICT_STACK_TYPE_NONE)*/)||
+ (p_service_cfg->service_type == BAL_BCM_SVC_TYPE_SHVLAN))
+ {
+ cfg_dpp_hdr_size += BAL_BCM_QOS_SINGLE_VLAN_TAG_HDR_SIZE;
+ }
+
+ /* Get the header length */
+ sdk_rc = bcm_cosq_control_get(unit,
+ p_service_cfg->ds_qos.voq_gport,
+ 0,
+ bcmCosqControlPacketLengthAdjust,
+ &val);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_control_get for bcmCosqControlPacketLengthAdjust failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* If current length does not match the configured length,
+ * configure it now.
+ */
+ if (val != cfg_dpp_hdr_size)
+ {
+ /* Debug */
+ BCM_LOG(INFO, log_id_sw_util,
+ "%s(): modifying value of bcmCosqControlPacketLengthAdjust from %u to %u for pon %u tid %u\n",
+ __FUNCTION__,
+ val,
+ cfg_dpp_hdr_size,
+ p_service_cfg->pon_port,
+ p_service_cfg->tunnel_id);
+
+ /* Adjust the packet length calculated above. This has to
+ * be configured for each queue (cosq) in the voq
+ * group.
+ */
+ for (cosq = 0; cosq < BAL_BCM_QOS_QUEUES_PER_LLID; cosq++)
+ {
+ /* Adjust the packet length calculated above. */
+ sdk_rc = bcm_cosq_control_set(unit,
+ p_service_cfg->ds_qos.voq_gport,
+ cosq,
+ bcmCosqControlPacketLengthAdjust,
+ cfg_dpp_hdr_size);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_control_set for bcmCosqControlPacketLengthAdjust for cosq %d failed with %s for pon %u tid %u\n",
+ __FUNCTION__, cosq, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+
+ /* Exception Block - check for errors from the previous loop */
+ if (rc != BCM_ERR_OK)
+ {
+ /* Error */
+ break;
+ }
+ }
+ } /* End - header adjustment */
+#endif
+ /*
+ * Connect a VOQ to a VOQ connector
+ */
+
+ /* Connect VOQ to the VOQ connector for the ingress direction */
+ connection.flags = BCM_COSQ_GPORT_CONNECTION_INGRESS;
+ connection.remote_modid = gp_bal_bcm_qos_cfg->mod_id;
+ connection.voq = p_service_cfg->ds_qos.voq_gport;
+ connection.voq_connector = p_service_cfg->ds_qos.voq_connector_gport;
+
+ sdk_rc = bcm_cosq_gport_connection_set(unit, &connection);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_connection_set for INGRESS failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* Connect VOQ to the VOQ connector for the egress direction */
+ connection.flags = BCM_COSQ_GPORT_CONNECTION_EGRESS;
+ connection.remote_modid = gp_bal_bcm_qos_cfg->mod_id;
+ connection.voq = p_service_cfg->ds_qos.voq_gport;
+ connection.voq_connector = p_service_cfg->ds_qos.voq_connector_gport;
+
+ sdk_rc = bcm_cosq_gport_connection_set(unit, &connection);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_cosq_gport_connection_set for EGRESS failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ rc = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ } while(0); /* Exception Block - End */
+
+ /* Check for errors */
+ if (rc != BCM_ERR_OK)
+ {
+ /* Failure */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "Downstream QoS setup failed for pon %u tid %u\n",
+ p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Cleanup */
+ bal_sw_dpp_llid_qos_cleanup(unit, p_service_cfg);
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Configure downstream QoS Port Map for a PON Link (LLID)
+ *
+ * This function configures downstream QoS Port Map for a PON Link
+ * (LLID), which is represented by a tunnel ID in ARAD. This sets the
+ * default traffic class (TC) value for VLAN tags being inserted or
+ * modified.
+ *
+ * @param unit SDK unit number
+ * @param p_service_cfg Pointer to the service configuration entry
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_llid_set_qos_port_map(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ int i;
+ /* Parameter checks */
+ BUG_ON(p_service_cfg == NULL);
+
+ /* Set the QoS Port Map for the NNI LIF */
+ for(i = 0; i < p_service_cfg->num_nni_gport; i++)
+ {
+ sdk_rc = bcm_qos_port_map_set(unit, p_service_cfg->nni_gport[i], gp_bal_bcm_qos_cfg->qos_port_map_id, -1);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): bcm_qos_port_map_set for nni_index %d returned with failure code '%s'\n",
+ __FUNCTION__, i, bcm_errmsg(sdk_rc));
+
+ rc = BCM_ERR_INTERNAL;
+ }
+ }
+
+ return rc;
+}
+
+/**************************************************************************/
+/**
+ * @brief Clean up QoS for a PON Link (LLID)
+ *
+ * Each SE and VOQ must be disconnected from the hierarchy before
+ * freeing the SE and VOQ objects.
+ *
+ * @param unit SDK unit number
+ * @param p_service_cfg Pointer to the service configuration entry
+ *
+ **************************************************************************/
+void bal_sw_dpp_llid_qos_cleanup(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ int cosq;
+ bcm_cosq_gport_connection_t connection;
+ bal_sw_dpp_qos_sched_pon_chan ds_pon_chan;
+ bcm_gport_t scheduler_gport;
+
+ /* Parameter checks */
+ BUG_ON(p_service_cfg == NULL);
+
+ /* Store the downstream PON rate, which will be used in several
+ * places throughout this function.
+ */
+ ds_pon_chan = p_service_cfg->ds_qos.pon_chan;
+
+ /* Get the scheduler gport that the VOQs are attached to */
+ if (p_service_cfg->ds_qos.min.rate > 0)
+ {
+ scheduler_gport = p_service_cfg->ds_qos.min.scheduler_gport;
+ }
+ else
+ {
+ scheduler_gport = p_service_cfg->ds_qos.max.scheduler_gport;
+ }
+
+ /* Disconnect VOQ from the VOQ connector for the egress direction */
+ connection.flags = BCM_COSQ_GPORT_CONNECTION_EGRESS | BCM_COSQ_GPORT_CONNECTION_INVALID;
+ connection.remote_modid = gp_bal_bcm_qos_cfg->mod_id;
+ connection.voq = p_service_cfg->ds_qos.voq_gport;
+ connection.voq_connector = p_service_cfg->ds_qos.voq_connector_gport;
+
+ sdk_rc = bcm_cosq_gport_connection_set(unit, &connection);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_connection_set for DISCONNECT EGRESS failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* Disconnect VOQ from the VOQ connector for the ingress direction */
+ connection.flags = BCM_COSQ_GPORT_CONNECTION_INGRESS | BCM_COSQ_GPORT_CONNECTION_INVALID;
+ connection.remote_modid = gp_bal_bcm_qos_cfg->mod_id;
+ connection.voq = p_service_cfg->ds_qos.voq_gport;
+ connection.voq_connector = p_service_cfg->ds_qos.voq_connector_gport;
+
+ sdk_rc = bcm_cosq_gport_connection_set(unit, &connection);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_connection_set for DISCONNECT INGRESS failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* Delete the VOQ */
+ sdk_rc = bcm_cosq_gport_delete(unit, p_service_cfg->ds_qos.voq_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_delete for VOQ failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* Disconnect the VOQ connector */
+ for (cosq = 0; cosq < BAL_BCM_QOS_QUEUES_PER_LLID; cosq++)
+ {
+ sdk_rc = bcm_cosq_gport_detach(unit,
+ scheduler_gport,
+ p_service_cfg->ds_qos.voq_connector_gport,
+ cosq);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_detach for VOQ Connector failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+ }
+
+ /* Delete the VOQ connector */
+ sdk_rc = bcm_cosq_gport_delete(unit, p_service_cfg->ds_qos.voq_connector_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_delete for VOQ Connector failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* If a MIN rate was configured for this PON Link, disconnect the
+ * PON Link scheduler from the MIN Rate scheduler.
+ */
+ if (p_service_cfg->ds_qos.min.rate > 0)
+ {
+ /* Detach from the parent SE */
+ sdk_rc = bcm_cosq_gport_detach(unit,
+ p_service_cfg->ds_qos.min.parent_gport,
+ p_service_cfg->ds_qos.min.scheduler_gport,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_detach for MIN Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+ }
+
+ /* Disconnect the PON Link scheduler from the MAX Rate scheduler. */
+ sdk_rc = bcm_cosq_gport_detach(unit,
+ p_service_cfg->ds_qos.max.parent_gport,
+ p_service_cfg->ds_qos.max.scheduler_gport,
+ 0);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_detach for MAX Rate SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* Delete the PON Link scheduler */
+ sdk_rc = bcm_cosq_gport_delete(unit, scheduler_gport);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(WARNING, log_id_sw_util,
+ "%s(): bcm_cosq_gport_delete for PON Link SE failed with %s for pon %u tid %u\n",
+ __FUNCTION__, bcm_errmsg(sdk_rc), p_service_cfg->pon_port, p_service_cfg->tunnel_id);
+
+ /* Continue cleanup, don't halt processing because of this error */
+ }
+
+ /* Free the voq ID to the free pool */
+ if (ds_pon_chan == BAL_BCM_SCHED_PON_CHAN_10G)
+ {
+ bal_sw_dpp_qos_free_flow_id(&gp_bal_bcm_qos_cfg->flow_id_pool_10g, &p_service_cfg->ds_qos.voq_flow_id);
+ }
+ else
+ {
+ bal_sw_dpp_qos_free_flow_id(&gp_bal_bcm_qos_cfg->flow_id_pool_1g, &p_service_cfg->ds_qos.voq_flow_id);
+ }
+}
+
+/**
+ * @brief Clear statistics for a VOQ
+ *
+ * This function is used to clear VOQ counters
+ *
+ * @param unit SDK unit number
+ * @param gport VOQ gport PON port number
+ *
+ */
+void bal_sw_dpp_qos_clear_voq_stats(int unit, bcm_gport_t gport)
+{
+ int cosq;
+
+ /* Clear all VOQ counters for the VOQ group */
+ for (cosq = 0; cosq < BAL_BCM_QOS_QUEUES_PER_LLID; cosq++)
+ {
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportReceivedBytes, 0);
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportReceivedPkts, 0);
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportEnqueuedBytes, 0);
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportEnqueuedPkts, 0);
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportDroppedBytes, 0);
+ bcm_cosq_gport_stat_set(unit, gport, cosq, bcmCosqGportDroppedPkts, 0);
+ }
+}
+
+/**
+ * @brief Display the qos configuration for each on the console (stdout)
+ */
+void bal_sw_dpp_print_all_port_qos(int unit)
+{
+ bal_sw_dpp_port_qos_cfg *p_port_qos = NULL;
+ uint8_t port_num;
+ uint8_t pon_chan;
+ bcm_gport_t e2e_pon_gport;
+ bcm_gport_t e2e_parent_gport;
+ uint32_t min, flags;
+ uint32_t bandwidth;
+ int32_t max_burst;
+ int32_t mode;
+ int32_t weight;
+ uint8_t wfq_lvl;
+
+ /* Display header */
+ printf("Port\\Chan\tgport\t\tRate (kbps)\tMaxBurst (bytes)\tWeight\n");
+ printf("---------\t-----\t\t-----------\t----------------\t------\n");
+
+ for (port_num=BAL_PON_PORT_START; port_num<=BAL_PON_PORT_END; port_num++)
+ {
+ /* Display Port info */
+
+
+ BCM_COSQ_GPORT_E2E_PORT_SET(e2e_pon_gport, port_num);
+
+ if (BCM_E_NONE == bcm_fabric_port_get(unit,
+ e2e_pon_gport,
+ 0,
+ &e2e_parent_gport))
+ {
+ bandwidth = 0;
+ max_burst = 0;
+ weight = 0;
+
+ bcm_cosq_gport_bandwidth_get(unit,
+ e2e_parent_gport,
+ 0,
+ &min,
+ &bandwidth,
+ &flags);
+
+ printf("Port %u\t0x%08X\t%11u\t%16d\t%6d\n",
+ port_num,
+ 0,
+ bandwidth,
+ 0,
+ 0);
+
+ }
+
+ /* Display PON channel configuration */
+ for (pon_chan = 0; pon_chan < BAL_BCM_SCHED_PON_CHAN_NUM; pon_chan++)
+ {
+ p_port_qos = &gp_bal_bcm_qos_cfg->pon[port_num][pon_chan];
+
+ bandwidth = 0;
+ max_burst = 0;
+ weight = 0;
+
+ /* Bandwidth (rate) */
+ bcm_cosq_gport_bandwidth_get(unit,
+ p_port_qos->pon_chan_scheduler,
+ 0,
+ 0,
+ &bandwidth,
+ 0);
+
+ /* Max Burst */
+ bcm_cosq_control_get(unit,
+ p_port_qos->pon_chan_scheduler,
+ 0,
+ bcmCosqControlBandwidthBurstMax,
+ &max_burst);
+
+ printf("%9s\t0x%08X\t%11u\t%16d\t%6d\n",
+ (pon_chan == BAL_BCM_SCHED_PON_CHAN_10G) ? "10G" : "1G",
+ p_port_qos->pon_chan_scheduler,
+ bandwidth,
+ max_burst,
+ weight);
+
+ printf("%9s\t0x%08X\t%11u\t%16d\t%6d\n",
+ "MIN",
+ p_port_qos->pon_chan_scheduler,
+ 0,
+ 0,
+ 0);
+
+ if (p_port_qos->sched_type == BAL_BCM_SCHED_TYPE_SP)
+ {
+ printf("%9s\t0x%08X\t%11u\t%16d\t%6d\n",
+ " MAX (SP)",
+ p_port_qos->sp_scheduler,
+ 0,
+ 0,
+ 0);
+ }
+ else
+ {
+ printf("%9s\t0x%08X\t%11u\t%16d\t%6d\n",
+ " MAX (WFQ)",
+ 0,
+ 0,
+ 0,
+ 0);
+
+ printf(" WFQ weight [");
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ bcm_cosq_gport_sched_get(unit,
+ p_port_qos->wfq_scheduler[wfq_lvl],
+ 0,
+ &mode,
+ &weight);
+
+ printf("w%u=%u(%u)", wfq_lvl, p_port_qos->pon_chan_weight_cfg[wfq_lvl], weight);
+
+ if (wfq_lvl != BAL_BCM_SCHED_WFQ_PRI_NUM - 1)
+ {
+ printf(", ");
+ }
+ }
+ printf("]\n");
+
+ printf(" WFQ gports [");
+ for (wfq_lvl=0; wfq_lvl<BAL_BCM_SCHED_WFQ_PRI_NUM; wfq_lvl++)
+ {
+ printf("w%u=0x%08X", wfq_lvl, p_port_qos->wfq_scheduler[wfq_lvl]);
+
+ if (wfq_lvl != BAL_BCM_SCHED_WFQ_PRI_NUM - 1)
+ {
+ printf(", ");
+ }
+ }
+ printf("]\n");
+ }
+ }
+
+ printf("\n");
+ }
+}
+
+/**
+ * @brief Display the Flow/VOQ ID pool information
+ */
+void bal_sw_dpp_qos_print_flowid_pool(int unit)
+{
+ bal_sw_dpp_qos_flowid_pool_entry *p_pool_entry = NULL;
+ uint8_t count, free_count;
+ int sdkVal;
+
+ printf("\nvoq ID Information:\n");
+ printf(" Min 10G voq ID = %u\n", DEFAULT_QOS_VOQ_BASE_10G);
+ printf(" Max 10G voq ID = %u\n", DEFAULT_QOS_VOQ_MAX_10G);
+ printf(" Min 1G voq ID = %u\n", DEFAULT_QOS_VOQ_BASE_1G);
+ printf(" Max 1G voq ID = %u\n", DEFAULT_QOS_VOQ_MAX_1G);
+ bcm_fabric_control_get(unit, bcmFabricQueueMin, &sdkVal);
+ printf(" Min VOQ ID = %d\n", sdkVal);
+ bcm_fabric_control_get(unit ,bcmFabricQueueMax, &sdkVal);
+ printf(" Max VOQ ID = %d\n", sdkVal);
+
+ printf("\n10G voq ID Table Info:\n");
+ printf(" next_flow_id_value = %u\n", gp_bal_bcm_qos_cfg->flow_id_pool_10g.next_flow_id_value);
+ printf(" max_value = %u\n", gp_bal_bcm_qos_cfg->flow_id_pool_10g.max_value);
+ printf(" Free 10g voq IDs = ");
+
+ printf(" ");
+ count = 0;
+ free_count = 0;
+ TAILQ_FOREACH(p_pool_entry, &gp_bal_bcm_qos_cfg->flow_id_pool_10g.free_table, entry)
+ {
+ printf("%d, ", p_pool_entry->flow_id);
+
+ if (count < 15)
+ {
+ count++;
+ }
+ else
+ {
+ printf("\n ");
+ count = 0;
+ }
+ free_count++;
+ }
+ printf("\n");
+ printf(" Number of Free 10g voq IDs = %d\n", free_count);
+
+ printf("\n1G voq ID Table Info:\n");
+ printf(" next_flow_id_value = %u\n", gp_bal_bcm_qos_cfg->flow_id_pool_1g.next_flow_id_value);
+ printf(" max_value = %u\n", gp_bal_bcm_qos_cfg->flow_id_pool_1g.max_value);
+ printf(" Free 1g voq IDs = ");
+
+ printf(" ");
+ count = 0;
+ free_count = 0;
+ TAILQ_FOREACH(p_pool_entry, &gp_bal_bcm_qos_cfg->flow_id_pool_1g.free_table, entry)
+ {
+ printf("%d, ", p_pool_entry->flow_id);
+
+ if (count < 15)
+ {
+ count++;
+ }
+ else
+ {
+ printf("\n ");
+ count = 0;
+ }
+ free_count++;
+ }
+ printf("\n");
+ printf(" Number of Free 1g voq IDs = %d\n", free_count);
+}
+
+#endif /* TEST_SW_UTIL_LOOPBACK */
+
+/*@}*/
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_qos.h b/bal_release/src/core/util/switch/dpp/bal_dpp_qos.h
new file mode 100644
index 0000000..28c7e36
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_qos.h
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_qos.h
+ * @brief BAL Switch Util QoS configuration API
+ *
+ * This include file contains the data structures and API for
+ * configuring and managing Quality of Service (QoS) for services on
+ * DPP (DUNE Packet Processor).
+ *
+ *
+ */
+
+/*@{*/
+
+#ifndef _BAL_DPP_QOS_H_
+#define _BAL_DPP_QOS_H_
+
+/* --- project includes --- */
+
+#include "flow_fsm.h"
+
+/* --- local static constants ---*/
+
+/**
+ * @brief Value representing 10G in units of kbps
+ */
+#define BAL_BCM_QOS_10G_kbps 10000000
+
+/**
+ * @brief Value representing 2G (Turbo Mode) in units of kbps
+ */
+#define BAL_BCM_QOS_2G_kbps 2000000
+
+/**
+ * @brief Value representing 1G in units of kbps
+ */
+#define BAL_BCM_QOS_1G_kbps 1000000
+
+/**
+ * @brief Scheduler weight for 10G port scheduler
+ */
+#define BAL_BCM_SCHED_WEIGHT_10G 10
+
+/**
+ * @brief Scheduler weight for 1G port scheduler when Turbo Mode is enabled
+ */
+#define BAL_BCM_SCHED_WEIGHT_2G 2
+
+/**
+ * @brief Scheduler weight for 1G port scheduler (when Turbo Mode is disabled)
+ */
+#define BAL_BCM_SCHED_WEIGHT_1G 1
+
+/**
+ * @brief Scheduler weight used for MIN Rate schedulers
+ */
+#define BAL_BCM_SCHED_WEIGHT_MIN_RATE 1
+
+/**
+ * @brief Scheduler weight used for MAX Rate schedulers
+ */
+#define BAL_BCM_SCHED_WEIGHT_MAX_RATE 1
+
+/**
+ * @brief Number of PON port schedulers
+ */
+#define BAL_BCM_QOS_NUM_PON_PORTS 16
+
+/**
+ * @brief PON port Max value as defined in config.bcm
+ */
+#define BAL_BCM_MAX_PON_NUM 16
+
+/**
+ * @brief Number of queues per PON Link (LLID)
+ */
+#define BAL_BCM_QOS_QUEUES_PER_LLID 4
+
+/**
+ * @brief Default CoS level for untagged frames for 10G queues
+ */
+#define BAL_BCM_QOS_UNTAGGED_DEFAULT_COS_10G 0
+
+/**
+ * @brief Default CoS level for untagged frames for 1G queues
+ */
+#define BAL_BCM_QOS_UNTAGGED_DEFAULT_COS_1G 4
+
+/**
+ * @brief Size of ICT and Shared Vlan tag overhead (in bytes)
+ */
+#define BAL_BCM_QOS_SINGLE_VLAN_TAG_HDR_SIZE 4
+
+/**
+ * @brief Base value for VOQ IDs assigned to the 1G channel
+ *
+ * All VOQ IDs configured on the 1G channel are configured with an
+ * ID value of 0x4000 (16384) and larger.
+ */
+#define BAL_BCM_QOS_VOQ_ID_1G_BASE 0x4000
+
+/**
+ * @brief WFQ maximum value for a weight
+ */
+#define BAL_BCM_SCHED_WFQ_MAX_WEIGHT 4096
+
+/**
+ * @brief Number of WFQ scheduling priority levels
+ */
+#define BAL_BCM_SCHED_WFQ_PRI_NUM 8
+
+/**
+ * @brief Default rate for PON port shaper in kbps (12.5Gbps)
+ */
+#define BAL_BCM_QOS_DEFAULT_PORT_RATE 12500000
+
+/**
+ * @brief Default rate for 10G PON channel shaper in kbps (10.25Gbps)
+ *
+ * The extra 0.25 Gbps allows for some overhead (flow control frames, etc.)
+ */
+#define BAL_BCM_QOS_DEFAULT_10G_CHAN_RATE 10250000
+
+/**
+ * @brief Default rate for 1G PON channel shaper in kbps (2.25Gbps)
+ *
+ * This is set to 2G to allow for Turbo Mode configurations.
+ *
+ * The extra 0.25 Gbps allows for some overhead (flow control frames, etc.)
+ */
+#define BAL_BCM_QOS_DEFAULT_1G_CHAN_RATE 2250000
+
+/**
+ * @brief Credit adjustment to account for scheduler overhead (percentage)
+ *
+ * The adjustment is five percent based on the recommendation from the
+ * Dune team.
+ */
+#define BAL_BCM_QOS_CREDIT_RATE_ADJ 0.05
+
+/**
+ * @brief Shaper adjustment to account for scheduler overhead (percentage)
+ *
+ * The adjustment is one percent based on the recommendation from the
+ * Dune team.
+ */
+#define BAL_BCM_QOS_SHAPER_RATE_ADJ 0.01
+
+/**
+ * @brief Default maximum bust size for PON port shaper in bytes (0 = disabled)
+ */
+#define BAL_BCM_QOS_DEFAULT_MAX_BURST 0
+
+/**
+ * @brief PFC flow control priority value for the 10G channel
+ */
+#define BAL_BCM_QOS_10G_CHAN_PFC 0
+
+/**
+ * @brief PFC flow control priority value for the 1G channel
+ */
+#define BAL_BCM_QOS_1G_CHAN_PFC 1
+
+/**
+ * @brief First logical PON port number
+ */
+#define BAL_PON_PORT_START 0
+
+/**
+ * @brief Last logical PON port number
+ */
+#define BAL_PON_PORT_END 7
+
+/**
+ * @brief The total number of PON ports
+ */
+#define NUM_PON_PORTS (BAL_PON_PORT_END - BAL_PON_PORT_START + 1)
+
+/**
+ * @brief Default DPP header size used by scheduler and rate
+ * calculations.
+ */
+#define DEFAULT_QOS_DPP_PKT_HDR_SIZE 19 /* bytes */
+
+/**
+ * @brief Size of the Dune PP header used to report the Flow ID (for
+ * QoS) in packets trapped to the CPU.
+ */
+#define BAL_BCM_DPP_FLOWID_HDR_SIZE 5
+
+/**
+ * @brief Size of ICT and Shared Vlan tag overhead (in bytes)
+ */
+#define BAL_BCM_QOS_SINGLE_VLAN_TAG_HDR_SIZE 4
+
+
+/**
+ * @brief Default VOQ Identifier Base Value for 10G flows
+ *
+ * 10G VOQ/Flow IDs can range from 3000..16383. This means the blocks
+ * will be allocated in groups of four as follows.
+ *
+ * blk 1 = 3000, 3001, 3002, 3003
+ * blk 2 = 3004, 3005, 3006, 3007
+ * ...
+ * blk last = 16380, 16381, 16382, 16383
+ *
+ * This means that the last ID used to allocate a 10G VOQ group will
+ * be 16380.
+ *
+ * VOQ/flow IDs start at 3000 because the SDK assigns ID values
+ * between 0..2000+ to port queues.
+ */
+#define DEFAULT_QOS_VOQ_BASE_10G 3000
+
+/**
+ * @brief Default VOQ Identifier Maximum Value for 10G flows
+ *
+ * The last available value for 10G flows is 16384 - 4.
+ */
+#define DEFAULT_QOS_VOQ_MAX_10G 16380
+
+/**
+ * @brief Default VOQ Identifier Base Value for 1G flows
+ *
+ * 1G VOQ/Flow IDs can range from 16384..32767. This means the blocks
+ * will be allocated in groups of four as follows.
+ *
+ * blk 1 = 16384, 16385, 16386, 16387
+ * blk 2 = 16388, 16389, 16390, 16392
+ * ...
+ * blk last = 32764, 32765, 32766, 32767
+ *
+ * This means that the last ID used to allocate a 1G VOQ group will be
+ * 32764.
+ */
+#define DEFAULT_QOS_VOQ_BASE_1G 16384
+
+/**
+ * @brief Default VOQ Identifier Maximum Value for 1G flows
+ *
+ * The last available value for 1G flows is 32768 - 4.
+ */
+#define DEFAULT_QOS_VOQ_MAX_1G 32764
+
+/**
+ * @brief Get the PP port number for the specified PON port and
+ * channel (10G vs. 1G)
+ */
+#define BAL_BCM_GET_PP_PORT(pon, chan) ((pon) + (NUM_PON_PORTS * (chan)))
+
+/**
+ * @brief PON channel (a.k.a speed, 10G vs. 1G)
+ *
+ * The 1G PON channel value is also used to represent 2G Turbo Mode
+ * when enabled.
+ */
+typedef enum bal_sw_dpp_qos_sched_pon_chan
+{
+ BAL_BCM_SCHED_PON_CHAN_10G = 0, /**< 10G PON channel */
+ BAL_BCM_SCHED_PON_CHAN_1G = 1, /**< 1G PON channel */
+ BAL_BCM_SCHED_PON_CHAN_NUM
+} bal_sw_dpp_qos_sched_pon_chan;
+
+/**
+ * @brief SLA Type (MIN vs. MAX)
+ */
+typedef enum bal_sw_dpp_qos_sched_sla_type
+{
+ BAL_BCM_SCHED_SLA_MIN_RATE = 0, /**< MIN Rate */
+ BAL_BCM_SCHED_SLA_MAX_RATE = 1, /**< MAX Rate */
+ BAL_BCM_SCHED_SLA_TYPE_NUM
+} bal_sw_dpp_qos_sched_sla_type;
+
+/**
+ * @brief Scheduling Type
+ */
+typedef enum bal_sw_dpp_qos_sched_type
+{
+ BAL_BCM_SCHED_TYPE_SP = 0, /**< Strict priority scheduling */
+ BAL_BCM_SCHED_TYPE_WFQ = 1, /**< Weighted Fair Queuing */
+ BAL_BCM_SCHED_TYPE_NUM
+} bal_sw_dpp_qos_sched_type;
+
+/**
+ * @brief SLA scheduler configuration
+ */
+typedef struct bal_sw_dpp_qos_sched_sla
+{
+ bcm_gport_t scheduler_gport; /**< Scheduler object gport*/
+ bcm_gport_t parent_gport; /**< Parent scheduler gport */
+ uint32_t rate; /**< Rate (or bandwidth) in Kbps */
+ uint32_t burst; /**< Max burst in Kbits */
+ uint8_t traffic_priority; /**< Traffic priority */
+} bal_sw_dpp_qos_sched_sla;
+
+/**
+ * @brief QoS configuration for a PON Link (LLID)
+ */
+typedef struct bal_sw_dpp_llid_qos
+{
+ bal_sw_dpp_qos_sched_pon_chan pon_chan; /**< PON Channel (or speed) the link is connected to */
+ bal_sw_dpp_qos_sched_sla min; /**< MIN Rate configuration */
+ bal_sw_dpp_qos_sched_sla max; /**< MAX Rate configuration */
+ bcm_gport_t voq_connector_gport; /**< VOQ Connector gport */
+ bcm_gport_t voq_gport; /**< VOQ gport */
+ int voq_flow_id; /**< VOQ Flow ID */
+ int voq_id; /**< VOQ ID */
+} bal_sw_dpp_llid_qos;
+
+/**
+ * @brief QoS configuration for a channelized PON port
+ */
+typedef struct bal_sw_dpp_port_qos_cfg
+{
+ bcm_gport_t mod_gport; /**< MOD port for a channelized PON interface */
+ bal_sw_dpp_qos_sched_type sched_type; /**< Scheduling type used on the PON channel (SP vs. WFQ) */
+ bcm_gport_t pon_chan_scheduler; /**< PON channel scheduler */
+ bcm_gport_t sp_scheduler; /**< Strict Priority scheduler for MAX rates (EIRs) */
+ bcm_gport_t wfq_scheduler[BAL_BCM_SCHED_WFQ_PRI_NUM]; /**< WFQ+FQ schedulers for MAX rates (EIRs) */
+ int32_t pon_chan_weight_cfg[BAL_BCM_SCHED_WFQ_PRI_NUM]; /**< Weight configuration for WFQ scheduler */
+} bal_sw_dpp_port_qos_cfg;
+
+/**
+ * @brief Flow/VOQ ID Pool Entry
+ */
+typedef struct bal_sw_dpp_qos_flowid_pool_entry
+{
+ uint32_t flow_id; /**< Flow/VOQ ID value */
+ TAILQ_ENTRY(bal_sw_dpp_qos_flowid_pool_entry) entry; /**< Link into the pool table */
+} bal_sw_dpp_qos_flowid_pool_entry;
+
+/**
+ * @brief Flow/VOQ ID resource pool
+ */
+typedef struct bal_sw_dpp_qos_flowid_pool
+{
+ uint32_t next_flow_id_value; /**< Next flow ID to be allocated */
+ uint32_t max_value; /**< Maximum value for the flow IDs in this pool */
+ TAILQ_HEAD(bal_sw_dpp_qos_flowid_pool_free_head, bal_sw_dpp_qos_flowid_pool_entry) free_table; /**< Flow/VOQ ID free pool */
+} bal_sw_dpp_qos_flowid_pool;
+
+/**
+ * @brief DML BCM APP QoS configuration context definition
+ */
+typedef struct bal_sw_qos_cfg
+{
+ int32_t mod_id; /**< Module ID for this ARAD device */
+ int32_t qos_port_map_id; /**< QoS Port Map Identifier */
+ bal_sw_dpp_port_qos_cfg pon[BAL_BCM_QOS_NUM_PON_PORTS][BAL_BCM_SCHED_PON_CHAN_NUM]; /**< DS QoS configuration for channelized PON ports */
+ bal_sw_dpp_qos_flowid_pool flow_id_pool_10g; /**< Flow/VOQ ID resource pool for 10G flows */
+ bal_sw_dpp_qos_flowid_pool flow_id_pool_1g; /**< Flow/VOQ ID resource pool for 1G flows */
+ int num_channels_per_pon;
+} bal_sw_qos_cfg;
+
+/**
+ * @brief WFQ scheduling configuration
+ *
+ * This structure is used to configure weight values per scheduler
+ * level (i.e., DOCSIS Traffic Priority). The range of weight values
+ * is 0:4K, where values 1:4K are used for WFQ scheduling and a value
+ * of '0' is used for strict priority.
+ */
+typedef struct bal_sw_dpp_qos_wfq_cfg
+{
+ uint32_t weights[BAL_BCM_SCHED_WFQ_PRI_NUM];
+} bal_sw_dpp_qos_wfq_cfg;
+
+extern bal_sw_qos_cfg *gp_bal_bcm_qos_cfg;
+
+/**
+ * @brief Max Number of NNI ports
+ */
+#define BAL_BCM_QOS_NUM_NNI_PORTS 16
+
+/**
+ * @brief Service Configuration Entry Type
+ *
+ * The type of service configuration that the DmlBcmServiceCfgT entry
+ * represents.
+ */
+typedef enum bal_sw_service_type
+{
+ BAL_BCM_SVC_TYPE_NONE, /**< None/uninitialized */
+ BAL_BCM_SVC_TYPE_ICT, /**< Intra-chassis Tagged */
+ BAL_BCM_SVC_TYPE_IP, /**< IP(HSD) */
+ BAL_BCM_SVC_TYPE_PB, /**< MEF Provider Bridging (VLAN tagged) */
+ BAL_BCM_SVC_TYPE_SHVLAN,/**< Shared VLAN */
+ BAL_BCM_SVC_TYPE_LAST /**< Number of bal_sw_service_type_t values */
+} bal_sw_service_type;
+
+/* --- forward declarations --- */
+
+typedef struct bal_sw_dpp_qos_service_cfg
+{
+ uint32_t bal_flow_id;
+ bcm_port_t pon_port; /* logical port number from bal flow config */
+ uint32_t num_nni_gport;
+ bcm_gport_t nni_gport[BAL_BCM_QOS_NUM_NNI_PORTS];
+ uint32_t tunnel_id;
+ bal_sw_dpp_llid_qos ds_qos;
+ bal_sw_service_type service_type;
+} bal_sw_dpp_qos_service_cfg;
+
+
+/* --- function prototypes --- */
+
+bcmos_errno bal_sw_dpp_qos_init(int unit, bal_swapp_port_map_indx pon_mode);
+void bal_sw_dpp_qos_cleanup(int unit);
+bcmos_errno bal_sw_dpp_port_qos_init(int unit, bcm_port_t pon_port, bal_sw_dpp_qos_sched_pon_chan pon_chan);
+void bal_sw_dpp_port_qos_cleanup(int unit, bcm_port_t pon_port, bal_sw_dpp_qos_sched_pon_chan pon_chan);
+bcmos_errno bal_sw_dpp_qos_set_port_bandwidth(int unit, bcm_port_t pon_port, uint32_t bandwidth, uint32_t max_burst);
+bcmos_errno bal_sw_dpp_qos_set_portchan_bandwidth(int unit, bcm_port_t pon_port, bal_sw_dpp_qos_sched_pon_chan pon_chan,
+ uint32_t bandwidth, uint32_t max_burst);
+bcmos_errno bal_sw_dpp_qos_set_ponchan_wfq_cfg(int unit, bcm_port_t pon_port,
+ bal_sw_dpp_qos_sched_pon_chan pon_chan, bal_sw_dpp_qos_wfq_cfg *p_wfq_cfg);
+bcmos_errno bal_sw_dpp_qos_set_llid_bandwidth(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg,
+ bal_sw_dpp_qos_sched_sla_type sla_type, uint32_t bandwidth, uint32_t max_burst);
+bcmos_errno bal_sw_dpp_llid_qos_config(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg_entry);
+bcmos_errno bal_sw_dpp_llid_set_qos_port_map(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg_entry);
+void bal_sw_dpp_llid_qos_cleanup(int unit, bal_sw_dpp_qos_service_cfg *p_service_cfg_entry);
+void bal_sw_dpp_qos_clear_voq_stats(int unit, bcm_gport_t gport);
+void bal_sw_dpp_print_all_port_qos(int unit);
+void bal_sw_dpp_qos_print_flowid_pool(int unit);
+
+#endif /* #ifndef _BAL_DPP_QOS_H_ */
+
+/*@}*/
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.c b/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.c
new file mode 100644
index 0000000..6614b7c
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.c
@@ -0,0 +1,236 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_qos_map.c
+ * @brief BAL Switch Util QoS map management API
+ *
+ * This file contains the data structures and functions for
+ * configuring and managing the pcp bits translation services for
+ * DUNE Pack Processor (DPP).
+ *
+ * The pcp translation service is accomplished using ING ingress vlan translation API
+ * The API required a Qos map table for pcp translatin on a LIF.
+ * This file defines 15 pre-map tables for all known use cases.
+ *
+ * A set of utilities API are included for callers to determine which table to use
+ *
+ * ********************************************************************************
+ *
+ */
+
+/*@{*/
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#include <stdint.h>
+
+#include "bcm_dev_log.h"
+#include "bcmos_errno.h"
+#include "bal_dpp_qos_map.h"
+
+#include "bal_switch_util.h" /* for definition of log_id_sw_util */
+
+#include "bcm/error.h"
+#include "bcm/qos.h"
+
+#define BAL_BCM_PCP_MAP_NUM 15
+#define BAL_BCM_PCP_MAP_ENTRIES 8
+#define BAL_BCM_MAX_PCP_VALUE 7
+#define BAL_BCM_FIXED_PCP_MAP_NUM 8
+
+
+const int g_bal_bcm_qos_pcp_map[BAL_BCM_PCP_MAP_NUM][BAL_BCM_PCP_MAP_ENTRIES] =
+{
+ {0, 0, 0, 0, 0, 0, 0, 0}, /* 0-7 --> 0 */
+ {1, 1, 1, 1, 1, 1, 1, 1}, /* 0-7 --> 1 */
+ {2, 2, 2, 2, 2, 2, 2, 2}, /* 0-7 --> 2 */
+ {3, 3, 3, 3, 3, 3, 3, 3}, /* 0-7 --> 3 */
+ {4, 4, 4, 4, 4, 4, 4, 4}, /* 0-7 --> 4 */
+ {5, 5, 5, 5, 5, 5, 5, 5}, /* 0-7 --> 5 */
+ {6, 6, 6, 6, 6, 6, 6, 6}, /* 0-7 --> 6 */
+ {7, 7, 7, 7, 7, 7, 7, 7}, /* 0-7 --> 7 */
+ {1, 2, 3, 4, 5, 6, 7, 0}, /* 0-6 --> 1-7, 7 ->0 offset = 1 or -7 */
+ {2, 3, 4, 5, 6, 7, 0, 1}, /* 0-5 --> 2-7, 6-7->0-1 offset = 2 or -6 */
+ {3, 4, 5, 6, 7, 0, 1, 2}, /* 0-4 --> 3-7, 5-7->0-2 offset = 3 or -5 */
+ {4, 5, 6, 7, 0, 1, 2, 3}, /* 0-3 --> 4-7, 4-7->0-3 offset = 4 or -4 */
+ {5, 6, 7, 0, 1, 2, 3, 4}, /* 0-2 --> 5-7, 3-7->0-4 offset = 5 or -3 */
+ {6, 7, 0, 1, 2, 3, 4, 5}, /* 0-1 --> 6-7, 2-7->0-5 offset = 6 or -2 */
+ {7, 0, 1, 2, 3, 4, 5, 6}, /* 0 --> 7, 1-7->0-6 offset = 7 or -1 */
+};
+
+static int g_bal_bcm_pcp_remark_map_id[BAL_BCM_PCP_MAP_NUM];
+
+/**************************************************************************/
+/**
+ * @brief Create the PCP remark mapping tables
+ *
+ * This function creates the mapping from PCP bits in the
+ * frames received by DPP to the internal priority in
+ * DPP. The created map id are used in the ingress vlan translation API
+ * to perform PCP bits replacement.
+ *
+ *
+ * @param unit SDK unit number
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_pcp_remark_maps_init(int unit)
+{
+ bcm_error_t sdk_rc = BCM_E_NONE;
+ bcm_qos_map_t l2_in_map;
+ int map_id, pcp;
+ int32_t qos_map_id;
+
+
+ for(map_id=0; map_id < BAL_BCM_PCP_MAP_NUM; map_id++)
+ {
+ /* in case anything goes wrong */
+ g_bal_bcm_pcp_remark_map_id[map_id] = BAL_BCM_INVALID_PCP_MAP_ID;
+
+ /* Create a map object */
+ sdk_rc = bcm_qos_map_create(unit, BCM_QOS_MAP_INGRESS| BCM_QOS_MAP_L2_VLAN_PCP, &qos_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "bcm_qos_map_create failed with %s\n",
+ bcm_errmsg(sdk_rc));
+
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* Create a mapping for each PCP bits value. */
+ for (pcp = 0; pcp < BAL_BCM_PCP_MAP_ENTRIES; pcp++)
+ {
+ bcm_qos_map_t_init(&l2_in_map);
+
+ /* Ingress PCP/CoS value */
+ l2_in_map.pkt_pri = g_bal_bcm_qos_pcp_map[map_id][pcp];
+
+ /* Set internal priority for this ingress pri */
+ l2_in_map.int_pri = pcp;
+
+ /* Set color for this ingress Priority */
+ l2_in_map.color = bcmColorGreen;
+
+ sdk_rc = bcm_qos_map_add(unit, BCM_QOS_MAP_L2_OUTER_TAG|BCM_QOS_MAP_L2|BCM_QOS_MAP_L2_VLAN_PCP, &l2_in_map, qos_map_id);
+ if (sdk_rc != BCM_E_NONE)
+ {
+ /* Error */
+ BCM_LOG(ERROR, log_id_sw_util,
+ "bcm_qos_map_add failed with %s, for pcp %d\n",
+ bcm_errmsg(sdk_rc), pcp);
+
+ return BCM_ERR_INTERNAL;
+ }
+
+ }
+
+ g_bal_bcm_pcp_remark_map_id[map_id] = qos_map_id;
+ }
+ return BCM_ERR_OK;
+}
+
+/**************************************************************************/
+/**
+ * @brief Retrieve PCP remark mapping table ID according to the translation
+ *
+ * This function retrieve the pre-created mapping table id associate with
+ * the translation.
+ * The created map id can be used in the ingress vlan translation API
+ * to perform PCP bits replacement.
+ *
+ * @param src_pcp the pcp value that need to be translated, or -1 for DONTCARE
+ * @param dst_pcp the translated pcp value
+ * @param p_map_id pointer for the retrieved id
+ *
+ * @return bcmos_errno
+ *
+ **************************************************************************/
+bcmos_errno bal_sw_dpp_pcp_remark_map_get(int src_pcp, int dst_pcp, int *p_map_id)
+{
+ int offset;
+ unsigned int indx;
+
+ if(dst_pcp < 0 || dst_pcp > BAL_BCM_MAX_PCP_VALUE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): invalid destination pcp = %d\n", __FUNCTION__, dst_pcp);
+ return BCM_ERR_PARM;
+ }
+ /* if source is DONTCARE, i.e map to a fixed PCP, use the first 8 map tables */
+ if(src_pcp == -1)
+ {
+ *p_map_id = g_bal_bcm_pcp_remark_map_id[dst_pcp];
+ }
+ else
+ {
+ if(src_pcp < 0 || src_pcp > BAL_BCM_MAX_PCP_VALUE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): invalid source pcp = %d\n", __FUNCTION__, src_pcp);
+ return BCM_ERR_PARM;
+ }
+ /* find out the offset between the src_pcp and dst_pcp */
+ offset = dst_pcp - src_pcp;
+ if (offset == 0)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): source pcp %d == destination pcp %d\n", __FUNCTION__, src_pcp, dst_pcp);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ if (offset < 0)
+ {
+ /* see comments in the above map tables */
+ offset += BAL_BCM_PCP_MAP_ENTRIES;
+ }
+
+ indx = offset + BAL_BCM_FIXED_PCP_MAP_NUM - 1;
+ if(indx >= BAL_BCM_PCP_MAP_NUM)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ "%s(): something is wrong, invalid map index = %d\n", __FUNCTION__, indx);
+ return BCM_ERR_INTERNAL;
+ }
+ /* index is 0 based */
+ *p_map_id = g_bal_bcm_pcp_remark_map_id[indx];
+
+ }
+
+ BCM_LOG(INFO, log_id_sw_util,
+ "%s(): pbits translate %d -> %d using bal qos map table %d, id 0x%x\n", __FUNCTION__, src_pcp, dst_pcp, indx, *p_map_id);
+ return BCM_ERR_OK;
+}
+
+#endif /* TEST_SW_UTIL_LOOPBACK */
+
+/*@}*/
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.h b/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.h
new file mode 100644
index 0000000..a73e5b5
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_qos_map.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_dpp_qos_map.h
+ *
+ * @brief bal qos map service function header file for DUNE PACKET PROCESSOR
+ *
+ */
+
+#ifndef _BAL_DPP_QOS_MAP_H_
+#define _BAL_DPP_QOS_MAP_H_
+/*@{*/
+
+#include "bcmos_errno.h"
+
+#define BAL_BCM_INVALID_PCP_MAP_ID -1
+
+bcmos_errno bal_sw_dpp_pcp_remark_maps_init(int unit);
+bcmos_errno bal_sw_dpp_pcp_remark_map_get(int src_pcp, int dst_pcp, int *p_map_id);
+
+/*@}*/
+
+#endif /* _BAL_DPP_QOS_MAP_H */
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.c b/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.c
new file mode 100644
index 0000000..d281e1f
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.c
@@ -0,0 +1,785 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+ /**
+ * @file bal_dpp_vswitch.c
+ * @brief BAL Switch util helper functions that handle vswitch service requests
+ * @addtogroup sw_util
+ */
+
+/*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include <bal_utils_msg.h>
+#include "bcmos_errno.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/types.h>
+#include <sal/core/libc.h>
+#ifndef sal_memset
+#define sal_memset memset
+#endif
+#include <bcm/port.h>
+#include <bcm/vlan.h>
+#include <bcm/error.h>
+#include <bcm/vswitch.h>
+
+#include "bal_switch_flow.h"
+#include "bal_dpp_vswitch.h"
+#include "bal_switch_util.h"
+
+/* A local link list to keep trak of virtual switch service */
+TAILQ_HEAD(bal_sw_vsi_list_head, bal_sw_vsi_service) g_swutil_vsi_list;
+
+/**
+ * @brief The vsi list init function prepare a link list to keep track of
+ * vsi service in the switch util
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_vsi_list_init(void)
+{
+ static uint32_t g_vsi_inited = 0;
+ if(g_vsi_inited == 0)
+ {
+ TAILQ_INIT(&g_swutil_vsi_list);
+ g_vsi_inited = 1;
+ }
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The vsi list search function by LIF tag
+ *
+ * @param p_lif_tag a pointer to the packet tag that need to match the entry in the list
+ * @param p_svc_indx a pointer to store the created service tag index within the vsi
+
+ * @return pointer to an element in the list, NULL if failed
+ */
+static bal_sw_vsi_service *bal_sw_util_dpp_vsi_service_get_by_tag(bal_sw_lif_pkt_tag *p_lif_tag, uint32_t *p_svc_indx)
+{
+ bal_sw_vsi_service *p_entry, *p_temp;
+ int lif_match = 0, svc_idx;
+
+ if(p_svc_indx == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "call VSI service get tag with invalid parameter\n");
+ return NULL;
+ }
+
+ /* clear the storage area */
+ *p_svc_indx = 0;
+
+ TAILQ_FOREACH_SAFE(p_entry, &g_swutil_vsi_list, next_service, p_temp)
+ {
+ for(svc_idx = 0; svc_idx < p_entry->num_tag; svc_idx++)
+ {
+ if( p_entry->pkt_tag[svc_idx].type == p_lif_tag->type)
+ {
+ switch (p_lif_tag->type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ if( p_lif_tag->o_vid == p_entry->pkt_tag[svc_idx].o_vid)
+ {
+ lif_match = 1;
+ }
+ break;
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ if( p_lif_tag->o_vid == p_entry->pkt_tag[svc_idx].o_vid && p_lif_tag->i_vid == p_entry->pkt_tag[svc_idx].i_vid)
+ {
+ lif_match = 1;
+ }
+ break;
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ lif_match = 1;
+ break;
+ default:
+ BCM_LOG(ERROR, log_id_sw_util, "Unsupported packet type %d in LIF info\n", p_lif_tag->type);
+ return NULL;
+ }
+ if(lif_match)
+ {
+ if(p_svc_indx)
+ {
+ *p_svc_indx = svc_idx;
+ }
+ return p_entry;
+ }
+ }
+ }
+ }
+
+ /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
+ return NULL;
+
+}
+
+/*
+ * @brief The vsi list insert function
+ *
+ * @param entry the vsi element to be added in the link list
+ * @return error code
+*/
+static bal_sw_vsi_service *bal_sw_util_vsi_list_insert(bal_sw_vsi_service *p_entry)
+{
+ bal_sw_vsi_service *p_new_entry;
+
+ p_new_entry = bcmos_calloc(sizeof(bal_sw_vsi_service));
+ if(NULL == p_new_entry)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "VSI list insert out of memory\n");
+ return NULL;
+ }
+ *p_new_entry = *p_entry;
+ TAILQ_INSERT_TAIL(&g_swutil_vsi_list, p_new_entry, next_service);
+ return p_new_entry;
+}
+
+/*
+ * @brief The vsi list remove function
+ *
+ * @param p_entry Pointer to the vsi element in the link list result from the search functions
+ * @return error code
+*/
+static bcmos_errno bal_sw_util_vsi_list_remove(bal_sw_vsi_service *p_entry)
+{
+ TAILQ_REMOVE(&g_swutil_vsi_list, p_entry, next_service);
+ bcmos_free(p_entry);
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The vsi create function create a virtual switch service that contains ingress LIF
+ * and virtual switch. This service can later be connected to multiple egress LIF of multiple FLOWs.
+ * The function use the source port and vid information in the bcmbal_flow_cfg as input
+ * The pointer of the created vsi will be returned
+ * Since a vsi can provide multiple srevices, the index to the created service tag is return here
+ *
+ * @param unit switch device id
+ * @param p_flow a pointer to the flow definition which the created service will be based on
+ * @param p_svc_indx a pointer to store the created service tag index within the vsi
+ *
+ * @return pointer to the vsi service list entry, NULL if operation failed
+ */
+
+bal_sw_vsi_service *bal_sw_util_dpp_vsi_service_create(int unit, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_indx)
+{
+ int rv;
+ bal_sw_lif_pkt_tag svc_pkt_tag = {0};
+ bal_sw_vsi_service *p_vsi_service, vsi_svc_elm;
+ bcm_vlan_t vsi;
+ int multicast_id, flags;
+
+ /* p_flow can be NULL when create vswitch for multicast group, service tag will be added when multicast flow is created */
+ if (p_flow == NULL)
+ {
+ BCM_LOG(INFO, log_id_sw_util, "create vsi service with no service tag \n");
+ p_vsi_service = NULL;
+ }
+ else
+ {
+ /* find out if the vsi service already exist */
+ svc_pkt_tag.type = p_flow->data.classifier.pkt_tag_type;
+ svc_pkt_tag.o_vid = p_flow->data.classifier.o_vid;
+ svc_pkt_tag.i_vid = p_flow->data.classifier.i_vid;
+ p_vsi_service = bal_sw_util_dpp_vsi_service_get_by_tag(&svc_pkt_tag, p_svc_indx);
+ }
+
+ /* if no service, create one */
+ if(p_vsi_service == NULL)
+ {
+ /* initialize link list vsi element */
+ memset(&vsi_svc_elm, 0, sizeof (bal_sw_vsi_service));
+ /* if flow (service tag) is specified, fill in the basic info, since it is new, add it to the first tag */
+ if(p_flow)
+ {
+ vsi_svc_elm.pkt_tag[0] = svc_pkt_tag;
+ vsi_svc_elm.num_tag = 1;
+ }
+
+ rv = bcm_vswitch_create(unit, &vsi);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "bcm_vswitch_create failed %d \n", rv);
+ return NULL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, " vswitch 0x%x created\n", vsi);
+ }
+ vsi_svc_elm.vswitch = vsi;
+ /* create two multicast groups (a.k.a. flooding group), one for upstream and one for downstream
+ clean up first, it is OK there is nothing to destroy */
+
+ /* Create the multicast group used for upstream flooding
+ * (PON-->NNI). For the upstream mcast group, the QAX hardware
+ * requires the ID to be set to a value equal to the VSI ID
+ * created above.
+ */
+ multicast_id = vsi + BAL_DPP_US_FLOOD_OFFSET;
+ rv = bcm_multicast_group_is_free(unit, multicast_id);
+ if (rv == BCM_E_EXISTS)
+ {
+ rv = bcm_multicast_destroy(unit, multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "US: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
+ bcm_vswitch_destroy(unit, vsi);
+ return NULL;
+ }
+ }
+ /* flags = ingress replication + fixed id + L2 multicast */
+ flags = BCM_MULTICAST_INGRESS_GROUP | BCM_MULTICAST_WITH_ID | BCM_MULTICAST_TYPE_L2;
+ rv = bcm_multicast_create(unit, flags, &multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "US: in bcm_multicast_create 0x%x w ingress failed %d \n", multicast_id, rv);
+ bcm_vswitch_destroy(unit, vsi);
+ return NULL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "US: vswitch flood group 0x%x created\n", multicast_id);
+ }
+ vsi_svc_elm.us_flood_grp_id = multicast_id;
+
+ /* downstream flooding group */
+ multicast_id = vsi + BAL_DPP_DS_FLOOD_OFFSET;
+ rv = bcm_multicast_group_is_free(unit, multicast_id);
+ if (rv == BCM_E_EXISTS)
+ {
+ rv = bcm_multicast_destroy(unit, multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "DS: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
+ bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
+ bcm_vswitch_destroy(unit, vsi);
+ return NULL;
+ }
+ }
+ flags = BCM_MULTICAST_INGRESS_GROUP | BCM_MULTICAST_WITH_ID | BCM_MULTICAST_TYPE_L2;
+ rv = bcm_multicast_create(unit, flags, &multicast_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "DS: in bcm_multicast_create 0x%x w ingress 2 failed %d \n", multicast_id, rv);
+ bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
+ bcm_vswitch_destroy(unit, vsi);
+ return NULL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "DS: vswitch flood group 0x%x created\n", multicast_id);
+ }
+ vsi_svc_elm.ds_flood_grp_id = multicast_id;
+
+ /* add vsi service to the vsi list */
+ p_vsi_service = bal_sw_util_vsi_list_insert(&vsi_svc_elm);
+ if (p_vsi_service == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "VSI: fail to insert new vsi to the service list\n");
+ bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
+ bcm_multicast_destroy(unit, vsi_svc_elm.ds_flood_grp_id);
+ bcm_vswitch_destroy(unit, vsi_svc_elm.vswitch);
+ return NULL;
+ }
+ p_vsi_service->use_count = 1;
+ }
+ else
+ {
+ p_vsi_service->use_count++;
+ }
+
+ return p_vsi_service;
+}
+
+/**
+ * @brief The vsi destroy function free up Hardare resource of a virtual switch.
+ * It also remove the vsi fromt the service list
+ *
+ * @param unit switch device id
+ * @param p_vsi_svc a pointer to the vsi service
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_vsi_service_destroy(int unit, bal_sw_vsi_service *p_vsi_svc)
+{
+ int rv;
+
+ /* input validation */
+ if (p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "destroy vsi service with invalid parameters \n");
+ return BCM_ERR_PARM;
+ }
+
+ /* only clean up when no more users */
+ if(p_vsi_svc->use_count > 1)
+ {
+ p_vsi_svc->use_count--;
+ return BCM_ERR_OK;
+ }
+
+ /* free up HW resource, continue even if any failed */
+ rv = bcm_multicast_destroy(unit, p_vsi_svc->us_flood_grp_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy US 0x%x failed %d \n", p_vsi_svc->us_flood_grp_id, rv);
+ }
+ rv = bcm_multicast_destroy(unit, p_vsi_svc->ds_flood_grp_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy DS 0x%x failed %d \n", p_vsi_svc->ds_flood_grp_id, rv);
+ }
+ rv = bcm_vswitch_destroy(unit, p_vsi_svc->vswitch);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy vswitch 0x%x failed %d \n", p_vsi_svc->vswitch, rv);
+ }
+
+ /* remove from the service list */
+ rv = bal_sw_util_vsi_list_remove(p_vsi_svc);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy VSI entry failed %d \n", rv);
+ }
+
+ return BCM_ERR_OK;
+}
+
+
+/**
+ * @brief The vsi port_find function search a port from the port list of a vsi service entry.
+ *
+ * @param p_vsi_svc a pointer to the vsi service
+ * @param svc_tag_indx an index to the service within the vsi that a port need to be searched
+ * @param port the ingress port that needs to be located
+ * @param idx pointer to a storage where the array index of the found port will be return
+ *
+ * @return error code
+ */
+
+static bcmos_errno bal_sw_util_dpp_vsi_service_port_find(bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port, uint32_t *idx)
+{
+ int i;
+
+ /* input validation */
+ if (p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "vsi service port find function with invalid parameters \n");
+ return BCM_ERR_PARM;
+ }
+ /* loop through the list */
+ for( i=0; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port; i++)
+ {
+ if(p_vsi_svc->pkt_tag[svc_tag_indx].port[i].port == port)
+ {
+ break;
+ }
+ }
+ if (i == p_vsi_svc->pkt_tag[svc_tag_indx].num_port)
+ {
+ return BCM_ERR_NOENT;
+ }
+ *idx = i;
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The vsi port_find function search a gport from the port list of a vsi service entry.
+ *
+ * @param p_vsi_svc a pointer to the vsi service
+ * @param svc_tag_indx an index to the service within the vsi that a gport need to be searched
+ * @param gport the ingress gport that needs to be located
+ * @param idx pointer to a storage where the array index of the found port will be return
+ *
+ * @return error code
+ */
+
+static bcmos_errno bal_sw_util_dpp_vsi_service_gport_find(bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t gport, uint32_t *idx)
+{
+ int i;
+
+ /* input validation */
+ if (p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "vsi service port find function with invalid parameters \n");
+ return BCM_ERR_PARM;
+ }
+ /* loop through the list */
+ for( i=0; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port; i++)
+ {
+ if(p_vsi_svc->pkt_tag[svc_tag_indx].port[i].gport == gport)
+ {
+ break;
+ }
+ }
+ if (i == p_vsi_svc->pkt_tag[svc_tag_indx].num_port)
+ {
+ return BCM_ERR_NOENT;
+ }
+ *idx = i;
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The vsi port_add function add an ingress port to the vsi service.
+ If the port is already in the vsi, just increase the counter
+ If the port is not in the vsi, create a gport and add it to the US flooding group.
+ This allows the US SPEAK_FIRST packets to be forwarded to the network.
+ *
+ * @param unit switch device id
+ * @param p_vsi_svc a pointer to the vsi service
+ * @param svc_tag_indx an index to the service within the vsi that a port need to be added
+ * @param port the ingress port that needs to be added to the vsi service
+ * @param p_gport a valid pointer where the created/existing gport will be returned.
+ * NULL, if caller don't care the gport
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_vsi_service_port_add(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port, int32_t *p_gport)
+{
+ bcm_vlan_port_t vp;
+ uint32_t idx;
+ int ind, rv;
+ int32_t gport;
+ bcmos_errno ret;
+ int port_encap_id;
+
+ /* input validation */
+ if (p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "vsi service port add function with invalid parameters \n");
+ return BCM_ERR_PARM;
+ }
+ /* check if the port already in the vsi */
+ ret = bal_sw_util_dpp_vsi_service_port_find(p_vsi_svc, svc_tag_indx, port, &idx);
+ /* if port already in the vsi, just increase the counter */
+ if(ret == BCM_ERR_OK)
+ {
+ if(p_gport)
+ {
+ *p_gport = p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].gport;
+ }
+ (p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count)++;
+ return BCM_ERR_OK;
+ }
+
+ /* create the LIF */
+ bcm_vlan_port_t_init(&vp);
+ vp.port = port;
+ /* configure frame match according to the service packet tags */
+ switch(p_vsi_svc->pkt_tag[svc_tag_indx].type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_VLAN;
+ vp.match_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].o_vid;
+ break;
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ vp.criteria = BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED;
+ vp.match_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].o_vid;
+ vp.match_inner_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].i_vid;
+ break;
+ default:
+ /* should not reach here */
+ BCM_LOG(ERROR, log_id_sw_util, "VSI: Unsupported packet type %d \n",p_vsi_svc->pkt_tag[svc_tag_indx].type );
+ return BCM_ERR_INTERNAL;
+ break;
+ }
+
+ vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
+ vp.flags = BCM_VLAN_PORT_OUTER_VLAN_PRESERVE | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;
+
+ rv = bcm_vlan_port_create(unit, &vp);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "VSI: bcm_vlan_port_create port %d, failed %d\n", port, rv);
+ return BCM_ERR_INTERNAL;
+ }
+
+ gport = vp.vlan_port_id;
+
+ // add gport to vswitch
+ rv = bcm_vswitch_port_add(unit, p_vsi_svc->vswitch, gport);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "VSI, bcm_vswitch_port_add for port %d failed %d\n", port, rv);
+ bcm_vlan_port_destroy(unit, gport);
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util, "VSI: bcm_vswitch_port_add for port %d, gport 0x%x\n", port, gport);
+ }
+ /* if caller requre for the gport info, return the gport */
+ if(p_gport)
+ {
+ *p_gport = gport;
+ }
+ /* record the gport into the vsi */
+ ind = p_vsi_svc->pkt_tag[svc_tag_indx].num_port;
+ if (ind == MAX_NET_PORT)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "VSI, reach max port allow\n");
+ bcm_vswitch_port_delete(unit, p_vsi_svc->vswitch, gport);
+ bcm_vlan_port_destroy(unit, gport);
+ return BCM_ERR_NORES;
+ }
+ p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].port = port;
+ p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].gport = gport;
+ p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].use_count = 1;
+ p_vsi_svc->pkt_tag[svc_tag_indx].num_port = ++ind;
+
+ ret = BCM_ERR_OK;
+ do
+ {
+ // update flooding group with phy_port/gport as ingress port
+ rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->us_flood_grp_id, port, gport, &port_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for port failed %d\n", rv);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ /* be a member of the upstream flooding group */
+ rv = bcm_multicast_ingress_add(unit, p_vsi_svc->us_flood_grp_id, port, port_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_add for port failed %d\n", rv);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+
+ /* now set the type of packets that goes to the downstream flooding group */
+ /* forward unknown unicast */
+ rv = bcm_port_control_set(unit, gport, bcmPortControlFloodUnknownUcastGroup, BAL_DPP_DS_FLOOD_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set ucast for nni failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* drop unknown multicast */
+ rv = bcm_port_control_set(unit, gport, bcmPortControlFloodUnknownMcastGroup, BCM_GPORT_BLACK_HOLE);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set mcast for nni failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* forward broadcast */
+ rv = bcm_port_control_set(unit, gport, bcmPortControlFloodBroadcastGroup, BAL_DPP_DS_FLOOD_OFFSET);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set bcast for nni failed %d\n", rv);
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }while(0);
+
+ return ret;
+}
+
+/**
+ * @brief The vsi port_rem function remove an ingress port to the vsi service.
+ *
+ * @param unit switch device id
+ * @param p_vsi_svc a pointer to the vsi service
+ * @param svc_tag_indx an index to the service within the vsi that a port need to be removed
+ * @param gport the ingress gport that needs to be removed from the vsi service
+ *
+ * @return error code
+ */
+
+bcmos_errno bal_sw_util_dpp_vsi_service_port_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t gport)
+{
+ uint32_t idx;;
+ int port_encap_id, rv, i;
+ bcmos_errno ret = BCM_ERR_OK;
+ int port;
+ /* input validation */
+ if (p_vsi_svc == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "vsi service port rem function with invalid parameters \n");
+ return BCM_ERR_PARM;
+ }
+ /* check if the port in the vsi */
+ ret = bal_sw_util_dpp_vsi_service_gport_find(p_vsi_svc, svc_tag_indx, gport, &idx);
+ if(ret != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, vsi service port find for gport %d failed\n", gport);
+ return ret;
+ }
+ /* only remove from the array when no flow reference it */
+ if(p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count > 1)
+ {
+ (p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count)--;
+ return BCM_ERR_OK;
+ }
+
+ port = p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].port;
+
+ /* compact the port list */
+ for(i=idx; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port-1; i++)
+ {
+ p_vsi_svc->pkt_tag[svc_tag_indx].port[i] = p_vsi_svc->pkt_tag[svc_tag_indx].port[i+1];
+ }
+ memset(&p_vsi_svc->pkt_tag[svc_tag_indx].port[i], 0, sizeof (bal_sw_lif_port));
+
+ (p_vsi_svc->pkt_tag[svc_tag_indx].num_port)--;
+
+ ret = BCM_ERR_OK;
+ do
+ {
+ /* find the encap_id */
+ rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->us_flood_grp_id, port, gport, &port_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for port %d failed %d\n", port, rv);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ /* remove from the upstream flooding group */
+ rv = bcm_multicast_ingress_delete(unit, p_vsi_svc->us_flood_grp_id, port, port_encap_id);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_delete for port %d failed %d\n", port, rv);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ rv = bcm_vswitch_port_delete(unit, p_vsi_svc->vswitch, gport);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vswitch_port_delete for port %d failed %d\n", port, rv);
+ ret = BCM_ERR_NOENT;
+ break;
+ }
+ rv = bcm_vlan_port_destroy(unit, gport);
+ if (rv != BCM_E_NONE)
+ {
+ BCM_LOG(WARNING, log_id_sw_util, "Error, bcm_vlan_port_destroy for port %d failed %d\n", port, rv);
+ /* Likely a bug in the 6.5.4 release, igore for now
+ ret = BCM_ERR_NOENT;
+ break;
+ */
+ }
+ }while(0);
+ return ret;
+}
+
+/**
+ * @brief The vsi_service_tag_add function add the service tag of a flow to a vsi target service.
+ *
+ * @param unit switch device id
+ * @param p_vsi_target a pointer to the vsi service
+ * @param p_flow a pointer to a flow that define the service tag need to be added
+ * @param p_svc_tag_indx a pointer to store the return service tag index that just added
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_vsi_service_tag_add(int unit, bal_sw_vsi_service *p_vsi_target, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_tag_indx)
+{
+ bal_sw_lif_pkt_tag svc_pkt_tag = {0};
+ bal_sw_vsi_service *p_vsi_service;
+
+ /* input parameters checking */
+ if (p_flow == NULL || p_vsi_target == NULL || p_svc_tag_indx == NULL)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "invalid parameters when adding vsi service tag \n");
+ return BCM_ERR_PARM;
+ }
+
+ /* find out if the service tag already exist */
+ svc_pkt_tag.type = p_flow->data.classifier.pkt_tag_type;
+ svc_pkt_tag.o_vid = p_flow->data.classifier.o_vid;
+ svc_pkt_tag.i_vid = p_flow->data.classifier.i_vid;
+ p_vsi_service = bal_sw_util_dpp_vsi_service_get_by_tag(&svc_pkt_tag, p_svc_tag_indx);
+ if (p_vsi_service)
+ {
+ /* if the service tag already exist in the system, it has to be within the same vsi.
+ We don't allow same service tag to be serviced by more than one vsi
+ */
+ if(p_vsi_service != p_vsi_target)
+ {
+ return BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ return BCM_ERR_OK;
+ }
+ }
+
+ /* now add the tag to the list */
+ p_vsi_target->pkt_tag[p_vsi_target->num_tag] = svc_pkt_tag;
+ *p_svc_tag_indx = p_vsi_target->num_tag;
+ p_vsi_target->num_tag ++;
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The vsi_service_tag_rem function remove the service tag index by svc_tag_indx from a vsi service.
+ *
+ * @param unit switch device id
+ * @param p_vsi_svc a pointer to the vsi service
+ * @param svc_tag_indx a service tag index point to the service tag list that need to be removed
+ *
+ * @return error code
+ */
+bcmos_errno bal_sw_util_dpp_vsi_service_tag_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx)
+{
+ int i;
+ /* input parameters checking */
+ if (p_vsi_svc == NULL || p_vsi_svc->num_tag <= svc_tag_indx)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, "invalid parameters when removing vsi service tag \n");
+ return BCM_ERR_PARM;
+ }
+ /* compact the tag list */
+ for(i=svc_tag_indx; i<p_vsi_svc->num_tag-1; i++)
+ {
+ p_vsi_svc->pkt_tag[i] = p_vsi_svc->pkt_tag[i+1];
+ }
+ memset(&p_vsi_svc->pkt_tag[i], 0, sizeof (bal_sw_lif_pkt_tag));
+
+ (p_vsi_svc->num_tag)--;
+ return BCM_ERR_OK;
+}
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+/*@}*/
+
+
diff --git a/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.h b/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.h
new file mode 100644
index 0000000..43ddd93
--- /dev/null
+++ b/bal_release/src/core/util/switch/dpp/bal_dpp_vswitch.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+ /**
+ * @file bal_dpp_vswitch.h
+ * @brief BAL Switch util helper functions prototype
+ * @addtogroup sw_util
+ */
+#ifndef _BAL_DPP_VSWITCH_H_
+#define _BAL_DPP_VSWITCH_H_
+
+#include "bal_switch_flow.h"
+
+/* DPP multicast group offsets - use vsi as base */
+/* The mc group should not overlap, so the following setting limit system to 0x1000 vsi */
+#define BAL_DPP_US_FLOOD_OFFSET 0x0
+#define BAL_DPP_DS_FLOOD_OFFSET 0x1000
+#define BAL_DPP_MC_OFFSET 0x2000
+
+#define MAX_SVC_PER_VSI 8
+
+/*@{*/
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+typedef struct bal_sw_lif_port bal_sw_lif_port;
+struct bal_sw_lif_port
+{
+ uint32_t port;
+ uint32_t gport;
+ int32_t use_count;
+};
+
+typedef struct bal_sw_lif_pkt_tag bal_sw_lif_pkt_tag;
+struct bal_sw_lif_pkt_tag
+{
+ uint32_t type;
+ uint32_t o_vid;
+ uint32_t i_vid;
+ uint32_t num_port;
+ bal_sw_lif_port port[MAX_NET_PORT];
+};
+
+typedef struct bal_sw_vsi_service bal_sw_vsi_service;
+struct bal_sw_vsi_service
+{
+ uint32_t num_tag;
+ bal_sw_lif_pkt_tag pkt_tag[MAX_SVC_PER_VSI];
+ uint32_t vswitch;
+ uint32_t us_flood_grp_id;
+ uint32_t ds_flood_grp_id;
+ int32_t use_count;
+ TAILQ_ENTRY(bal_sw_vsi_service) next_service;
+};
+
+extern bcmos_errno bal_sw_util_dpp_vsi_service_port_add(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port, int32_t *p_gport);
+extern bcmos_errno bal_sw_util_dpp_vsi_service_port_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port);
+extern bcmos_errno bal_sw_util_dpp_vsi_service_tag_add(int unit, bal_sw_vsi_service *p_vsi_svc, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_tag_indx);
+extern bcmos_errno bal_sw_util_dpp_vsi_service_tag_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx);
+extern bal_sw_vsi_service *bal_sw_util_dpp_vsi_service_create(int unit, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_tag_indx);
+extern bcmos_errno bal_sw_util_dpp_vsi_service_destroy(int unit, bal_sw_vsi_service *p_vsi_svc);
+extern bcmos_errno bal_sw_util_vsi_list_init(void);
+
+#endif /* TEST_SW_UTIL_LOOPBACK */
+/*@}*/
+#endif
diff --git a/bal_release/src/core/util/switch/esw/Makefile b/bal_release/src/core/util/switch/esw/Makefile
new file mode 100644
index 0000000..88473f7
--- /dev/null
+++ b/bal_release/src/core/util/switch/esw/Makefile
@@ -0,0 +1,43 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+# BAL Switch Util ESW
+MOD_NAME = switch_util_esw
+MOD_TYPE = lib
+MOD_DEPS = dev_log utils bal_api bal_app_utils
+srcs = bal_esw_acc_term.c bal_esw_flow.c
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../../main -I$(SRC_DIR)/..
+
+ifeq ("$(TEST_SW_UTIL_LOOPBACK)", "y")
+ MOD_DEFS += -DTEST_SW_UTIL_LOOPBACK
+else
+ MOD_DEPS += switch_sdk
+endif
+
diff --git a/bal_release/src/core/util/switch/esw/bal_esw_acc_term.c b/bal_release/src/core/util/switch/esw/bal_esw_acc_term.c
new file mode 100755
index 0000000..ef9ded3
--- /dev/null
+++ b/bal_release/src/core/util/switch/esw/bal_esw_acc_term.c
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+#include "bal_esw_acc_term.h"
+
+#include <bcm/types.h>
+#include <bcm/port.h>
+
+/**
+ * @file bal_esw_acc_term.c
+ * @brief BAL Switch util functions that handle access terminal requests on Enterprise SWitch
+ * @addtogroup sw_util
+ *
+ */
+
+/*@{*/
+
+
+/**
+ * @brief Connect access terminal with ESW as part of the components
+ *
+ * This routine is called by sw_util_access_terminal_connect in the BAL core
+ * to execute ESW specific API for access_terminal_connect request
+ *
+ * @param p_net_map Pointer to the net ports mapping from logical numbrer to physical number
+ * @param p_pon_map Pointer to the pon ports mapping from logical numbrer to physical number
+ * @return bcmos_errno
+ */
+bcmos_errno sw_util_esw_acc_term_connect(bal_swapp_port *p_net_map, bal_swapp_port *p_pon_map )
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ int rc = 0;
+ bal_swapp_port *port;
+ bcm_pbmp_t pon_pbmp, net_pbmp;
+
+ BCM_LOG(INFO, log_id_sw_util, " KT2 - Got a access terminal CONNECT\n");
+
+ BCM_PBMP_CLEAR(pon_pbmp);
+ BCM_PBMP_CLEAR(net_pbmp);
+
+ /* setup the device ID - This is very hardware specific */
+ port = p_net_map;
+ /* -1 indicate the end of table */
+ while(port->pbm_id != -1)
+ {
+ /* add port to the net list */
+ BCM_PBMP_PORT_ADD(net_pbmp, port->pbm_id);
+ port++;
+ }
+
+ port = p_pon_map;
+ while(port->pbm_id != -1)
+ {
+ /* add port to the pon list */
+ BCM_PBMP_PORT_ADD(pon_pbmp, port->pbm_id);
+ port++;
+ }
+
+ /* set up the valid egress ports for pon facing ports */
+ port = p_pon_map;
+ while(port->pbm_id != -1)
+ {
+ rc = bcm_port_egress_set(port->device_id, port->pbm_id, 0, /* modid */ net_pbmp);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util, " ESW - Add port %d to pon interface failed\n", port->pbm_id );
+ }
+ port++;
+ }
+
+ /* set up the valid egress ports for net facing ports */
+ port = p_net_map;
+ while(port->pbm_id != -1)
+ {
+ rc = bcm_port_egress_set(port->device_id, port->pbm_id, 0, /* modid */ pon_pbmp);
+ if (rc)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ESW - Add port %d to net interface failed\n", port->pbm_id );
+ }
+ port++;
+ }
+
+ /* translate ING error code to BAL error code */
+ if (rc)
+ {
+ ret = BCM_ERR_INTERNAL;
+ }
+ else
+ {
+ ret = BCM_ERR_OK;
+ }
+ return ret;
+}
+
+/*@}*/
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
diff --git a/bal_release/src/core/util/switch/esw/bal_esw_acc_term.h b/bal_release/src/core/util/switch/esw/bal_esw_acc_term.h
new file mode 100755
index 0000000..1343f68
--- /dev/null
+++ b/bal_release/src/core/util/switch/esw/bal_esw_acc_term.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_esw_acc_term.h
+ *
+ * @brief bal switch esw util access terminal service function header file
+ *
+ * @addtogroup sw_util
+ */
+
+#ifndef _BAL_ESW_ACC_TERM_H_
+#define _BAL_ESW_ACC_TERM_H_
+
+/*@{*/
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+#include "bal_switch_acc_term.h"
+
+extern bcmos_errno sw_util_esw_acc_term_connect(bal_swapp_port *p_net_map, bal_swapp_port *p_pon_map);
+
+/*@}*/
+
+#endif
diff --git a/bal_release/src/core/util/switch/esw/bal_esw_flow.c b/bal_release/src/core/util/switch/esw/bal_esw_flow.c
new file mode 100755
index 0000000..27d33af
--- /dev/null
+++ b/bal_release/src/core/util/switch/esw/bal_esw_flow.c
@@ -0,0 +1,555 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_esw_flow.c
+ * @brief BAL Switch util functions that handle flow requests
+ * @addtogroup sw_util
+ */
+
+ /*@{*/
+#include <bal_common.h>
+#include <bcm_dev_log.h>
+#include <bal_msg.h>
+#include "bal_switch_flow.h"
+#include "flow_fsm.h"
+#include "bcmos_errno.h"
+#include "bal_switch_util.h"
+
+#ifndef TEST_SW_UTIL_LOOPBACK
+#include <bcm/types.h>
+#include <sal/core/libc.h>
+#ifndef sal_memset
+#define sal_memset memset
+#endif
+#include <bcm/port.h>
+#include <bcm/vlan.h>
+#include <bcm/field.h>
+#include <bcm/error.h>
+#include <sal/core/libc.h>
+
+#include "bal_switch_acc_term.h"
+#include "bal_esw_flow.h"
+/**
+ * @brief The acl add function add an Access Control Rule in the switch VCAP/ICAP/ECAP
+ * to perform action based on flow classifier
+ *
+ * @param unit the switch unit this rule is to be added
+ * @param p_flow a pointer to the flow definition the created rule will be based on
+ * @return error code
+ */
+static bcm_field_group_t esw_group_id = 0;
+/* add an ingress ACL rule */
+static bcmos_errno bal_swapp_esw_acl_add(int unit, bcmbal_flow_cfg *p_flow)
+{
+ uint32_t ret, j;
+ uint32_t nni_phy;
+ int vid;
+ bcm_field_qset_t qset;
+ bcm_field_entry_t eid;
+ bcm_mac_t bcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ bcm_mac_t dst_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ do
+ {
+ vid = p_flow->data.classifier.o_vid;
+
+ /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
+ /* The KT2 resources allow only limit number of qset - indexed by esw_group_id, create qset when necessary */
+ if (0 == esw_group_id)
+ {
+ BCM_FIELD_QSET_INIT(qset);
+ BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageLookup);
+ BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyOuterVlan);
+ BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort);
+ BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyDstMac);
+ ret = bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &esw_group_id);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to create field - %d\n", ret );
+ break;
+ }
+ }
+
+ /* if action is to drop broadcast, add an ACL in nni VCAP to drop it */
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST)
+ {
+ /* loop through all nni ports */
+ for(j=0; -1 != (nni_phy = bal_bcm_net_inf_pbm_get(j)); j++)
+ {
+ if ( bal_bcm_net_inf_dev_get(j) != unit)
+ {
+ continue;
+ }
+
+ ret = bcm_field_entry_create(unit, esw_group_id, &eid);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to create field entry for port %d - ret = %d\n", nni_phy, ret );
+ break;
+ }
+
+ ret = bcm_field_qualify_DstMac(unit, eid, bcast_mac, dst_mask);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to set field dst mac qualifier %d - ret = %d\n", nni_phy, ret );
+ break;
+ }
+
+ ret = bcm_field_qualify_OuterVlanId(unit, eid, vid, 0xffff);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to set field outer vlan qualifier %d - ret = %d\n", nni_phy, ret );
+ break;
+ }
+ ret = bcm_field_action_add(unit, eid, bcmFieldActionDrop, 0, 0);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to add action to the field entry %d - ret = %d\n", nni_phy, ret );
+ break;
+ }
+
+ ret = bcm_field_entry_install(unit, eid);
+ if (ret != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to install field entry %d - ret = %d\n", nni_phy, ret );
+ break;
+ }
+ } /* for loop */
+ } /* if drop bcast */
+ } while(0);
+
+
+ if (ret != BCM_E_NONE)
+ {
+ return BCM_ERR_INTERNAL;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/**
+ * @brief The ingress vlan translation function program switch to
+ * translate packet vlan attributes before the switch vaidate the
+ * vlan membership of the packets
+ * @param unit the switch unit this translation is perfromed
+ * @param p_flow a pointer to the flow that contains translation action
+ * @return error code
+ */
+static bcmos_errno bal_swapp_esw_ivlanx(int unit, bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcm_gport_t pon_gport;
+ uint32_t pon_phy_pbm;
+ int bcm_rc;
+
+ /* find out which PON this action is to be performed */
+ /* map pon logical port to physical port */
+ pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
+ /* create local gport based on pon physical port number */
+ BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm);
+
+ do
+ {
+ /* For TR-156 1:1 uptream single tagged packets,
+ S-tag add acton is performed in the INGRESS vlan translator.
+ */
+ if (BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
+ {
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG )
+ {
+ uint32_t u_ovid, u_ivid;
+ bcm_vlan_action_set_t u_action;
+ bcm_vlan_action_set_t_init(&u_action);
+
+ /* set gpon ingress translaton to add outer tag on upstream packets */
+ u_action.new_outer_vlan = p_flow->data.action.o_vid;
+ u_action.priority = p_flow->data.action.o_pbits;
+
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
+ u_action.ot_outer = bcmVlanActionAdd;
+ u_action.ot_outer_pkt_prio = bcmVlanActionReplace;
+ u_ovid = p_flow->data.classifier.o_vid;
+ u_ivid = BCM_VLAN_NONE;
+ break;
+ default: /* not supported, goto while(0) */
+ u_ovid = BCM_VLAN_NONE;
+ u_ivid = BCM_VLAN_NONE;
+ ret = BCM_ERR_INTERNAL;
+ continue;
+ }
+ /* enable ingress vlan translation on specified port */
+ bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanTranslateIngressEnable, 1);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to enable ingress vlan translation on port %d - %d\n",
+ pon_phy_pbm, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* set the outer vlan id as lookup key - i.e. packet filtering key */
+ bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanPortTranslateKeyFirst, bcmVlanTranslateKeyOuter);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to set upstream lookup key on port %d - %d\n",
+ pon_phy_pbm, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* install the action into ingress vlan translation table */
+ bcm_rc = bcm_vlan_translate_action_add(unit, pon_gport, bcmVlanTranslateKeyOuter, u_ovid, u_ivid, &u_action);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to set ingress action on port %d - %d\n",
+ pon_phy_pbm, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow upstream action 0x%x not supported\n", p_flow->data.action.cmds_bitmask);
+
+ ret = BCM_ERR_NOT_SUPPORTED;
+ }
+ }
+
+ } while(0);
+
+ return ret;
+}
+
+/**
+ * @brief The engress vlan translation function program switch to
+ * translate packet vlan attributes before the packets were sent out
+ *
+ * @param unit the switch unit this translation is perfromed
+ * @param p_flow a pointer to the flow that contains translation action
+ * @return error code
+ */
+static bcmos_errno bal_swapp_esw_evlanx(int unit, bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcm_gport_t pon_gport;
+ uint32_t pon_phy_pbm;
+ int bcm_rc;
+
+ /* find out which PON this action is to be performed */
+ /* map pon logical port to physical port */
+ pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
+ /* create local gport based on pon physical port number */
+ BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm);
+
+ do
+ {
+ /* For TR-156 1:1 downstream double tagged packets,
+ S-tag remove acton is performed in the EGRESS vlan translator.
+ */
+ if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow->key.flow_type)
+ {
+
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG )
+ {
+ /* set gpon egress translaton to drop outer tag of double tag downstream packets */
+ uint32_t d_ovid, d_ivid;
+ bcm_vlan_action_set_t d_action;
+ bcm_vlan_action_set_t_init(&d_action);
+ switch(p_flow->data.classifier.pkt_tag_type)
+ {
+ case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
+ d_action.dt_outer = bcmVlanActionDelete;
+ d_ovid = p_flow->data.classifier.o_vid;
+ d_ivid = p_flow->data.classifier.i_vid;
+ break;
+
+ default: /* not supported, goto while(0) */
+ d_ovid = BCM_VLAN_NONE;
+ d_ivid = BCM_VLAN_NONE;
+ ret = BCM_ERR_INTERNAL;
+ continue;
+ }
+ /* enable egress vlan translation on specified port */
+ bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanTranslateEgressEnable, 1);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to enable egress vlan translation on port %d - %d\n",
+ pon_phy_pbm, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+
+ /* install the action into egress vlan translation table */
+ bcm_rc = bcm_vlan_translate_egress_action_add(unit, pon_gport, d_ovid, d_ivid, &d_action);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to set egress action on port %d - %d\n",
+ pon_phy_pbm, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ }
+ else
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow downstream action 0x%x not supported\n", p_flow->data.action.cmds_bitmask);
+
+ ret = BCM_ERR_NOT_SUPPORTED;
+ }
+
+ }
+
+ } while(0);
+
+ return ret;
+}
+
+
+/**
+ * @brief The flow add function program KT2 to forward packets that have
+ * specified attributes to the designated ports.
+ * The packets is modified before egress
+ * On the downstream, an access id (outer vlan tag) is added to the packets
+ * On the upstream, outer vlan tag (access id) is removed from the packets
+ *
+ * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
+ * @param p_flow A pointer to the requested add flow info
+ * @return error code
+ */
+bcmos_errno bal_sw_util_esw_flow_add(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcm_gport_t pon_gport;
+ uint32_t pon_phy_pbm;
+ bcm_vlan_t vlan_id;
+ bcm_gport_t nni_gport;
+ uint32_t nni_phy_pbm;
+ int ii;
+ int bcm_rc;
+ int unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id);
+
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got an ESW flow request - iwf_mode=%d flow_id=%d sub_port=%d svc_id=%d\n",
+ iwf_mode,
+ p_flow->key.flow_id, p_flow->data.access_int_id, p_flow->data.svc_port_id);
+ BCM_LOG(DEBUG, log_id_sw_util,
+ " classifier - mask=0x%llx otpid=%x itpid=%x ovid=%x ivid=%x\n",
+ (unsigned long long)p_flow->data.classifier.presence_mask,
+ p_flow->data.classifier.o_tpid, p_flow->data.classifier.i_tpid,
+ p_flow->data.classifier.o_vid, p_flow->data.classifier.i_vid);
+
+ /*
+ * First, validate that the specified PON has at least one NNI port on the same device.
+ * If not, return an error, as this is not supported.
+ */
+ ii = 0;
+ ret = BCM_ERR_NOT_SUPPORTED;
+ /* walk through the entire mapping table */
+ while(-1 != bal_bcm_net_inf_pbm_get(ii))
+ {
+ if(bal_bcm_net_inf_dev_get(ii) == unit)
+ {
+ ret = BCM_ERR_OK;
+ break;
+ }
+ ii++; /* Next NNI */
+ }
+
+ do
+ {
+ /*
+ * Check return code from device check above. Return if there was an error.
+ */
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " ERROR: no network port is on the same device as access port %d\n", p_flow->data.access_int_id);
+ break;
+ }
+
+ /* create vlan domain for this flow */
+ vlan_id = (bcm_vlan_t)p_flow->data.classifier.o_vid;
+ bcm_rc = bcm_vlan_create(unit, vlan_id);
+
+ /* if OK or already existed, continue */
+ if (bcm_rc != BCM_E_NONE && bcm_rc != BCM_E_EXISTS)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " failed to create vlan %d on unit %d - bcm_rc:%d\n", vlan_id, unit, bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ else
+ {
+ BCM_LOG(INFO, log_id_sw_util,
+ " vlan %d %s on unit %d - bcm_rc:%d\n",
+ vlan_id,
+ (BCM_E_EXISTS == bcm_rc) ? "reused" : "created",
+ unit,
+ bcm_rc );
+ }
+
+ /* map pon logical port to physical port */
+ pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
+
+ /* create gport based on pon physical port number */
+ BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm);
+
+ /* add the specified pon to vlan */
+ bcm_rc = bcm_vlan_gport_add(unit, vlan_id, pon_gport, BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP);
+
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to add pon %d (pbm %d, gport %d) into vlan %d - %d\n",
+ p_flow->data.access_int_id, pon_phy_pbm, pon_gport, vlan_id, bcm_rc );
+
+ ret = BCM_ERR_INTERNAL;
+
+ break;
+ }
+
+ /* Add all the NNI ports that are on the same device to the vlan as well */
+
+ ii = 0; /* Start with the first NNI logical interface */
+
+ /* map nni logical ports to physical ports */
+ while(-1 != (nni_phy_pbm = bal_bcm_net_inf_pbm_get(ii)))
+ {
+ if ( bal_bcm_net_inf_dev_get(ii) != unit)
+ {
+ continue;
+ }
+ /* create gport based on nni physical port number */
+ BCM_GPORT_LOCAL_SET(nni_gport, nni_phy_pbm);
+
+ bcm_rc = bcm_vlan_gport_add(unit, vlan_id, nni_gport, BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP);
+
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to add nni %d (pbm %d, gport %d) into vlan %d - %d\n",
+ ii, nni_phy_pbm, nni_gport, vlan_id, bcm_rc );
+
+ ret = BCM_ERR_INTERNAL;
+
+ break;
+ }
+
+ ii++; /* Next NNI */
+ }
+
+ /* perform the ACTION */
+ if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)
+ /* && BCMOS_TRUE == BCMBAL_ATTRIBUTE_CFG_PROP_IS_SET(&p_flow->data.action, action, action_cmds_bitmask) */
+ )
+ {
+ BCM_LOG(INFO, log_id_sw_util,
+ " Got a flow action - flow type = %d, cmd=%d in_ovid=%d, out_ovid=%d\n",
+ p_flow->key.flow_type, p_flow->data.action.cmds_bitmask,
+ p_flow->data.classifier.i_vid, p_flow->data.classifier.o_vid);
+
+ /* enable vlan translation */
+ bcm_rc = bcm_vlan_control_set(unit, bcmVlanTranslate, 1);
+ if (bcm_rc != BCM_E_NONE)
+ {
+ BCM_LOG(ERROR, log_id_sw_util,
+ " flow fail to enable vlan translation - %d\n",
+ bcm_rc );
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ /* For TR-156 1:1 downstream,
+ ACTIONs are performed on the EGRESS vlan translator.
+ For TR-156 1:1 upstream,
+ ACTIONs are perform on the INGRESS vlan translator.
+ For TR-156 N:1 there is no actions for switch
+ The outer tag adding is per PON base, i.e. upstream packets with same
+ inner vid can add different outer vid based on receiving PON
+ */
+ if (BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
+ {
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG )
+ {
+ ret = bal_swapp_esw_ivlanx(unit, p_flow);
+ }
+ }
+ else if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow->key.flow_type)/* downstream */
+ {
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG )
+ {
+ ret = bal_swapp_esw_evlanx(unit, p_flow);
+ }
+ }
+ else /* broadcast */
+ {
+ if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST)
+ {
+ ret = bal_swapp_esw_acl_add(unit, p_flow);
+ }
+
+ }
+ } /* end if ACTION set */
+
+ } while(0);
+
+
+ return ret;
+}
+
+/**
+ * @brief The flow remove function remove switch resource that were allocated during ADD
+ *
+ * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
+ * @param p_flow A pointer to the requested add flow info
+ * @return error code
+ */
+bcmos_errno bal_sw_util_esw_flow_remove(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow)
+{
+ return BCM_ERR_OK;
+}
+
+#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
+
+/*@}*/
diff --git a/bal_release/src/core/util/switch/esw/bal_esw_flow.h b/bal_release/src/core/util/switch/esw/bal_esw_flow.h
new file mode 100755
index 0000000..3146222
--- /dev/null
+++ b/bal_release/src/core/util/switch/esw/bal_esw_flow.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_esw_flow.h
+ *
+ * @brief Function Prototype for switch app flow functions for ESW
+ *
+ * @ingroup switch_app
+ */
+
+#ifndef _BAL_ESW_FLOW_H_
+#define _BAL_ESW_FLOW_H_
+
+#include "bal_switch_util.h"
+
+/*@{*/
+
+bcmos_errno bal_sw_util_esw_flow_add(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow);
+bcmos_errno bal_sw_util_esw_flow_remove(bcmbal_iwf_mode iwf_mode, bcmbal_flow_cfg *p_flow);
+
+/*@}*/
+
+#endif
diff --git a/bal_release/src/datamodel/bal.objset b/bal_release/src/datamodel/bal.objset
new file mode 100644
index 0000000..e8801cf
--- /dev/null
+++ b/bal_release/src/datamodel/bal.objset
@@ -0,0 +1,3901 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ElementSet Version="2.1">
+ <KeyValuePairs>
+ <KeyValuePair>
+ <Key>SupportsAutoCfg</Key>
+ <Value>False</Value>
+ </KeyValuePair>
+ </KeyValuePairs>
+ <Label>
+ <ShortName>bal</ShortName>
+ <LongName>BAL</LongName>
+ <Description>BAL Object Model</Description>
+ </Label>
+ <CustomTypes>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>access_id</ShortName>
+ <LongName>Access ID</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>action</ShortName>
+ <LongName>action</LongName>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>cmds_bitmask</ShortName>
+ <LongName>Commands bitmask</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>action_cmd_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>o_vid</ShortName>
+ <LongName>Outer vid</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>o_pbits</ShortName>
+ <LongName>Outer pbits</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>o_tpid</ShortName>
+ <LongName>Outer tpid</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_vid</ShortName>
+ <LongName>Inner vid</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_pbits</ShortName>
+ <LongName>Inner pbits</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_tpid</ShortName>
+ <LongName>Inner tpid</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>action_cmd_id</ShortName>
+ <LongName>action_cmd_id</LongName>
+ </Label>
+ <Flags>True</Flags>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>add_outer_tag</ShortName>
+ <LongName>Add outer tag</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>remove_outer_tag</ShortName>
+ <LongName>Remove outer tag</LongName>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>xlate_outer_tag</ShortName>
+ <LongName>Translate outer tag</LongName>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>xlate_two_tags</ShortName>
+ <LongName>Translate two tags</LongName>
+ </Label>
+ <Value>8</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>discard_ds_bcast</ShortName>
+ <LongName>Discard downstream broadcast</LongName>
+ <Description>Used to satisfy TR-156 Issue 3 R-111</Description>
+ </Label>
+ <Value>16</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>discard_ds_unknown</ShortName>
+ <LongName>Discard downstream unknown</LongName>
+ <Description>Used to satisfy TR-156 Issue 3 R-109</Description>
+ </Label>
+ <Value>32</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>add_two_tags</ShortName>
+ <LongName>Add two tags</LongName>
+ </Label>
+ <Value>64</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>remove_two_tags</ShortName>
+ <LongName>Remove two tags</LongName>
+ </Label>
+ <Value>128</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>remark_pbits</ShortName>
+ <LongName>Remark pbits</LongName>
+ <Description>Set the outer tag pbits</Description>
+ </Label>
+ <Value>256</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>copy_pbits</ShortName>
+ <LongName>Copy pbits</LongName>
+ <Description>Copy the inner pbits to outer pbits</Description>
+ </Label>
+ <Value>512</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>reverse_copy_pbits</ShortName>
+ <LongName>Reverse copy pbits</LongName>
+ <Description>Copy the outer pbits to inner pbits</Description>
+ </Label>
+ <Value>1024</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>dscp_to_pbits</ShortName>
+ <LongName>Dscp to pbits</LongName>
+ <Description>Copy the L4 DSCP to outer pbits</Description>
+ </Label>
+ <Value>2048</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>trap_to_host</ShortName>
+ <LongName>Trap to host</LongName>
+ <Description>Not a valid action for a group object member</Description>
+ </Label>
+ <Value>4096</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>aggregation_port_id</ShortName>
+ <LongName>Aggregation port id</LongName>
+ </Label>
+ <BaseType>
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>classifier</ShortName>
+ <LongName>classifier</LongName>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>o_tpid</ShortName>
+ <LongName>Outer tpid</LongName>
+ <Description>Outer TPID of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>o_vid</ShortName>
+ <LongName>Outer vid</LongName>
+ <Description>Outer VID of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_tpid</ShortName>
+ <LongName>Inner tpid</LongName>
+ <Description>Inner TPID of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_vid</ShortName>
+ <LongName>Inner vid</LongName>
+ <Description>Inner VID of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>o_pbits</ShortName>
+ <LongName>Outer Pbits</LongName>
+ <Description>Outer PBITS of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>i_pbits</ShortName>
+ <LongName>Inner Pbits</LongName>
+ <Description>Inner PBITS of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ether_type</ShortName>
+ <LongName>Ether type</LongName>
+ <Description>Ethertype of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>dst_mac</ShortName>
+ <LongName>Destination mac</LongName>
+ <Description>Destination MAC address of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>MacAddress</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>src_mac</ShortName>
+ <LongName>Source mac</LongName>
+ <Description>Source MAC address of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>MacAddress</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ip_proto</ShortName>
+ <LongName>IP Protocol</LongName>
+ <Description>IP protocol of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>dst_ip</ShortName>
+ <LongName>Destination IP address</LongName>
+ <Description>Destination IP address of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>IPv4Address</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>src_ip</ShortName>
+ <LongName>Source IP address</LongName>
+ <Description>Source IP address of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>IPv4Address</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>src_port</ShortName>
+ <LongName>Source port</LongName>
+ <Description>Source port of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>dst_port</ShortName>
+ <LongName>Destination port</LongName>
+ <Description>Destination port of the packet to be classified</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>pkt_tag_type</ShortName>
+ <LongName>Packet tag type</LongName>
+ <Description>The tag type of the ingress packets</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>pkt_tag_type</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>control</ShortName>
+ <LongName>control</LongName>
+ <Description>Generic enable/disable enumeration</Description>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>disable</ShortName>
+ <LongName>disable</LongName>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>enable</ShortName>
+ <LongName>enable</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>cookie</ShortName>
+ <LongName>cookie</LongName>
+ </Label>
+ <BaseType>
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeClassifiedStructure">
+ <Label>
+ <ShortName>dest</ShortName>
+ <LongName>Packet destination</LongName>
+ </Label>
+ <Options>ValueType</Options>
+ <CommonFields>
+ <Field>
+ <Label>
+ <ShortName>type</ShortName>
+ <LongName>packet destination</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>dest_type</ShortName>
+ </FieldType>
+ </Field>
+ </CommonFields>
+ <ClassifierFieldName>type</ClassifierFieldName>
+ <ClassifiedStructures>
+ <ClassifiedStructure>
+ <ClassifierValue>nni</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Options>ValueType</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>int_id</ShortName>
+ <LongName>Interface ID</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>sub_term</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Options>ValueType</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>Subscriber terminal ID</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_uni</ShortName>
+ <LongName>Subscriber terminal UNI</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>int_id</ShortName>
+ <LongName>Interface ID</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>host</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Options>ValueType</Options>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ </ClassifiedStructures>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>dest_type</ShortName>
+ <LongName>Destination type</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>nni</ShortName>
+ <LongName>nni</LongName>
+ <Description>for packets being sent to the NNI</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>sub_term</ShortName>
+ <LongName>subscriber terminal</LongName>
+ <Description>for packets being sent to a subscriber terminal</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>host</ShortName>
+ <LongName>host</LongName>
+ <Description> for packet indications received from NNI or SUB_TERM and being sent to the host</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>ds_miss_mode</ShortName>
+ <LongName>Downstrean action for unknown packets</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>discard</ShortName>
+ <LongName>Discard</LongName>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>broadcast</ShortName>
+ <LongName>Broadcast</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>vid</ShortName>
+ <LongName>Vid</LongName>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>extra_bw_eligibility_type</ShortName>
+ <LongName>extra_bw_eligibility_type</LongName>
+ <Description>Extra BW Eligibility Type</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>none</ShortName>
+ <LongName>none</LongName>
+ <Description>None</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>not_assured</ShortName>
+ <LongName>not_assured</LongName>
+ <Description>Not assured</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>best_effort</ShortName>
+ <LongName>best_effort</LongName>
+ <Description>Best effort</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>flow_id</ShortName>
+ <LongName>flow id</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>flow_type</ShortName>
+ <LongName>Flow Type</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>upstream</ShortName>
+ <LongName>Upstream flow</LongName>
+ <Description>Upstream flow</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>downstream</ShortName>
+ <LongName>Downstream flow</LongName>
+ <Description>Downstream Flow</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>broadcast</ShortName>
+ <LongName>Broadcast flow</LongName>
+ <Description>Broadcast Flow</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>multicast</ShortName>
+ <LongName>Multicast flow</LongName>
+ <Description>Multicast Flow</Description>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>group_id</ShortName>
+ <LongName>group id</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>group_member_cmd</ShortName>
+ <LongName>Member operation type</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>add_members</ShortName>
+ <LongName>Add new members</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>rem_members</ShortName>
+ <LongName>Remove existing members</LongName>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>set_members</ShortName>
+ <LongName>Replace members with new set</LongName>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>group_member_info</ShortName>
+ <LongName>Group Member Info</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>Access Interface ID</LongName>
+ <Description>Access interface id for this member</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id</ShortName>
+ <LongName>Service Port ID</LongName>
+ <Description>The multicast "GEM" for this member</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>action</ShortName>
+ <LongName>VLAN Actions</LongName>
+ <Description>VLAN actions</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>action</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>queue</ShortName>
+ <LongName>Egress queue</LongName>
+ <Description>Egress queue</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_queue_ref</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>group_owner</ShortName>
+ <LongName>group_owner</LongName>
+ <Description>owner of the group</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>none</ShortName>
+ <LongName>group_owner_none</LongName>
+ <Description>no owner</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>multicast</ShortName>
+ <LongName>group_owner_multicast</LongName>
+ <Description>used as multicast group</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>unicast</ShortName>
+ <LongName>group_owner_unicast</LongName>
+ <Description>used as unicast group</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>Interface ID</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>intf_type</ShortName>
+ <LongName>Interface type</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>nni</ShortName>
+ <LongName>NNI Interface</LongName>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>pon</ShortName>
+ <LongName>POIN Interface</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>iwf_mode</ShortName>
+ <LongName>Interworking Function Mode</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>direct_mapping</ShortName>
+ <LongName>Direct mapping</LongName>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>per_flow</ShortName>
+ <LongName>Per flow </LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>password</ShortName>
+ <LongName>Password</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>arr</ShortName>
+ <LongName>Array</LongName>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <MinimumLength>10</MinimumLength>
+ <MaximumLength>10</MaximumLength>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>percent</ShortName>
+ <LongName>percent</LongName>
+ <Description>Percent</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <MinimumValue>0</MinimumValue>
+ <MaximumValue>100</MaximumValue>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>pkt_tag_type</ShortName>
+ <LongName>Packet tag type</LongName>
+ </Label>
+ <Flags>True</Flags>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>untagged</ShortName>
+ <LongName>Untagged</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>single_tag</ShortName>
+ <LongName>Single tag</LongName>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>double_tag</ShortName>
+ <LongName>Double tag</LongName>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>registration_id</ShortName>
+ <LongName>Registration id</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>arr</ShortName>
+ <LongName>Array</LongName>
+ <Description>ONU registration ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <MinimumLength>36</MinimumLength>
+ <MaximumLength>36</MaximumLength>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>serial_number</ShortName>
+ <LongName>Serial number</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>vendor_id</ShortName>
+ <LongName>vendor id</LongName>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <MinimumLength>4</MinimumLength>
+ <MaximumLength>4</MaximumLength>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>vendor_specific</ShortName>
+ <LongName>vendor specific</LongName>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <MinimumLength>4</MinimumLength>
+ <MaximumLength>4</MaximumLength>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>service_port_id</ShortName>
+ <LongName>Service port id</LongName>
+ </Label>
+ <BaseType>
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>sla</ShortName>
+ <LongName>SLA</LongName>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>min_rate</ShortName>
+ <LongName>Minimum rate</LongName>
+ <Description>The minimal rate for this flow, in kilobits per second (optional)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>max_rate</ShortName>
+ <LongName>Maximum rate</LongName>
+ <Description>The maximum rate for this flow, in kilobits per second (optional)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>state</ShortName>
+ <LongName>state</LongName>
+ <Description>Admin state values for access terminal object</Description>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>up</ShortName>
+ <LongName>Up</LongName>
+ <Description>Admin state up</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>down</ShortName>
+ <LongName>Down</LongName>
+ <Description>Admin state down</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>testing</ShortName>
+ <LongName>Testing</LongName>
+ <Description>Admin state testing</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>status</ShortName>
+ <LongName>status</LongName>
+ <Description>Oper status values</Description>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>up</ShortName>
+ <LongName>Up</LongName>
+ <Description>Oper status up</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>down</ShortName>
+ <LongName>Down</LongName>
+ <Description>Oper status down</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>testing</ShortName>
+ <LongName>Testing</LongName>
+ <Description>Oper status testing</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>not_present</ShortName>
+ <LongName>Not present</LongName>
+ <Description>Oper status not present</Description>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>lower_layer_down</ShortName>
+ <LongName>Lower layer down</LongName>
+ <Description>Oper status lower layer down</Description>
+ </Label>
+ <Value>5</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>unknown</ShortName>
+ <LongName>Unknown</LongName>
+ <Description>Oper status unknown</Description>
+ </Label>
+ <Value>6</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>sub_id</ShortName>
+ <LongName>Subterminal Terminal ID</LongName>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Constants>
+ <AliasConstantEntry>
+ <Label>
+ <ShortName>unknown</ShortName>
+ <LongName>Unknown</LongName>
+ </Label>
+ <Value>0xFFFF</Value>
+ </AliasConstantEntry>
+ </Constants>
+ </CustomType>
+ <CustomType Type="CustomTypeClassifiedStructure">
+ <Label>
+ <ShortName>tm_bac</ShortName>
+ <LongName>tm_bac</LongName>
+ <Description>Queue Buffer Admission Control</Description>
+ </Label>
+ <CommonFields>
+ <Field>
+ <Label>
+ <ShortName>type</ShortName>
+ <LongName>type</LongName>
+ <Description>Buffer Admission Control Type</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_bac_type</ShortName>
+ </FieldType>
+ </Field>
+ </CommonFields>
+ <ClassifierFieldName>type</ClassifierFieldName>
+ <ClassifiedStructures>
+ <ClassifiedStructure>
+ <ClassifierValue>taildrop</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>max_size</ShortName>
+ <LongName>max_size</LongName>
+ <Description>max number of packets in the queue</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>red</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>red</ShortName>
+ <LongName>red</LongName>
+ <Description>Random Early Discard configuration</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_red</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>wred</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>green</ShortName>
+ <LongName>green</LongName>
+ <Description>Green Random Early Discard Configuration</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_red</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>yellow</ShortName>
+ <LongName>yellow</LongName>
+ <Description>Yellow Random Early Discard Configuration</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_red</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>red</ShortName>
+ <LongName>red</LongName>
+ <Description>Red Random Early Discard Configuration</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_red</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ </ClassifiedStructures>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_bac_type</ShortName>
+ <LongName>tm_bac_type</LongName>
+ <Description>Buffer Admission Control Type</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>taildrop</ShortName>
+ <LongName>taildrop</LongName>
+ <Description>Taildrop </Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>wtaildrop</ShortName>
+ <LongName>wtaildrop</LongName>
+ <Description>Weighted taildrop</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>red</ShortName>
+ <LongName>red</LongName>
+ <Description>Random Early Discard</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>wred</ShortName>
+ <LongName>wred</LongName>
+ <Description>Weighted Random Early Discard</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_creation_mode</ShortName>
+ <LongName>tm_creation_mode</LongName>
+ <Description>TM Creation Mode</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>manual</ShortName>
+ <LongName>manual</LongName>
+ <Description>tm object created manually</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>auto</ShortName>
+ <LongName>auto</LongName>
+ <Description>tm object created automatically</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>tm_priority</ShortName>
+ <LongName>tm_priority</LongName>
+ <Description>Scheduling Priority</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>tm_queue_id</ShortName>
+ <LongName>tm_queue_id</LongName>
+ <Description>Queue ID</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>tm_queue_ref</ShortName>
+ <LongName>tm_queue_ref</LongName>
+ <Description>Queue Reference</Description>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sched_id</ShortName>
+ <LongName>Scheduler ID</LongName>
+ <Description>Scheduler (tm_sched) ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>queue_id</ShortName>
+ <LongName>Queue ID</LongName>
+ <Description>Queue ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_queue_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>tm_red</ShortName>
+ <LongName>tm_red</LongName>
+ <Description>Random Early Discard Configuration</Description>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>min_threshold</ShortName>
+ <LongName>min_threshold</LongName>
+ <Description>Min threshold in percent of max queue size</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>percent</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>max_threshold</ShortName>
+ <LongName>max_threshold</LongName>
+ <Description>Max threshold in percent of max queue size</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>percent</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>max_probability</ShortName>
+ <LongName>max_probability</LongName>
+ <Description>Discard probability for occupancy between min_threshold and max_threshold</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>percent</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_sched_child_type</ShortName>
+ <LongName>tm_sched_child_type</LongName>
+ <Description>Scheduling Level for the Children TM </Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>queue</ShortName>
+ <LongName>queue</LongName>
+ <Description>Queue-level scheduler</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>sched</ShortName>
+ <LongName>sched</LongName>
+ <Description>Scheduler-level scheduler</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_sched_dir</ShortName>
+ <LongName>tm_sched_dir</LongName>
+ <Description>Traffic Direction</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>us</ShortName>
+ <LongName>upstream</LongName>
+ <Description>Upstream</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>ds</ShortName>
+ <LongName>downstream</LongName>
+ <Description>Downstream</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>tm_sched_id</ShortName>
+ <LongName>tm_sched_id</LongName>
+ <Description>TM Scheduler ID</Description>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Constants>
+ <AliasConstantEntry>
+ <Label>
+ <ShortName>unknown</ShortName>
+ <LongName>Unknown</LongName>
+ </Label>
+ <Value>65535</Value>
+ </AliasConstantEntry>
+ </Constants>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>tm_sched_id_index</ShortName>
+ <LongName>tm node id index</LongName>
+ </Label>
+ <BaseType>
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <MinimumValue>0</MinimumValue>
+ <MaximumValue>2048</MaximumValue>
+ </CustomType>
+ <CustomType Type="CustomTypeClassifiedStructure">
+ <Label>
+ <ShortName>tm_sched_owner</ShortName>
+ <LongName>tm_sched_owner</LongName>
+ <Description>TM Scheduler Owner</Description>
+ </Label>
+ <CommonFields>
+ <Field>
+ <Label>
+ <ShortName>type</ShortName>
+ <LongName>type</LongName>
+ <Description>Owner type</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_owner_type</ShortName>
+ </FieldType>
+ </Field>
+ </CommonFields>
+ <ClassifierFieldName>type</ClassifierFieldName>
+ <ClassifiedStructures>
+ <ClassifiedStructure>
+ <ClassifierValue>interface</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_type</ShortName>
+ <LongName>intf_type</LongName>
+ <Description>Interface Type</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ <Description>Interface ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>sub_term</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ <Description>PON interface id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>sub_term_id</LongName>
+ <Description>Subscriber terminal ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>agg_port</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ <Description>PON interface id</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>sub_term_id</LongName>
+ <Description>Subscriber terminal id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>agg_port_id</ShortName>
+ <LongName>agg_port_id</LongName>
+ <Description>Aggregation port id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>aggregation_port_id</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>uni</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ <Description>PON interface id</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>sub_term_id</LongName>
+ <Description>Subscriber terminal id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>index</ShortName>
+ <LongName>index</LongName>
+ <Description>Index at subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ <ClassifiedStructure>
+ <ClassifierValue>virtual</ClassifierValue>
+ <EmbeddedStructure>
+ <Label>
+ <ShortName></ShortName>
+ <LongName></LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>index</ShortName>
+ <LongName>index</LongName>
+ <Description>Owner index</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </EmbeddedStructure>
+ </ClassifiedStructure>
+ </ClassifiedStructures>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_sched_owner_type</ShortName>
+ <LongName>tm_scheduler_owner_type</LongName>
+ <Description>TM Scheduler Owner Type</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>undefined</ShortName>
+ <LongName>undefined</LongName>
+ <Description>Undefined</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>interface</ShortName>
+ <LongName>interface</LongName>
+ <Description>Interface</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>sub_term</ShortName>
+ <LongName>subs_term</LongName>
+ <Description>Subscriber terminal</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>agg_port</ShortName>
+ <LongName>agg_port</LongName>
+ <Description>TM scheduler is owned by aggregation port</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>uni</ShortName>
+ <LongName>uni</LongName>
+ <Description>TM scheduler is owned by UNI port</Description>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>virtual</ShortName>
+ <LongName>virtual</LongName>
+ <Description>Other unspecified owner</Description>
+ </Label>
+ <Value>5</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>tm_sched_parent</ShortName>
+ <LongName>tm_sched_parent</LongName>
+ <Description>Scheduling Parent Connect Point</Description>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sched_id</ShortName>
+ <LongName>sched_id</LongName>
+ <Description>Parent scheduler id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>priority</ShortName>
+ <LongName>priority</LongName>
+ <Description>Priority</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_priority</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>weight</ShortName>
+ <LongName>weight</LongName>
+ <Description>Weight</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_weight</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>tm_sched_type</ShortName>
+ <LongName>tm_sched_type</LongName>
+ <Description>Scheduler Type</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>none</ShortName>
+ <LongName>none</LongName>
+ <Description>NO scheduling</Description>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>wfq</ShortName>
+ <LongName>wfq</LongName>
+ <Description>Weighted Fair Queue</Description>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>sp</ShortName>
+ <LongName>sp</LongName>
+ <Description>Strict Priority</Description>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>sp_wfq</ShortName>
+ <LongName>sp_wfq</LongName>
+ <Description>Hybrid SP + WFQ</Description>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>tm_shaping</ShortName>
+ <LongName>tm_shaping</LongName>
+ <Description>Shaping Parameters</Description>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sbr</ShortName>
+ <LongName>sbr</LongName>
+ <Description>Sustained Bit Rate (kbps)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>pbr</ShortName>
+ <LongName>pbr</LongName>
+ <Description>Peak Bit Rate (kbps)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>burst</ShortName>
+ <LongName>burst</LongName>
+ <Description>Max Burst Bytes at Peak Bit Rate</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeStructure">
+ <Label>
+ <ShortName>tm_tcont_sla</ShortName>
+ <LongName>tm_tcont_sla</LongName>
+ <Description>ITU-PON Extended SLA Parameters</Description>
+ </Label>
+ <Options>PresenceMask</Options>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>extra_bw_elig</ShortName>
+ <LongName>extra_bw_elig</LongName>
+ <Description>Extra BW eligibility type</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>extra_bw_eligibility_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>nrt_cbr</ShortName>
+ <LongName>nrt_cbr</LongName>
+ <Description>NRT CBR</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rt_cbr</ShortName>
+ <LongName>rt_cbr</LongName>
+ <Description>RT_CBR</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rt_profile</ShortName>
+ <LongName>rt_profile</LongName>
+ <Description>RT Profile</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>nrt_profile</ShortName>
+ <LongName>key:</LongName>
+ <Description>NRT Profile</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </CustomType>
+ <CustomType Type="CustomTypeAlias">
+ <Label>
+ <ShortName>tm_weight</ShortName>
+ <LongName>tm_weight</LongName>
+ <Description>Scheduling Weight</Description>
+ </Label>
+ <BaseType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ </CustomType>
+ <CustomType Type="CustomTypeEnum">
+ <Label>
+ <ShortName>trx_type</ShortName>
+ <LongName>Transceiver types</LongName>
+ <Description>Transceiver types</Description>
+ </Label>
+ <BaseType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </BaseType>
+ <Entries>
+ <EnumEntry>
+ <Label>
+ <ShortName>gpon_sps_43_48</ShortName>
+ <LongName>gpon_sps_43_48</LongName>
+ </Label>
+ <Value>0</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>gpon_sps_sog_4321</ShortName>
+ <LongName>gpon_sps_sog_4321</LongName>
+ </Label>
+ <Value>1</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>gpon_lte_3680_m</ShortName>
+ <LongName>gpon_lte_3680_m</LongName>
+ </Label>
+ <Value>2</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>gpon_source_photonics</ShortName>
+ <LongName>gpon_source_photonics</LongName>
+ </Label>
+ <Value>3</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>gpon_lte_3680_p</ShortName>
+ <LongName>gpon_lte_3680_p</LongName>
+ </Label>
+ <Value>4</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>xgpon_lth_7222_pc</ShortName>
+ <LongName>xgpon_lth_7222_pc</LongName>
+ </Label>
+ <Value>5</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>xgpon_lth_7226_pc</ShortName>
+ <LongName>xgpon_lth_7226_pc</LongName>
+ </Label>
+ <Value>6</Value>
+ </EnumEntry>
+ <EnumEntry>
+ <Label>
+ <ShortName>xgpon_lth_5302_pc</ShortName>
+ <LongName>xgpon_lth_5302_pc</LongName>
+ </Label>
+ <Value>7</Value>
+ </EnumEntry>
+ </Entries>
+ </CustomType>
+ </CustomTypes>
+ <OmObjects>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>access_terminal</ShortName>
+ <LongName>BAL Access Terminal</LongName>
+ <Description>BAL Access Terminal Object</Description>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>access_term_id</ShortName>
+ <LongName>access_term_id</LongName>
+ <Description>Reserved (set to 0)</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>access_id</ShortName>
+ </FieldType>
+ <DefaultValue>1</DefaultValue>
+ <MinimumValue>1</MinimumValue>
+ <MaximumValue>1</MaximumValue>
+ <Options>Reserved, IsInstanceNumber</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>iwf_mode</ShortName>
+ <LongName>Interworking function mode</LongName>
+ <Description>The interworking mode</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>iwf_mode</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Access Terminal Indication</LongName>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Current administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Current operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>iwf_mode</ShortName>
+ <LongName>Interworking function mode</LongName>
+ <Description>The interworking mode</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>iwf_mode</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>flow</ShortName>
+ <LongName>BAL Flow</LongName>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>access_int_id</ShortName>
+ <LongName>Access Interface ID</LongName>
+ <Description>The ID of the subscriber side interface; i.e. PON</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>network_int_id</ShortName>
+ <LongName>Network Interface ID</LongName>
+ <Description>The ID of the network side interface; i.e. NNI</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>Subscriber Terminal ID</LongName>
+ <Description>The ID of the subsccriber terminal device</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_uni_idx</ShortName>
+ <LongName>Subscriber Terminal uni port index</LongName>
+ <Description>The index of the subsccriber terminal uni port the flow is related to</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id</ShortName>
+ <LongName>Service Port ID</LongName>
+ <Description>The ID of the service port (for GPON/XGPON - GEM ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>agg_port_id</ShortName>
+ <LongName>Aggregate port ID</LongName>
+ <Description>The ID of the aggregate port (for GPON/XGPON - ALLOC ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>aggregation_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>resolve_mac</ShortName>
+ <LongName>Resolve mac</LongName>
+ <Description>A flag indicating if the MAC address table should be used in DS GEM resolution</Description>
+ </Label>
+ <FieldType Type="FieldTypeBoolean" />
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>classifier</ShortName>
+ <LongName>Classifier</LongName>
+ <Description>The classifier for this flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>classifier</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>action</ShortName>
+ <LongName>Action</LongName>
+ <Description>The action associated with the flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>action</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sla</ShortName>
+ <LongName>SLA</LongName>
+ <Description>SLA parameters for this flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sla</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>cookie</ShortName>
+ <LongName>Cookie</LongName>
+ <Description>Application cookie</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>cookie</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>priority</ShortName>
+ <LongName>Priority</LongName>
+ <Description>Priority for this flow in case of multiple match.
+Higher value precednece over lower value.</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ <MinimumValue>1</MinimumValue>
+ <MaximumValue>255</MaximumValue>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>group_id</ShortName>
+ <LongName>Group ID</LongName>
+ <Description>RW - The multicast group associated with this flow, valid for type MULTICAST only</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>group_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>queue</ShortName>
+ <LongName>Egress queue</LongName>
+ <Description>Egress queue</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_queue_ref</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>flow_id</ShortName>
+ <LongName>Flow ID</LongName>
+ <Description>The ID of the flow object instance being referenced</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_id</ShortName>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_type</ShortName>
+ <LongName>Flow type</LongName>
+ <Description>The type of the flow, Upstream, Downstream, Broadcast or Multicast</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_type</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>stat</ShortName>
+ <LongName>stat</LongName>
+ </Label>
+ <Type>Statistics</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>rx_packets</ShortName>
+ <LongName>Received packets</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rx_bytes</ShortName>
+ <LongName>Received bytes</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_packets</ShortName>
+ <LongName>Transmitted packets</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_bytes</ShortName>
+ <LongName>Transmitted bytes</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Flow Indication</LongName>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Operational Status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>access_int_id</ShortName>
+ <LongName>Access interface ID</LongName>
+ <Description>The ID of the subscriber side interface; i.e. PON</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>network_int_id</ShortName>
+ <LongName>Network Interface ID</LongName>
+ <Description>The ID of the network side interface; i.e. NNI</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>Subscriber terminal ID</LongName>
+ <Description>The ID of the subsccriber terminal device</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id</ShortName>
+ <LongName>Service port ID</LongName>
+ <Description>The ID of the service port (for GPON/XGPON - GEM ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>agg_port_id</ShortName>
+ <LongName>Aggregate port ID</LongName>
+ <Description>The ID of the aggregate port (for GPON/XGPON - ALLOC ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>resolve_mac</ShortName>
+ <LongName>Resolve mac</LongName>
+ <Description>A flag indicating if the MAC address table should be used in DS GEM resolution</Description>
+ </Label>
+ <FieldType Type="FieldTypeBoolean" />
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>base_tc_id</ShortName>
+ <LongName>Base TCONT ID</LongName>
+ <Description>The base index of the TC object(s) to be used for this flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>classifier</ShortName>
+ <LongName>Classifier</LongName>
+ <Description>The classifier for this flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>classifier</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>action</ShortName>
+ <LongName>Action</LongName>
+ <Description>The action associated with the flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>action</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sla</ShortName>
+ <LongName>SLA</LongName>
+ <Description>SLA parameters for this flow</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sla</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>cookie</ShortName>
+ <LongName>Cookie</LongName>
+ <Description>Application cookie</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>priority</ShortName>
+ <LongName>Priority</LongName>
+ <Description>Priority for this flow in case of multiple match.
+Higher value precednece over lower value.</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ <MinimumValue>1</MinimumValue>
+ <MaximumValue>255</MaximumValue>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>group</ShortName>
+ <LongName>BAL Group</LongName>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>members_cmd</ShortName>
+ <LongName>Membership operation commands</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>group_member_cmd</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>members</ShortName>
+ <LongName>Member</LongName>
+ <Description>The list of members associated with this group</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>group_member_info</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>cookie</ShortName>
+ <LongName>Application cookie</LongName>
+ <Description>Application cookie</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>cookie</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flows</ShortName>
+ <LongName>List of flows associated with the group </LongName>
+ <Description>List of flows associated with this group</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>flow_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ <MinimumLength>0</MinimumLength>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>owner</ShortName>
+ <LongName>Owner of the group</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>group_owner</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>group_id</ShortName>
+ <LongName>Group ID</LongName>
+ <Description>The ID of the group object instance being referenced</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>group_id</ShortName>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>interface</ShortName>
+ <LongName>BAL Interface</LongName>
+ <Description>BAL interface object</Description>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_type</ShortName>
+ <LongName>intf_type</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_type</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>min_data_agg_port_id</ShortName>
+ <LongName>Minimum aggregate port ID</LongName>
+ <Description>The minimum agg_port_id that is allowed in the system</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>aggregation_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>min_data_svc_port_id</ShortName>
+ <LongName>Minimum service port ID</LongName>
+ <Description>The minimum svc_port_id that is allowed in the system</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>transceiver_type</ShortName>
+ <LongName>Transceiver type</LongName>
+ <Description>The transceiver type used on an interface</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>trx_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_miss_mode</ShortName>
+ <LongName>Downstream unknown packet action</LongName>
+ <Description>Defines the action to take for unknown downstream packets</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>ds_miss_mode</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>mtu</ShortName>
+ <LongName>MTU</LongName>
+ <Description>The MTU for an interface</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_control</ShortName>
+ <LongName>Flow control</LongName>
+ <Description>Flow control enable or disable</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>control</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_tm</ShortName>
+ <LongName>Downstream scheduler and shaper</LongName>
+ <Description>Downstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>us_tm</ShortName>
+ <LongName>Upstream scheduler and shaper</LongName>
+ <Description>Upstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id_list</ShortName>
+ <LongName>Sub-term id list</LongName>
+ <Description>A list of subscriber terminal ids configured on this interface</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>stat</ShortName>
+ <LongName>stat</LongName>
+ </Label>
+ <Type>Statistics</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>rx_packets</ShortName>
+ <LongName>Recieved packets</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rx_bytes</ShortName>
+ <LongName>Received bytes</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_packets</ShortName>
+ <LongName>Transmitted packets</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_bytes</ShortName>
+ <LongName>Transmitted bytes</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Interface Indication</LongName>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Current administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Current operational state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>min_data_agg_port_id</ShortName>
+ <LongName>Minimum aggregate port ID</LongName>
+ <Description>The minimum agg_port_id that is allowed in the system</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>min_data_svc_port_id</ShortName>
+ <LongName>Minimum service port ID</LongName>
+ <Description>The minimum svc_port_id that is allowed in the system</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>transceiver_type</ShortName>
+ <LongName>Transceiver type</LongName>
+ <Description>The transceiver type used on an interface</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>trx_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_miss_mode</ShortName>
+ <LongName>Downstream unknown packet action</LongName>
+ <Description>Defines the action to take for DS unknown packets</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>ds_miss_mode</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>mtu</ShortName>
+ <LongName>MTU</LongName>
+ <Description>The MTU for an interface</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_control</ShortName>
+ <LongName>Flow control</LongName>
+ <Description>Flow control enable or disable</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>control</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_tm</ShortName>
+ <LongName>Downstream scheduler and shaper</LongName>
+ <Description>Downstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>us_tm</ShortName>
+ <LongName>Upstream scheduler and shaper</LongName>
+ <Description>Upstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>packet</ShortName>
+ <LongName>packet</LongName>
+ <Description>Packet that can be transmitted or received</Description>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>flow_id</ShortName>
+ <LongName>Flow Id</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_type</ShortName>
+ <LongName>Flow Type</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>Interface ID</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_type</ShortName>
+ <LongName>Interface Type</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port</ShortName>
+ <LongName>Service Port</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_cookie</ShortName>
+ <LongName>Flow Cookie</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>cookie</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>pkt</ShortName>
+ <LongName>Packet Data</LongName>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>reserved</ShortName>
+ <LongName>Reserved key field</LongName>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>packet_send_dest</ShortName>
+ <LongName>Packet destination</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>dest</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Packet indication</LongName>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>flow_id</ShortName>
+ <LongName>Flow Id</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_type</ShortName>
+ <LongName>Flow Type</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>flow_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>Interface ID</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_type</ShortName>
+ <LongName>Interface Type</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port</ShortName>
+ <LongName>Service Port</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>flow_cookie</ShortName>
+ <LongName>Flow Cookie</LongName>
+ <Description>N/A for sending a packet</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>cookie</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>pkt</ShortName>
+ <LongName>Packet Data</LongName>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>subscriber_terminal</ShortName>
+ <LongName>BAL Subscriber Terminal</LongName>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sub_term_id</ShortName>
+ <LongName>sub_term_id</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>sub_id</ShortName>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>intf_id</ShortName>
+ <LongName>intf_id</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>intf_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>serial_number</ShortName>
+ <LongName>Serial number</LongName>
+ <Description>The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>serial_number</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>password</ShortName>
+ <LongName>Password</LongName>
+ <Description>The password of a GPON subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>password</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>registration_id</ShortName>
+ <LongName>Registration id</LongName>
+ <Description>ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>registration_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id</ShortName>
+ <LongName>Service port ID</LongName>
+ <Description>The management service port ID (for PON, the ONU ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>mac_address</ShortName>
+ <LongName>MAC address</LongName>
+ <Description>The Ethernet MAC address of an EPON subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>MacAddress</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_tm</ShortName>
+ <LongName>Downstream scheduler and shaper</LongName>
+ <Description>Downstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>us_tm</ShortName>
+ <LongName>Upstream scheduler and shaper</LongName>
+ <Description>Upstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id_list</ShortName>
+ <LongName>svc_port_id list</LongName>
+ <Description>A list of bearer traffic svc_port_ids associated with this subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>service_port_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>agg_port_id_list</ShortName>
+ <LongName>agg_port_id list</LongName>
+ <Description>A list of aggr_port_ids associated with this subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>aggregation_port_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>stat</ShortName>
+ <LongName>stat</LongName>
+ </Label>
+ <Type>Statistics</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>rx_packets</ShortName>
+ <LongName>Received packets</LongName>
+ <Description>Received packets on specified object</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rx_bytes</ShortName>
+ <LongName>Received bytes</LongName>
+ <Description>Received bytes on specified object</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_packets</ShortName>
+ <LongName>Transmitted packets</LongName>
+ <Description>Transmitted packets on specified object</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tx_bytes</ShortName>
+ <LongName>Transmitted bytes</LongName>
+ <Description>Transmittted bytes on specified object</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Subscriber Terminal Indication</LongName>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>admin_state</ShortName>
+ <LongName>Administrative state</LongName>
+ <Description>Current administrative state</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>state</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>oper_status</ShortName>
+ <LongName>Operational status</LongName>
+ <Description>Current operational status</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>status</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>serial_number</ShortName>
+ <LongName>Serial number</LongName>
+ <Description>The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>serial_number</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>password</ShortName>
+ <LongName>Password</LongName>
+ <Description>The password of a GPON subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>password</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>registration_id</ShortName>
+ <LongName>Registration id</LongName>
+ <Description>ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>registration_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>svc_port_id</ShortName>
+ <LongName>Service port ID</LongName>
+ <Description>The service port ID (for PON, the ONU ID)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>2</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>mac_address</ShortName>
+ <LongName>MAC address</LongName>
+ <Description>The Ethernet MAC address of an epon subscriber terminal</Description>
+ </Label>
+ <FieldType Type="FieldTypeWellKnown">
+ <WellKnownType>MacAddress</WellKnownType>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ds_tm</ShortName>
+ <LongName>Downstream scheduler and shaper</LongName>
+ <Description>Downstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>us_tm</ShortName>
+ <LongName>Upstream scheduler and shaper</LongName>
+ <Description>Upstream scheduler and shaper</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>tm_queue</ShortName>
+ <LongName>tm_queue</LongName>
+ <Description>Transmit queue</Description>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>sched_id</ShortName>
+ <LongName>sched_id</LongName>
+ <Description>Scheduler that owns the queue</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sched_dir</ShortName>
+ <LongName>sched dir</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_dir</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>id</ShortName>
+ <LongName>id</LongName>
+ <Description>Queue id</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_queue_id</ShortName>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>priority</ShortName>
+ <LongName>priority</LongName>
+ <Description>Scheduling priority</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_priority</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>weight</ShortName>
+ <LongName>weight</LongName>
+ <Description>Scheduling weight</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_weight</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rate</ShortName>
+ <LongName>rate</LongName>
+ <Description>Rate shaping parameters</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_shaping</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>bac</ShortName>
+ <LongName>bac</LongName>
+ <Description>Buffer admission control</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_bac</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>creation_mode</ShortName>
+ <LongName>creation_mode</LongName>
+ <Description>Creation mode</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_creation_mode</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>ref_count</ShortName>
+ <LongName>ref_count</LongName>
+ <Description>reference count (flows)</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>stat</ShortName>
+ <LongName>stat</LongName>
+ </Label>
+ <Type>Statistics</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>packets_ok</ShortName>
+ <LongName>packets_ok</LongName>
+ <Description>Packets transmitted succewssfully</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>bytes_ok</ShortName>
+ <LongName>bytes_ok</LongName>
+ <Description>Bytes transmitted successfully</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>packets_discarded</ShortName>
+ <LongName>packets_discarded</LongName>
+ <Description>Packets discarded</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>bytes_discarded</ShortName>
+ <LongName>bytes_discarded</LongName>
+ <Description>Bytes discarded</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>8</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Tm Queue Indication</LongName>
+ <Description>Tm Queue Indication</Description>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>ret</ShortName>
+ <LongName>ret</LongName>
+ <Description>ret</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ <ObjectModel.OmObject>
+ <Label>
+ <ShortName>tm_sched</ShortName>
+ <LongName>tm_sched</LongName>
+ <Description>Scheduling node</Description>
+ </Label>
+ <Groups>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>key</ShortName>
+ <LongName>key</LongName>
+ </Label>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>dir</ShortName>
+ <LongName>dir</LongName>
+ <Description>Traffic direction</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_dir</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>id</ShortName>
+ <LongName>id</LongName>
+ <Description>ID</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </FieldType>
+ <Options>IsInstanceNumber</Options>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>cfg</ShortName>
+ <LongName>cfg</LongName>
+ </Label>
+ <Type>Configuration</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>owner</ShortName>
+ <LongName>owner</LongName>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_owner</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sched_type</ShortName>
+ <LongName>type</LongName>
+ <Description>Scheduler type</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sched_parent</ShortName>
+ <LongName>parent</LongName>
+ <Description>Scheduling parameters for parent scheduler</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_parent</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sched_child_type</ShortName>
+ <LongName>child_type</LongName>
+ <Description>Scheduling level for children tm </Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_sched_child_type</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>rate</ShortName>
+ <LongName>rate</LongName>
+ <Description>Rate shaping parameters</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_shaping</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>tcont_sla</ShortName>
+ <LongName>tcont_sla</LongName>
+ <Description>Additional SLA parameters for agg_port owner</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_tcont_sla</ShortName>
+ </FieldType>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>creation_mode</ShortName>
+ <LongName>creation_mode</LongName>
+ <Description>Creation mode</Description>
+ </Label>
+ <FieldType Type="FieldTypeReference">
+ <ShortName>tm_creation_mode</ShortName>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>queues</ShortName>
+ <LongName>queues</LongName>
+ <Description>Subsidiary queues</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>tm_queue_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>sub_scheds</ShortName>
+ <LongName>sub_scheds</LongName>
+ <Description>Subsidiary schedulers</Description>
+ </Label>
+ <FieldType Type="FieldTypeList">
+ <ElementType Type="FieldTypeReference">
+ <ShortName>tm_sched_id</ShortName>
+ </ElementType>
+ <AutoCountFieldType>
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </AutoCountFieldType>
+ </FieldType>
+ <Options>ReadOnly</Options>
+ </Field>
+ <Field>
+ <Label>
+ <ShortName>num_priorities</ShortName>
+ <LongName>num_priorities</LongName>
+ <Description>Max number of strict priority scheduling elements</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>1</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ <ObjectModel.OmGroup>
+ <Label>
+ <ShortName>ind</ShortName>
+ <LongName>Tm Sched Indication</LongName>
+ <Description>Tm Sched Indication</Description>
+ </Label>
+ <Type>Indication</Type>
+ <Fields>
+ <Field>
+ <Label>
+ <ShortName>ret</ShortName>
+ <LongName>ret</LongName>
+ <Description>ret</Description>
+ </Label>
+ <FieldType Type="FieldTypeNumber">
+ <Width>4</Width>
+ <Signed>False</Signed>
+ </FieldType>
+ </Field>
+ </Fields>
+ </ObjectModel.OmGroup>
+ </Groups>
+ </ObjectModel.OmObject>
+ </OmObjects>
+</ElementSet>
\ No newline at end of file
diff --git a/bal_release/src/lib/common/placeholder b/bal_release/src/lib/common/placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bal_release/src/lib/common/placeholder
diff --git a/bal_release/src/lib/libbalapi/Makefile b/bal_release/src/lib/libbalapi/Makefile
new file mode 100644
index 0000000..79fea84
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/Makefile
@@ -0,0 +1,38 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = bal_api
+MOD_TYPE = lib
+MOD_DEPS = common_include dev_log maple_sdk balobjmsg
+ifeq ("$(BAL_MONOLITHIC)", "y")
+MOD_DEPS += bal_core
+endif
+
+srcs = bal_api.c bal_api_worker.c
diff --git a/bal_release/src/lib/libbalapi/bal_api.c b/bal_release/src/lib/libbalapi/bal_api.c
new file mode 100644
index 0000000..4374fd2
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api.c
@@ -0,0 +1,658 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_api.c
+ * @brief The BAL Public API
+ *
+ * @addtogroup api
+ */
+
+/*@{*/
+
+/* Project includes */
+#include "bal_api.h"
+#include "bal_msg.h"
+#include "bal_api_worker.h"
+#include "bal_obj_msg_pack_unpack.h"
+#ifdef BAL_MONOLITHIC
+#include <bal_worker.h>
+#endif
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+/*
+ * @brief The logging device id for the BAL public API
+ */
+dev_log_id log_id_public_api;
+#endif
+
+/*
+ * @brief The global mgmt queues
+ *
+ * These are the queues through which the BAL API communicates with
+ * the core, and vice versa.
+ */
+static bcmos_msg_queue balapi_rsp_queue;
+static bcmos_msg_queue balapi_to_core_queue;
+
+bcmos_msg_queue *p_balapi_rsp_queue;
+bcmos_msg_queue *p_balapi_to_core_queue;
+
+static bcmos_mutex balapi_lock;
+static uint32_t balapi_exchange_id;
+static STAILQ_HEAD(pending_req_list, bcmos_msg) pending_req_list;
+
+static bcmos_task api_rsp_rx_thread;
+static int _bal_ipc_api_rx_handler(long data);
+
+/* Rx polling timeout (us) */
+#define BAL_API_RX_POLL_TIMEOUT 100000
+
+/*****************************************************************************
+ * Initialize the BAL Public API internal data structures
+ *****************************************************************************/
+bcmos_errno bcmbal_api_init(const char *balapi_mgmt_ip_port,
+ const char *core_mgmt_ip_port)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+ bcmos_msg_queue_parm msg_q_p = {};
+ bcmos_task_parm task_p = {};
+
+#ifdef ENABLE_LOG
+ log_id_public_api = bcm_dev_log_id_register("BAL_API", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(log_id_public_api == DEV_LOG_INVALID_ID);
+#endif
+
+ do
+ {
+ STAILQ_INIT(&pending_req_list);
+
+ ret = bcmos_mutex_create(&balapi_lock, 0, "bal_api");
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API protection mutex\n");
+ break;
+ }
+
+ /* Create BAL API RX management queue - the BAL Public API
+ * exchanges management messages with the BAL core using this queue.
+ */
+ msg_q_p.name = "balapi_mgmt_q";
+ if (NULL != balapi_mgmt_ip_port)
+ {
+ msg_q_p.local_ep_address = balapi_mgmt_ip_port;
+ msg_q_p.remote_ep_address = NULL;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+ }
+ else
+ {
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_LOCAL;
+ }
+ ret = bcmos_msg_queue_create(&balapi_rsp_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ p_balapi_rsp_queue = &balapi_rsp_queue;
+#ifdef BAL_MONOLITHIC
+ if (NULL == balapi_mgmt_ip_port)
+ p_bal_core_to_api_queue = p_balapi_rsp_queue;
+#endif
+
+ /* Create queue for sending API requests to the core. Only do it if API and core interact via UDP
+ */
+ if (NULL != core_mgmt_ip_port)
+ {
+ msg_q_p.name = "balapi_to_core_q";
+ msg_q_p.local_ep_address = NULL;
+ msg_q_p.remote_ep_address = core_mgmt_ip_port;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+
+ ret = bcmos_msg_queue_create(&balapi_to_core_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
+ ret = BCM_ERR_INTERNAL;
+ break;
+ }
+ p_balapi_to_core_queue = &balapi_to_core_queue;
+ }
+
+ /* Create BAL API RX thread */
+ task_p.name = "ipc_api_rsp_rx_thread";
+ task_p.priority = TASK_PRIORITY_IPC_RX;
+ task_p.handler = _bal_ipc_api_rx_handler;
+ task_p.data = (long)p_balapi_rsp_queue;
+
+ ret = bcmos_task_create(&api_rsp_rx_thread, &task_p);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API response RX thread\n");
+ break;
+ }
+
+ /*
+ * Initialize the BAL Public API backend worker and rx threads. These
+ * threads are used to receive asynchronous indications from the core.
+ */
+ enable_bal_api_indications(balapi_mgmt_ip_port);
+
+ }
+ while(0);
+
+ return ret;
+}
+
+/*****************************************************************************
+ * Un-initialize the BAL Public API internal data structures
+ *****************************************************************************/
+bcmos_errno bcmbal_api_finish(void)
+{
+ bcmos_task_destroy(&api_rsp_rx_thread);
+ bcmos_msg_queue_destroy(&balapi_rsp_queue);
+ if (p_balapi_to_core_queue == &balapi_to_core_queue)
+ bcmos_msg_queue_destroy(&balapi_to_core_queue);
+
+ bal_api_indications_finish();
+
+ return BCM_ERR_OK;
+}
+
+/* Find pending request matching response */
+static bal_comm_msg_hdr *_bal_api_get_request_by_ex_id(uint32_t ex_id)
+{
+ bcmos_msg *req_msg, *tmp_msg;
+ bal_comm_msg_hdr *comm_hdr = NULL;
+
+ STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
+ {
+ comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
+ if (comm_hdr->ex_id == ex_id)
+ {
+ STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
+ break;
+ }
+ }
+ return req_msg ? comm_hdr : NULL;
+}
+
+/* Check if any pending request timed out */
+static void _bal_api_check_req_timeout(void)
+{
+ bcmos_msg *req_msg, *tmp_msg;
+ bal_comm_msg_hdr *comm_hdr;
+ bcmbal_obj *req_obj;
+ uint32_t ts = bcmos_timestamp();
+
+ STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
+ {
+ comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
+ if (ts - comm_hdr->timestamp >= BCMBAL_MSG_TIMEOUT_1_SEC)
+ {
+ STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
+ req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(comm_hdr);
+ /* Release pending API call */
+ req_obj->status = BCM_ERR_TIMEOUT;
+ BCM_LOG(DEBUG, log_id_public_api, "Timing out request %p\n", comm_hdr);
+ bcmos_sem_post(&comm_hdr->sem);
+ }
+ }
+}
+
+/* API response handler */
+static int _bal_ipc_api_rx_handler(long data)
+{
+ static uint32_t last_timeout_check_ts;
+ bcmos_msg_queue *rxq = (bcmos_msg_queue *)data;
+ bcmos_task *my_task = bcmos_task_current();
+ bcmos_msg *msg;
+ bcmos_errno ret = BCM_ERR_OK;
+ uint32_t ex_id;
+ bal_comm_msg_hdr *req;
+ bcmbal_obj *req_obj;
+
+ last_timeout_check_ts = bcmos_timestamp();
+ while (!my_task->destroy_request)
+ {
+ /* Wait for response */
+ msg = NULL;
+ req = NULL;
+
+ ret = bcmos_msg_recv(rxq, BAL_API_RX_POLL_TIMEOUT, &msg);
+ if(BCM_ERR_OK != ret && BCM_ERR_TIMEOUT != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "error during bcmos_msg_recv (error:%s)\n", bcmos_strerror(ret));
+ }
+
+ /* Peek exchange id */
+ if (msg)
+ {
+ ret = bcmbal_bal_msg_peek_ex_id(msg, &ex_id);
+ if(BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "bad message. Can't find exchange id (error:%s)\n", bcmos_strerror(ret));
+ bcmos_msg_free(msg);
+ msg = NULL;
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_public_api, "Received message with ex_id=%u\n", ex_id);
+ }
+ }
+
+ /* Now find pending request and also check if any pending request(s) timed out */
+ bcmos_mutex_lock(&balapi_lock);
+ if (msg)
+ {
+ req = _bal_api_get_request_by_ex_id(ex_id);
+ if (NULL == req)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "Request with ex_id=%u is not found. Probably expired. Response discarded\n", ex_id);
+ }
+ else
+ {
+ BCM_LOG(DEBUG, log_id_public_api, "Found request %p\n", req);
+ }
+ }
+ if (bcmos_timestamp() - last_timeout_check_ts >= BCMBAL_MSG_TIMEOUT_1_SEC)
+ {
+ _bal_api_check_req_timeout();
+ last_timeout_check_ts = bcmos_timestamp();
+ }
+ bcmos_mutex_unlock(&balapi_lock);
+
+ /* Got a message. Now unpack it */
+ if (req)
+ {
+ req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(req);
+ ret = bcmbal_obj_msg_unpack(msg, &req);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Error during message unpack: %s\n", bcmos_strerror(ret));
+ req_obj->status = ret;
+ }
+ /* Release pending API */
+ BCM_LOG(DEBUG, log_id_public_api, "Posting request semaphore for %p\n", req);
+ bcmos_sem_post(&req->sem);
+ }
+
+ if (msg)
+ bcmos_msg_free(msg); /* release packed message. It is no longer needed */
+ }
+
+ my_task->destroyed = BCMOS_TRUE;
+
+ return (BCM_ERR_OK == ret) ? 0 : -EINVAL;
+}
+
+static bcmbal_mgmt_oper_id _bcmbal_obj_to_oper_id(const bcmbal_obj *objinfo)
+{
+ if (objinfo->group == BCMBAL_MGT_GROUP_STAT)
+ {
+ return BCMBAL_MGMT_OPER_ID_GET_STATS;
+ }
+ else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_GET))
+ {
+ return BCMBAL_MGMT_OPER_ID_GET;
+ }
+ else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_CLEAR))
+ {
+ return BCMBAL_MGMT_OPER_ID_CLEAR;
+ }
+ else
+ {
+ return BCMBAL_MGMT_OPER_ID_SET;
+ }
+}
+
+#define BALAPI_OPER_TIMEOUT (30000000) /* 30 seconds */
+
+static bcmos_errno _bcmbal_oper(bcmbal_obj *objinfo)
+{
+ bal_comm_msg_hdr *comm_hdr = bcmbal_bal_hdr_get(objinfo);
+ bcmos_msg *os_msg;
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /*
+ * Send the message to the core for processing
+ */
+
+ /* Parameter checks */
+ BUG_ON(NULL == objinfo);
+
+ /* Check the magic number to be sure that the object has been properly initialized */
+ if(BCMBAL_OBJ_INIT_VAL != objinfo->obj_init_val)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "Object has not been initialized: must use a BCMBAL INIT macro on the object before calling the BAL API\n");
+ return BCM_ERR_PARM;
+ }
+
+ ret = bcmos_sem_create(&comm_hdr->sem, 0, 0, "api_req");
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Can't create semaphore: %s\n", bcmos_strerror(ret));
+ /* return here. We don't want to destroy semaphore that wasn't created */
+ return ret;
+ }
+
+ do
+ {
+ bcmbal_msg_hdr_set(objinfo,
+ BCMBAL_MGMT_MSG,
+ BAL_MSG_TYPE_REQ,
+ BAL_SUBSYSTEM_PUBLIC_API,
+ objinfo->obj_type,
+ _bcmbal_obj_to_oper_id(objinfo),
+ 0);
+
+ BCM_LOG(DEBUG, log_id_public_api, "about to send %p\n", objinfo);
+
+ bcmos_mutex_lock(&balapi_lock);
+ bcmbal_ex_id_set(objinfo, ++balapi_exchange_id);
+ os_msg = bcmbal_bcmos_hdr_get(objinfo);
+ STAILQ_INSERT_TAIL(&pending_req_list, os_msg, next);
+ bcmos_mutex_unlock(&balapi_lock);
+
+ if (BCM_ERR_OK != (ret = bcmbal_msg_send(p_balapi_to_core_queue, objinfo, BCMOS_MSG_SEND_NO_FREE_ON_ERROR)))
+ {
+ BCM_LOG(ERROR, log_id_public_api, "message send failed with error: %s\n", bcmos_strerror(ret));
+ break;
+ }
+ BCM_LOG(DEBUG, log_id_public_api, "REQ message sent to core\n");
+
+ /*
+ * We've sent the message to the core, now, wait for the response (or timeout)
+ */
+ ret = bcmos_sem_wait(&comm_hdr->sem, BALAPI_OPER_TIMEOUT);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "rsp message receive for failed with error: %s\n",
+ bcmos_strerror(ret));
+ break;
+ }
+ BCM_LOG(DEBUG, log_id_public_api, "RSP message received from core\n");
+
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "failed to process rsp msg\n");
+ break;
+ }
+
+ if(BCM_ERR_OK != objinfo->status)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "remote message command status is: %s\n",
+ bcmos_strerror(objinfo->status));
+ }
+
+ /*
+ * Pass the command status received from the core back to the caller
+ */
+ ret = objinfo->status;
+ }
+ while(0);
+
+ bcmos_sem_destroy(&comm_hdr->sem);
+
+ return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Set (or modify) command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_set(bcmbal_cfg *objinfo)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SET\n");
+
+ if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ }
+ else
+ {
+ objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_SET;
+ ret = _bcmbal_oper(&objinfo->hdr);
+ }
+
+ return ret;
+}
+
+#define BCMBAL_MAX_PROXY_PACKET_SIZE (1600)
+
+/*****************************************************************************
+ * BAL Public API Packet Send function.
+ *****************************************************************************/
+bcmos_errno bcmbal_pkt_send(bcmbal_dest dest,
+ const char *packet_to_send,
+ uint16_t packet_len)
+{
+ /* Convert the user packet into a BAL object */
+ bcmbal_packet_cfg *p_packet_obj;
+ bcmbal_packet_key key;
+ bcmbal_u8_list_u32 pkt;
+ bcmos_errno ret;
+
+ BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SEND to %s\n",
+ (BCMBAL_DEST_TYPE_NNI == dest.type) ? "NNI" : "SUB-TERM");
+
+ if(BCMBAL_MAX_PROXY_PACKET_SIZE < packet_len)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "user packet length (%d) cannot be greater than %d\n",
+ packet_len,
+ BCMBAL_MAX_PROXY_PACKET_SIZE);
+
+ return BCM_ERR_PARM;
+ }
+
+ BCM_LOG(INFO, log_id_public_api, "user packet first 8 bytes %02X%02X%02X%02X%02X%02X%02X%02X\n",
+ packet_to_send[0], packet_to_send[1], packet_to_send[2], packet_to_send[3],
+ packet_to_send[4], packet_to_send[5], packet_to_send[6], packet_to_send[7]);
+
+ /* Set up the object key */
+ key.packet_send_dest = dest;
+
+ /* Allocate room for the packet object including the user packet */
+ p_packet_obj = bcmos_calloc(sizeof(bcmbal_packet_cfg) + packet_len);
+
+ BCMBAL_CFG_INIT(p_packet_obj, packet, key);
+
+ /* Now fill in user packet data into the object */
+ pkt.len = packet_len;
+ pkt.val = (uint8_t *)&p_packet_obj[1];
+ memcpy(pkt.val, packet_to_send, packet_len);
+
+ BCMBAL_CFG_PROP_SET(p_packet_obj, packet, pkt, pkt);
+
+ p_packet_obj->hdr.hdr.type = BCMBAL_OBJ_MSG_TYPE_SET; /* internally packet SEND is modeled as a config SET */
+ ret = _bcmbal_oper(&(p_packet_obj->hdr.hdr));
+ bcmos_free(p_packet_obj);
+
+ return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Get command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_get(bcmbal_cfg *objinfo)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(DEBUG, log_id_public_api, "BAL PUBLIC API - BCMBAL_GET\n");
+
+ if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ }
+ else
+ {
+ objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_GET;
+ ret = _bcmbal_oper(&(objinfo->hdr));
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Clear command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_clear(bcmbal_cfg *objinfo)
+{
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_CLEAR\n");
+
+ if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+ ret = BCM_ERR_NOT_SUPPORTED;
+
+ }
+ else
+ {
+ objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_CLEAR;
+ ret = _bcmbal_oper(&objinfo->hdr);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+ * @brief BAL Public API Get Stats command.
+ *****************************************************************************/
+bcmos_errno bcmbal_stat_get(bcmbal_stat *objinfo)
+{
+
+ /* Parameter checks */
+ BUG_ON(NULL == objinfo);
+
+ /*
+ * @todo Finish the stats function
+ */
+
+ BCM_LOG(ERROR, log_id_public_api, "bal get stats API not supported\n");
+
+ return BCM_ERR_NOT_SUPPORTED;
+}
+
+/*****************************************************************************
+ * BAL Public API indication subscription.
+ *****************************************************************************/
+bcmos_errno bcmbal_subscribe_ind(bcmbal_cb_cfg *cb_cfg)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ /*
+ * The indication subscription function
+ */
+ BCM_LOG(DEBUG, log_id_public_api, "BAL indication subscription for type: %s (%d)\n",
+ bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);
+
+ ret = _manage_api_ind_listener(IND_CB_SUBSCRIBE, cb_cfg);
+
+ return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API indication un-subscription.
+ *****************************************************************************/
+bcmos_errno bcmbal_unsubscribe_ind(bcmbal_cb_cfg *cb_cfg)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BUG_ON(NULL == cb_cfg);
+
+ /*
+ * The indication subscription function
+ */
+ BCM_LOG(DEBUG, log_id_public_api, "BAL indication un-subscription for type: %s (%d)\n",
+ bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);
+
+ ret = _manage_api_ind_listener(IND_CB_UNSUBSCRIBE, cb_cfg);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to get the string representation of the interface type
+ *
+ * @param int_type The interface type to get
+ *
+ * @returns const char * A pointer to a string containing the interface type,
+ * or "INVALID", if not a valid type.
+ *
+ *****************************************************************************/
+const char *bcmbal_get_interface_type_str(bcmbal_intf_type int_type)
+{
+ const char *type_str;
+
+ switch (int_type)
+ {
+ case(BCMBAL_INTF_TYPE_PON):
+ {
+ type_str = "pon";
+ }
+ break;
+
+ case(BCMBAL_INTF_TYPE_NNI):
+ {
+ type_str = "nni";
+ }
+ break;
+
+ default:
+ {
+ type_str = "INVALID";
+ }
+ break;
+
+ }
+
+ return type_str;
+}
+
+
+/*@}*/
diff --git a/bal_release/src/lib/libbalapi/bal_api.dox b/bal_release/src/lib/libbalapi/bal_api.dox
new file mode 100644
index 0000000..f8db011
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api.dox
@@ -0,0 +1,108 @@
+/*
+ * BAL Programmers Guide - introduction
+ */
+
+/** \mainpage BAL Public Interface Concept
+
+\section intro Introduction
+This document describes the BAL user interface. The user interface is constructed from a
+small set of public APIs and an objects model.
+
+The objects model is designed to manage different entities in the system, and enables a simple and intuitive
+approach for managing line card.
+
+The API layer is designed to enable the management of line card containing muultiple MAC and SWITCH devices
+and support any host application architecture. It includes a set of APIs to access the line card configuration and
+asynchronous indications to send events to the host application.
+
+The API layer is part of the Broadcom® BAL SDK, which is provided as C source code, which is
+independent of the CPU and operating system being used.
+
+\section object_model_table BAL Object Model
+
+The system is modeled as a set of managed objects. The term “object” here doesn’t imply any inheritance, it
+means an entity that can be addressed individually and has a set of properties (attributes) and methods
+(operations), for example, access_terminal, flow, etc.
+
+Each object can have multiple properties (aka attributes), whereas a property is an object parameter that can be set or
+retrieved independently.
+ - A property is a simple type or a structure containing one or more fields, where fields can themselves be
+structures
+ - Each property has a specific permission type, such as Read-Only (RO) and Read-Write (RW).
+
+Object properties are grouped into sections/management groups. The following sections can contain zero or
+more properties:
+ - Key—Field(s) that uniquely identify the object instance (for example, subscriber_terminal key = {subs_id, intf_id}).
+ - Configuration
+ - Read-Write, Read-Only and Write-Only configuration properties
+ - Statistics
+ - Performance monitoring counters
+ - Debug counters
+ - Autonomous Indications
+ - Notifications that are generated asynchronously.
+ Indications can be either autonomous (such as alarms) or asynchronous responses to previously
+ submitted configuration change (for instance, subscriber_terminal admin_state=up request).
+
+\section object_model_prop Object and Properties Implementation
+
+\subsection object_model_structs Object Structures
+
+The main input parameter of all the APIs is an object structure, referred to as the Object Request Message. Each
+object section has a different structure that includes a generic header, object key, and a specific section structure
+according to the section type (for example, configuration, statics, etc).
+ - Generic header: A basic component of all the different section structures is the object generic header
+ \ref bcmbal_obj
+
+ - The configuration structure bcmbal_xx_cfg contains:
+ - The generic header \ref bcmbal_cfg
+ - The object key, if any
+ - The structure bcmbal_xx_cfg_data, containing all object configuration properties
+
+ - This statistics structure bcmbal_xx_stat contains:
+ - The generic header \ref bcmbal_stat
+ - The object key, if any
+ - The structure bcmbal_xx_stat_data, containing all the object statistics
+
+ - The per-autonomous indication structure bcmbal_xx_auto_yy contains:
+ - The generic header \ref bcmbal_auto
+ - The autonomous message ID is stored in the subgroup field.
+ - The object key, if any
+ - The structure bcmbal_xx_auto_yy_data, containing all indication properties, if any
+
+\subsection object_model_init_macros Structure Initialization Macros
+The following macros are used for initializing objects:
+ - \ref BCMBAL_CFG_INIT(cfg_msg, _object, _key)
+ - \ref BCMBAL_STAT_INIT(stat_msg, _object, _key)
+
+The macros perform the following tasks:
+ - Check that the structure matches the object section.
+ - Clear all control fields in the generic header \ref bcmbal_obj.
+
+\subsection object_model_prop_macros Property Presence Mask Manipulation Macros
+The presence mask indicates which of the properties in the object structure need to be accessed (set/get, etc.)
+The mask is a bit field, wherein each bit corresponds to a specific property. The following macros should be used
+for setting the presence mask:
+
+ - Set configuration parameter value:\n
+ \ref BCMBAL_CFG_PROP_SET(_msg, _object, _parm_name, _parm_value)
+ - Indicate that the property should be fetched by a bcmolt_cfg_get() request:\n
+ \ref BCMBAL_CFG_PROP_GET(_msg, _object, _parm_name)
+ - Indicate that the statistic should be fetched by a bcmolt_stat_get() request:\n
+ \ref BCMBAL_STAT_PROP_GET(_msg, _object, _parm_name)
+
+\subsection object_model_enums Enumerations
+In the following descriptions, XX is the object name and YY is the property name from the XML model.
+
+The system model includes the enumerations:
+ - The bcmbal_obj_id enumeration lists all objects. It includes per-object BCMBAL_OBJ_ID_XX constants,
+ where XX is the object name from the XML model.
+ - The bcmbal_xx_cfg_id enumeration lists all XX objects' properties from the “Configuration” section in the
+ XML model. It includes the BCMBAL_XX_CFG_ID_YY constants.
+ - The bcmbal_xx_stat_id enumeration lists all XX object's properties from the “Statistics” section in the XML
+ model. It includes the BCMBAL_XX_STAT_ID_YY constants.
+ - The bcmbal_xx_auto_id enumeration lists all XX object's indications from the “Autonomous Indications”
+ section in the XML model. It includes the BCMBAL_XX_AUTO_ID_YY constants.
+
+\section api_section BAL Public API
+ See \ref api in API Reference chapter
+*/
diff --git a/bal_release/src/lib/libbalapi/bal_api.h b/bal_release/src/lib/libbalapi/bal_api.h
new file mode 100644
index 0000000..60f1e0b
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api.h
@@ -0,0 +1,286 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_api.h
+ * @brief Function declarations and all inclusions required for the BAL Public API
+ *
+ * @defgroup api BAL Public API
+ */
+#ifndef BCMBAL_API_H
+#define BCMBAL_API_H
+
+#include <bcmos_system.h>
+#include <bcmolt_model_types.h>
+
+#include <bal_objs.h>
+
+
+/*@{*/
+
+/*
+ * This example only controls the default access terminal
+ */
+#define DEFAULT_ATERM_ID (0)
+
+/* Max number of access-terminals supported by BAL */
+#define MAX_ACC_TERM_ID (255)
+
+/*------------------------------------------------
+ * See the bal_objs.h file for the BAL objects
+ *------------------------------------------------
+ */
+
+/*
+ * An enumeration of the BAL mgmt operations
+ */
+typedef enum
+{
+ BCMBAL_MGMT_OPER_ID_SET = 1 << 0,
+ BCMBAL_MGMT_OPER_ID_GET = 1 << 1,
+ BCMBAL_MGMT_OPER_ID_GET_STATS = 1 << 2,
+ BCMBAL_MGMT_OPER_ID_CLEAR = 1 << 3,
+ BCMBAL_MGMT_OPER_ID__NUM_OF = 1 << 4,
+ BCMBAL_MGMT_OPER_ID_ALL = BCMBAL_MGMT_OPER_ID__NUM_OF - 1,
+} bcmbal_mgmt_oper_id;
+
+
+/* access_terminal:key:acc_term_id max value */
+#define BAL_API_MAX_ACC_TERM_ID (255)
+
+/* flow:key:flow_id max value */
+#define BAL_API_MAX_FLOW_ID (65535)
+
+/* interface:mtu limits */
+#define BAL_API_MIN_INTF_MTU_SIZE (64)
+#define BAL_API_MAX_INTF_MTU_SIZE (9216)
+
+/* Max number of interfaces per interface:type in BAL */
+#define BAL_API_MAX_INTF_ID (15)
+
+/* Max sub_term_id per interface for the various modes */
+#define BAL_API_MAX_SUB_TERM_ID_GPON (127)
+#define BAL_API_MAX_SUB_TERM_ID_EPON (256)
+#define BAL_API_MAX_SUB_TERM_ID_XGPON (511)
+
+/* Max and min values for interface attributes */
+#define BAL_API_MIN_LOW_DATA_AGG_PORT_ID (256)
+#define BAL_API_MAX_LOW_DATA_AGG_PORT_ID (14591)
+
+#define BAL_API_MIN_LOW_DATA_SVC_PORT_ID (1024)
+#define BAL_API_MAX_LOW_DATA_SVC_PORT_ID (57598)
+
+
+/* Max and Min values for agg_port_id and svc_port_id */
+#define BAL_API_MIN_DATA_SVC_PORT_ID (256)
+#define BAL_API_MAX_DATA_SVC_PORT_ID (16383)
+
+/* Max and Min values for agg_port_id and svc_port_id */
+#define BAL_API_MIN_DATA_AGG_PORT_ID (256)
+#define BAL_API_MAX_DATA_AGG_PORT_ID (16383)
+
+/* Max value for pbits */
+#define MAX_PBITS_VALUE (7)
+
+/*
+ * BAL CLI max values
+ */
+/** Max number of supported OLTs */
+#define MAX_SUPPORTED_OLTS (BAL_API_MAX_ACC_TERM_ID+1)
+
+/** Max number of supported subscriber terminals (ONUs) */
+#define MAX_SUPPORTED_SUBS (BAL_API_MAX_SUB_TERM_ID_XGPON+1)
+
+/** Max number of supported flows */
+#define MAX_SUPPORTED_FLOWS (BAL_API_MAX_FLOW_ID+1)
+
+/** Max number of supported PON and NNI interfaces */
+#define MAX_SUPPORTED_INTF (BAL_API_MAX_INTF_ID+1)
+
+/** BAL Indication callback handler function prototype */
+typedef void (*f_bcmbal_ind_handler)(bcmbal_obj *obj);
+
+/** BAL Indication callback registration parameters */
+typedef struct bcmbal_cb_cfg
+{
+ bcmbal_obj_id obj_type; /**< Object type */
+ f_bcmbal_ind_handler ind_cb_hdlr; /**< Indication callback function. NULL=unregister */
+ bcmos_module_id module; /**< Target module id.
+ If it is BCMOS_MODULE_ID_NONE (0), the callback will be called
+ in BAL's context. Otherwise, it will be called in application
+ module's context */
+} bcmbal_cb_cfg; /* This structure is used for passing the mgmt queue
+
+ * IP:port information between the core main thread and
+ * core worker thread and bal API.
+ */
+typedef struct mgmt_queue_addr_ports
+{
+ const char *core_mgmt_ip_port;
+ const char *balapi_mgmt_ip_port;
+} mgmt_queue_addr_ports;
+
+extern dev_log_id log_id_public_api;
+
+const char *bcmbal_get_interface_type_str(bcmbal_intf_type int_type);
+
+/*
+ *------------------------------------------------------------------------------------------
+ *
+ * @brief The BAL Public API
+ *
+ *------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @brief Initialize the BAL Public API internal data structures
+ *
+ * @param balapi_mgmt_ip_port The IP:port of the BAL API management queue
+ *
+ * @param core_mgmt_ip_port The IP:port of the core management queue
+ *
+ * @returns bcmos_errno
+ *
+ **/
+bcmos_errno bcmbal_api_init(const char *balapi_mgmt_ip_port, const char *core_mgmt_ip_port);
+
+/**
+ * @brief Un-initialize the BAL Public API internal data structures
+ *
+ * @returns bcmos_errno == BCM_ERR_OK
+ *
+ **/
+bcmos_errno bcmbal_api_finish(void);
+
+/**
+ * @brief BAL Public API Set (or modify) command.
+ *
+ * Set (or modify) the specified object instance (with implicit creation
+ * of dynamic objects) associated with the specified access-terminal device.
+ *
+ * @param objinfo A pointer to a BAL object
+ *
+ * @returns bcmos_errno
+ *
+ **/
+bcmos_errno bcmbal_cfg_set(bcmbal_cfg *objinfo);
+
+/**
+ * @brief BAL Public API Get command.
+ *
+ * Get the specified object instance
+ *
+ * @param objinfo A pointer to a BAL object
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_cfg_get(bcmbal_cfg *objinfo);
+
+/**
+ * @brief BAL Public API Packet Send function.
+ *
+ * Send a packet to the specified destination
+ *
+ * @param dest The destination of the user packet
+ *
+ * @param packet_to_send A pointer to the user packet to send to the specified destination
+ *
+ * @param packet_len The length of the user packet (must be <=1600 bytes)
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_pkt_send(bcmbal_dest dest,
+ const char *packet_to_send,
+ uint16_t packet_len);
+
+/**
+ * @brief BAL Public API Clear command.
+ *
+ * Set all attributes to default (or remove the object instance for
+ * dynamic objects) for the specified object instance
+ *
+ * @param objinfo A pointer to a BAL object
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_cfg_clear(bcmbal_cfg * objinfo);
+
+/**
+ * @brief BAL Public API Get Stats command.
+ *
+ * Get (and clear) the stats associated with specified object instance
+ *
+ * @param objinfo A pointer to a BAL object
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_stat_get(bcmbal_stat *objinfo);
+
+/**
+ * @brief BAL Public API indication subscription.
+ *
+ * Subscription function for the specified indications
+ *
+ * @param cb_cfg A pointer to the callback configuration parameters for the
+ * object indications being subscribed to.
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_subscribe_ind(bcmbal_cb_cfg *cb_cfg);
+
+/**
+ * @brief BAL Public API indication un-subscription.
+ *
+ * Un-subscription function for the specified (or all) indications
+ *
+ * @param cb_cfg A pointer to the callback configuration parameters for the
+ * object indications being un-subscribed from.
+ *
+ * @returns bcmos_errno
+ *
+ */
+bcmos_errno bcmbal_unsubscribe_ind(bcmbal_cb_cfg *cb_cfg);
+
+/**
+ * @brief Get the number of NNI ports supported by the running system
+ *
+ * @returns Number of NNI ports
+ */
+uint16_t bcmbal_num_nni_ports_get(void);
+
+/*@}*/
+
+#endif /* BCMBAL_API_H */
diff --git a/bal_release/src/lib/libbalapi/bal_api_worker.c b/bal_release/src/lib/libbalapi/bal_api_worker.c
new file mode 100644
index 0000000..178060c
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api_worker.c
@@ -0,0 +1,513 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_api_worker.c
+ * @brief Main processing loop for the worker thread that handles INDications
+ * sent from the core to the BAL public API
+ *
+ */
+
+/*
+ * We need access to the BAL subsystem names
+ */
+#define BAL_SUBSYSTEM_STR_REQ
+
+#include <bcmos_system.h>
+#include <bal_msg.h>
+#include <bal_obj_msg_pack_unpack.h>
+#include <bal_osmsg.h>
+#include <bal_api.h>
+#include "bal_api_worker.h"
+#ifdef BAL_MONOLITHIC
+#include <bal_worker.h>
+#endif
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+#endif
+
+/* This rx thread and worker thread are used to process indications from the core
+ */
+static bcmos_task api_ind_rx_thread;
+static bcmos_task api_ind_worker_thread;
+
+/* Local function declarations */
+static int _bal_ipc_api_ind_rx_handler(long data);
+static void bal_ipc_api_indication_handler(bcmos_module_id module_id, bcmos_msg *msg);
+
+
+typedef struct indication_subscription_inst indication_subscription_inst;
+struct indication_subscription_inst
+{
+ bcmbal_cb_cfg cb_cfg;
+ /**< TAILQ link for list management */
+ TAILQ_ENTRY(indication_subscription_inst) indication_subscription_inst_next;
+};
+
+TAILQ_HEAD(indication_subscription_list_head, indication_subscription_inst) indication_subscription_list;
+
+/*
+ * The queue through which the core converses with
+ * the backend of the Public API for indications.
+ */
+static bcmos_msg_queue bal_api_ind_backend_queue;
+bcmos_msg_queue *p_bal_api_ind_queue;
+
+/* Create API backend message queue */
+bcmos_errno bal_api_ind_msg_queue_create(mgmt_queue_addr_ports *mgmt_queue_info)
+{
+ bcmos_msg_queue_parm msg_q_p = {};
+ bcmos_errno ret = BCM_ERR_OK;
+
+ do
+ {
+ /* Create BAL API indication receive queue - the core sends IND messages
+ * to the BAL public API using this queue.
+ */
+ msg_q_p.name = "api_ind_rx_q";
+
+ if (NULL != mgmt_queue_info->balapi_mgmt_ip_port)
+ {
+ uint16_t portnum;
+ char *p_ind_portnum_str;
+ char balapi_ind_port_str[256];
+
+ /*
+ * make a copy of the user chosen bal api mgmt port
+ */
+ strcpy(balapi_ind_port_str, mgmt_queue_info->balapi_mgmt_ip_port);
+
+ /* Find the port number */
+ p_ind_portnum_str = strchr(balapi_ind_port_str, ':') + 1;
+
+ /* convert to an integer and increment it by one */
+ portnum = atoi(p_ind_portnum_str) + 1;
+
+ /* create the new string defining the BAL API indication port */
+ sprintf(p_ind_portnum_str,"%d", portnum);
+
+ /* Set up the BAL API indication IP:port access parameter
+ */
+ msg_q_p.local_ep_address = balapi_ind_port_str;
+ msg_q_p.remote_ep_address = NULL;
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+ }
+ else
+ {
+ msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_LOCAL;
+ }
+
+ ret = bcmos_msg_queue_create(&bal_api_ind_backend_queue, &msg_q_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't BAL API rx indication queue\n");
+ break;
+ }
+
+ p_bal_api_ind_queue = &bal_api_ind_backend_queue;
+#ifdef BAL_MONOLITHIC
+ if (NULL == mgmt_queue_info->balapi_mgmt_ip_port)
+ p_bal_core_to_api_ind_queue = p_bal_api_ind_queue;
+#endif
+ } while (0);
+
+ return ret;
+}
+
+/* Worker module init function.
+ * Register for messages this module is expected to receive
+ */
+static bcmos_errno _bal_worker_module_bal_api_init(long data)
+{
+ bcmos_task_parm task_p = {};
+ bcmos_errno ret = BCM_ERR_OK;
+
+ BUG_ON(0 == data);
+
+ do
+ {
+ /* Create BAL API indication RX thread */
+ task_p.name = "ipc_api_ind_rx_thread";
+ task_p.priority = TASK_PRIORITY_IPC_RX;
+ task_p.handler = _bal_ipc_api_ind_rx_handler;
+ task_p.data = (long)&bal_api_ind_backend_queue;
+
+ ret = bcmos_task_create(&api_ind_rx_thread, &task_p);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API indication RX thread\n");
+ break;
+ }
+
+ /* Register the message types to be handled by the mgmt module
+ */
+ bcmos_msg_register(BCMBAL_MGMT_API_IND_MSG,
+ 0,
+ BCMOS_MODULE_ID_WORKER_API_IND, bal_ipc_api_indication_handler);
+
+ }
+ while(0);
+
+ return ret;
+}
+
+static int _bal_ipc_api_ind_rx_handler(long data)
+{
+ bcmos_msg_queue *rxq = (bcmos_msg_queue *)data;
+ bcmos_task *my_task = bcmos_task_current();
+ bcmos_msg *msg;
+ bcmos_errno ret = BCM_ERR_OK;
+ void *payload;
+
+ while (!my_task->destroy_request)
+ {
+ payload = NULL;
+ ret = bcmbal_msg_recv(rxq, BCMOS_WAIT_FOREVER, &payload);
+ if (ret)
+ {
+ /* Unexpected failure */
+ BCM_LOG(ERROR, log_id_public_api, "bcmbal_msg_recv() -> %s\n", bcmos_strerror(ret));
+ continue;
+ }
+
+ /* Message received */
+ BCM_LOG(DEBUG, log_id_public_api, "bcmbal_msg_recv(%p) -> %s\n", payload, bcmos_strerror(ret));
+
+ /*
+ * Got a message, so now dispatch it. This will result in one
+ * of the modules (registered for the message being processed)
+ * executing its message callback handler.
+ */
+ msg = bcmbal_bcmos_hdr_get(payload);
+ ret = bcmos_msg_dispatch(msg, BCMOS_MSG_SEND_AUTO_FREE);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "Couldn't dispatch message %d:%d\n",
+ (int)msg->type, (int)msg->instance);
+ }
+ }
+
+ my_task->destroyed = BCMOS_TRUE;
+
+ return (BCM_ERR_OK == ret) ? 0 : -EINVAL;
+}
+
+
+/* Message wrapper that is called when indication is delivered in application module's context */
+static void _int_deliver_wrapper_cb(bcmos_module_id module_id, bcmos_msg *msg)
+{
+ void *msg_payload = bcmbal_payload_ptr_get(bcmbal_bal_hdr_get_by_bcmos_hdr(msg));
+ f_bcmbal_ind_handler handler = (f_bcmbal_ind_handler)bcmbal_scratchpad_get(msg_payload);
+
+ handler((bcmbal_obj *)msg_payload);
+ bcmbal_msg_free((bcmbal_obj *)msg_payload);
+}
+
+static void process_listener_callbacks(bcmbal_obj *obj)
+{
+
+ indication_subscription_inst *current_entry, *p_temp_entry;
+
+ BCM_LOG(DEBUG, log_id_public_api, "inspecting registered callback for object %d\n",
+ obj->obj_type);
+
+ TAILQ_FOREACH_SAFE(current_entry,
+ &indication_subscription_list,
+ indication_subscription_inst_next,
+ p_temp_entry)
+ {
+ BCM_LOG(DEBUG, log_id_public_api, "entry objtype %d\n", current_entry->cb_cfg.obj_type);
+
+ if((BCMBAL_OBJ_ID_ANY == current_entry->cb_cfg.obj_type) ||
+ (current_entry->cb_cfg.obj_type == obj->obj_type))
+ {
+ BCM_LOG(DEBUG, log_id_public_api,
+ "Calling registered callback for object %d\n",
+ obj->obj_type);
+
+ /* call the registered function directly or in the target module's context */
+ if (BCMOS_MODULE_ID_NONE == current_entry->cb_cfg.module)
+ {
+ current_entry->cb_cfg.ind_cb_hdlr(obj);
+ }
+ else
+ {
+ bcmbal_obj *clone = bcmbal_msg_clone(obj);
+ bcmos_errno err;
+ if (NULL == clone)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "Couldn't clone message for object %d\n",
+ obj->obj_type);
+ continue;
+ }
+ bcmbal_scratchpad_set(clone, current_entry->cb_cfg.ind_cb_hdlr);
+ err = bcmbal_msg_call(clone,
+ current_entry->cb_cfg.module,
+ _int_deliver_wrapper_cb,
+ BCMOS_MSG_SEND_AUTO_FREE);
+ if (BCM_ERR_OK != err)
+ {
+ BCM_LOG(ERROR, log_id_public_api,
+ "Couldn't deliver message for object %d to module %d. Error %s\n",
+ obj->obj_type, current_entry->cb_cfg.module, bcmos_strerror(err));
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/*
+ * This is the handler for indication messages received by the BAL Public API
+ * backend from the core. We need to see who has subscribed for these messages,
+ * and call those registered functions.
+ */
+static void bal_ipc_api_indication_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+
+ void *msg_payload;
+
+ msg_payload = bcmbal_payload_ptr_get(bcmbal_bal_hdr_get_by_bcmos_hdr(msg));
+
+ /*
+ * TO-DO
+ * validate the message major and minor version is correct
+ */
+
+ do
+ {
+ if(BAL_SUBSYSTEM_CORE != bcmbal_sender_get(msg_payload))
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Mgmt IND message received from wrong subsystem (%s)\n",
+ subsystem_str[bcmbal_sender_get(msg_payload)]);
+ break;
+ }
+
+ if(BCMBAL_MGMT_API_IND_MSG != bcmbal_type_major_get(msg_payload))
+ {
+ BCM_LOG(ERROR, log_id_public_api,"Mgmt IND message received with wrong major type (%d)\n",
+ bcmbal_type_major_get(msg_payload));
+ break;
+ }
+
+ /* Look through the list of registered subscribers for this indication
+ * and call them.
+ */
+ BCM_LOG(DEBUG, log_id_public_api,
+ "Processing indication listeners\n");
+
+ process_listener_callbacks((bcmbal_obj *)msg_payload);
+
+ }
+ while(0);
+
+ bcmbal_msg_free(msg_payload);
+
+ return;
+}
+
+void enable_bal_api_indications(const char *balapi_mgmt_ip_port)
+{
+
+ bcmos_task_parm task_p = {};
+ bcmos_module_parm module_p = {};
+ bcmos_errno ret = BCM_ERR_OK;
+ mgmt_queue_addr_ports mgmt_queue_info;
+
+ TAILQ_INIT(&indication_subscription_list);
+
+ do
+ {
+ /* Create quues for communication between BAL API and the core */
+ mgmt_queue_info.balapi_mgmt_ip_port = balapi_mgmt_ip_port;
+ ret = bal_api_ind_msg_queue_create(&mgmt_queue_info);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API indication queue\n");
+ break;
+ }
+
+ module_p.qparm.name = "bal_api_ind_worker_module";
+ module_p.init = _bal_worker_module_bal_api_init;
+ module_p.data = (long)&mgmt_queue_info; /* IP address and port information */
+
+ /* Create worker thread & modules for BAL indication messages from the core */
+ task_p.name = "bal_api_ind_worker";
+ task_p.priority = TASK_PRIORITY_WORKER;
+
+ ret = bcmos_task_create(&api_ind_worker_thread, &task_p);
+ if (BCM_ERR_OK != ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API indication worker thread\n");
+ break;
+ }
+
+ ret = bcmos_module_create(BCMOS_MODULE_ID_WORKER_API_IND, &api_ind_worker_thread, &module_p);
+ if (ret)
+ {
+ BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API indication worker module\n");
+ break;
+ }
+
+ BCM_LOG(DEBUG, log_id_public_api, "BAL API indication handler registered\n");
+
+ }
+ while(0);
+
+ return;
+}
+
+
+/** NOTE: when cb_cfg->obj_type is BCMBAL_OBJ_ID_ANY AND type is UN-SUBSCRIBE, then this is unsubscribe all */
+bcmos_errno _manage_api_ind_listener(bcmbal_ind_cb_management_type type, bcmbal_cb_cfg *cb_cfg)
+{
+
+ bcmos_errno ret = BCM_ERR_OK;
+ indication_subscription_inst *new_ind_entry;
+ indication_subscription_inst *current_entry, *p_temp_entry;
+ bcmos_bool is_unsubscribe;
+
+ BUG_ON(NULL == cb_cfg);
+ BUG_ON(NULL == cb_cfg->ind_cb_hdlr);
+
+ is_unsubscribe = (IND_CB_UNSUBSCRIBE == type);
+
+ BCM_LOG(DEBUG,log_id_public_api,
+ "%s: %s for BAL API indications\n",
+ __FUNCTION__,
+ is_unsubscribe ? "Unsubscribing" : "Subscribing");
+
+ do
+ {
+ bcmos_bool b_found_existing_entry = BCMOS_FALSE;
+
+ TAILQ_FOREACH_SAFE(current_entry,
+ &indication_subscription_list,
+ indication_subscription_inst_next,
+ p_temp_entry)
+ {
+ if(
+ ((is_unsubscribe && (BCMBAL_OBJ_ID_ANY == cb_cfg->obj_type)) ? BCMOS_TRUE :
+ (current_entry->cb_cfg.obj_type == cb_cfg->obj_type)) &&
+ (current_entry->cb_cfg.ind_cb_hdlr == cb_cfg->ind_cb_hdlr) &&
+ (current_entry->cb_cfg.module == cb_cfg->module))
+ {
+ BCM_LOG(DEBUG,log_id_public_api,
+ "Found existing registration\n");
+
+ if(is_unsubscribe)
+ {
+ BCM_LOG(DEBUG,log_id_public_api,
+ "Removing registration\n");
+ TAILQ_REMOVE(&indication_subscription_list, current_entry, indication_subscription_inst_next);
+ bcmos_free(current_entry);
+ }
+
+ b_found_existing_entry = BCMOS_TRUE;
+
+ /* Don't stop looking for matches if we are unsubscribing from ANY indications, there could be many
+ * assigned to a single callback function */
+ if(!(is_unsubscribe && (BCMBAL_OBJ_ID_ANY == cb_cfg->obj_type))) break;
+ }
+
+ }
+
+ /* If we are subscribing to indication and we have already recorded
+ * this subscription, OR we are un-subscribing (whether or not we
+ * found a subscription to remove), then return right away with OK
+ */
+ if((BCMOS_TRUE == b_found_existing_entry) || is_unsubscribe)
+ {
+ break;
+ }
+
+ BCM_LOG(DEBUG,log_id_public_api,
+ "Registering NEW subscriber for BAL API indications\n");
+
+ /* This is a new subscription */
+ new_ind_entry = bcmos_calloc(sizeof(indication_subscription_inst));
+
+ if (NULL == new_ind_entry)
+ {
+ BCM_LOG(FATAL, log_id_public_api,
+ "Failed to register api indication subscription\n");
+ ret = BCM_ERR_NOMEM;
+ break;
+ }
+
+ new_ind_entry->cb_cfg = *cb_cfg;
+
+ TAILQ_INSERT_TAIL(&indication_subscription_list, new_ind_entry, indication_subscription_inst_next);
+
+ } while(0);
+
+ return ret;
+
+}
+
+static void free_all_indication_subscriptions(void)
+{
+ indication_subscription_inst *current_entry, *p_temp_entry;
+
+ TAILQ_FOREACH_SAFE(current_entry,
+ &indication_subscription_list,
+ indication_subscription_inst_next,
+ p_temp_entry)
+ {
+ TAILQ_REMOVE(&indication_subscription_list, current_entry, indication_subscription_inst_next);
+ bcmos_free(current_entry);
+ }
+
+ return;
+}
+
+
+void bal_api_indications_finish(void)
+{
+ free_all_indication_subscriptions();
+
+ bcmos_msg_unregister(BCMBAL_MGMT_API_IND_MSG,
+ 0,
+ BCMOS_MODULE_ID_WORKER_API_IND);
+
+ bcmos_msg_queue_destroy(&bal_api_ind_backend_queue);
+
+ bcmos_module_destroy(BCMOS_MODULE_ID_WORKER_API_IND);
+
+ bcmos_task_destroy(&api_ind_rx_thread);
+
+ bcmos_task_destroy(&api_ind_worker_thread);
+
+ return;
+}
diff --git a/bal_release/src/lib/libbalapi/bal_api_worker.h b/bal_release/src/lib/libbalapi/bal_api_worker.h
new file mode 100644
index 0000000..7e258ca
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api_worker.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_worker.h
+ *
+ * @brief Bal worker thread included
+ *
+ * Module contains the data structures and functions used to support the
+ * BAL core worker thread.
+ */
+
+#ifndef BAL_API_WORKER_H
+#define BAL_API_WORKER_H
+
+#include <bcmos_errno.h>
+
+extern bcmos_msg_queue *p_balapi_to_core_queue;
+
+typedef enum {
+ IND_CB_SUBSCRIBE,
+ IND_CB_UNSUBSCRIBE
+}bcmbal_ind_cb_management_type;
+
+/*
+ * Function declarations
+ */
+extern bcmos_errno bal_api_ind_msg_queue_create(mgmt_queue_addr_ports *mgmt_queue_info);
+extern void enable_bal_api_indications(const char *balapi_mgmt_ip_port);
+extern bcmos_errno _manage_api_ind_listener(bcmbal_ind_cb_management_type type, bcmbal_cb_cfg *cb_cfg);
+extern void bal_api_indications_finish(void);
+
+
+#endif /* BAL_API_WORKER_H */
diff --git a/bal_release/src/lib/libbalapicli/Makefile b/bal_release/src/lib/libbalapicli/Makefile
new file mode 100644
index 0000000..44b7bac
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/Makefile
@@ -0,0 +1,37 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = bal_api_cli
+MOD_TYPE = lib
+MOD_DEPS = cli bal_api
+MOD_INC_DIRS = $(SRC_DIR) $(OUT_DIR)
+
+srcs = bal_api_cli.c bal_api_cli_dump.c
+gen_bal_srcs = bal_api_cli_helpers.c bal_api_cli_handlers.c
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli.c b/bal_release/src/lib/libbalapicli/bal_api_cli.c
new file mode 100644
index 0000000..cbbe973
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli.c
@@ -0,0 +1,1059 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#include <bcmos_system.h>
+#include <bcmcli.h>
+#include <bal_api.h>
+#include "bal_api_cli.h"
+#include "bal_api_cli_helpers.h"
+#include "bal_api_cli_handlers.h"
+
+#define BCMBAL_APICLI_CAST_DISCARD_CONST(p, type) (type)((long)(p))
+
+/* bool enum table */
+static bcmcli_enum_val bool_enum[] =
+{
+ { .name = "yes", .val = 1 },
+ { .name = "no", .val = 0 },
+ BCMCLI_ENUM_LAST
+};
+
+static bcmbal_apicli_type_descr bool_type_descr = {
+ .name = "bool",
+ .descr = "Boolean",
+ .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM,
+ .size = sizeof(bcmos_bool),
+ .x = {.e = bool_enum}
+};
+
+/* parameter data */
+typedef struct
+{
+ const bcmbal_apicli_prop_descr *prop; /* property */
+ const bcmbal_apicli_field_descr *field; /* field or NULL */
+ const bcmbal_apicli_field_descr *array_fd; /* array field descriptor or NULL */
+ uint16_t offset; /* offset from the beginning of the property */
+ uint16_t array_fd_offset; /* offset of array_fd from the beginning of the property */
+ bcmbal_mgt_group group; /* management group */
+} bcmbal_apicli_parm_data;
+
+typedef enum
+{
+ BCMBAL_APICLI_FLAGS_NONE = 0,
+ BCMBAL_APICLI_FLAGS_IGNORE_FIELDS = 1 << 0
+} bcmbal_apicli_flags;
+
+/* Current session */
+static bcmcli_session *current_session;
+
+/*
+ * helpers
+ */
+
+/* calculate number of fields in type */
+static uint32_t bcmbal_apicli_get_num_fields_in_type(const bcmbal_apicli_type_descr *td)
+{
+ uint16_t f;
+ uint32_t nf = 0;
+
+
+ switch (td->base_type)
+ {
+ case BCMBAL_APICLI_BASE_TYPE_ID_STRUCT:
+ {
+ if (!td->x.s.num_fields)
+ return 0;
+ BUG_ON(!td->x.s.fields);
+ for (f = 0; f < td->x.s.num_fields; f++)
+ {
+ nf += bcmbal_apicli_get_num_fields_in_type(td->x.s.fields[f].type);
+ }
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNION:
+ {
+ /* Union. Count only common fields */
+ nf = td->x.u.num_common_fields;
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED:
+ {
+ nf = bcmbal_apicli_get_num_fields_in_type(td->x.arr_fixed.elem_type);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN:
+ {
+ nf = bcmbal_apicli_get_num_fields_in_type(td->x.arr_dyn.elem_type);
+ break;
+ }
+
+ default:
+ {
+ nf = 1;
+ break;
+ }
+ }
+
+ return nf;
+}
+
+/* calculate number of property fields for given object+group+subgroup+access. simple property=single field */
+static bcmos_errno bcmbal_apicli_get_num_fields_in_group(bcmbal_obj_id o, bcmbal_mgt_group group, uint16_t subgroup,
+ bcmbal_apicli_prop_access_id access_level, uint32_t *nfields)
+{
+ uint32_t nf = 0;
+ int i;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ for (i = 0; rc != BCM_ERR_RANGE; i++)
+ {
+ const bcmbal_apicli_prop_descr *pd;
+ rc = bcmbal_apicli_object_property(o, group, subgroup, i, &pd);
+ if (rc == BCM_ERR_OK && (pd->access & access_level))
+ {
+ /* Calculate number of fields if write access. Count only properties for read access */
+ if ((access_level & BCMBAL_APICLI_PROP_ACCESS_ID_W) != 0)
+ {
+ BUG_ON(!pd->type);
+ nf += bcmbal_apicli_get_num_fields_in_type(pd->type);
+ }
+ else
+ {
+ ++nf;
+ }
+ }
+ }
+ *nfields = nf;
+
+ return BCM_ERR_OK;
+}
+
+/*
+ * Command handlers
+ */
+
+static bcmos_errno bcmbal_apicli_objects_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ int rc;
+ bcmbal_obj_id o;
+ const char *name, *descr;
+
+ bcmcli_print(session, "System Object Types:\n");
+ bcmcli_print(session, "=======================================\n");
+ bcmcli_print(session, "Id Name Description\n");
+ bcmcli_print(session, "=======================================\n");
+ for (o = 0; o < BCMBAL_OBJ_ID__NUM_OF; o++)
+ {
+ rc = bcmbal_apicli_object_name(o, &name, &descr);
+ if (!rc)
+ bcmcli_print(session, "%.4d %-22s %s\n", o, name, descr);
+ }
+
+ return 0;
+}
+
+static bcmos_errno bcmbal_apicli_set_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ return bcmbal_apicli_call(BCMBAL_MGT_GROUP_CFG, BCMBAL_OBJ_MSG_TYPE_SET, session);
+}
+
+static bcmos_errno bcmbal_apicli_get_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ return bcmbal_apicli_call(BCMBAL_MGT_GROUP_CFG, BCMBAL_OBJ_MSG_TYPE_GET, session);
+}
+
+static bcmos_errno bcmbal_apicli_clear_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ return bcmbal_apicli_call(BCMBAL_MGT_GROUP_CFG, BCMBAL_OBJ_MSG_TYPE_CLEAR, session);
+}
+
+static bcmos_errno bcmbal_apicli_stat_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ return bcmbal_apicli_call(BCMBAL_MGT_GROUP_STAT, BCMBAL_OBJ_MSG_TYPE_GET, session);
+}
+
+/*
+ * Init-time helpers
+ */
+
+/* map to CLI type */
+static bcmos_errno bcmbal_apicli_map_type(
+ const bcmbal_apicli_type_descr *td,
+ const bcmbal_apicli_type_descr *array_td,
+ bcmcli_cmd_parm *cmd_parm)
+{
+ bcmbal_apicli_parm_data *parm_data = cmd_parm->user_data;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ /* Map type */
+ switch(td->base_type)
+ {
+ case BCMBAL_APICLI_BASE_TYPE_ID_SNUM:
+ cmd_parm->type = BCMCLI_PARM_NUMBER;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNUM:
+ cmd_parm->type = BCMCLI_PARM_UNUMBER;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX:
+ cmd_parm->type = BCMCLI_PARM_HEX;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_BOOL:
+ cmd_parm->type = BCMCLI_PARM_ENUM;
+ cmd_parm->enum_table = bool_enum;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_FLOAT:
+ cmd_parm->type = td->size == sizeof(double) ? BCMCLI_PARM_DOUBLE : BCMCLI_PARM_FLOAT;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_STRING:
+ cmd_parm->type = BCMCLI_PARM_STRING;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_IPV4:
+ cmd_parm->type = BCMCLI_PARM_IP;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_MAC:
+ cmd_parm->type = BCMCLI_PARM_MAC;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_ENUM:
+ cmd_parm->type = BCMCLI_PARM_ENUM;
+ cmd_parm->enum_table = td->x.e;
+ break;
+ case BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK:
+ cmd_parm->type = BCMCLI_PARM_ENUM_MASK;
+ cmd_parm->enum_table = td->x.e;
+ break;
+ default:
+ bcmcli_print(current_session, "*** can't map type %s (%d)\n", td->name, (int)td->base_type);
+ rc = BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ /* Map uint8_t array to buffer if it is independent (not structure field) */
+ if (array_td &&
+ td->size == 1 &&
+ (td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNUM || td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX) &&
+ (parm_data->array_fd == parm_data->field || !parm_data->field))
+ {
+ cmd_parm->type = BCMCLI_PARM_BUFFER;
+ }
+
+ return rc;
+}
+
+/* allocate memory for name and description and copy to to parm */
+static bcmos_errno bcmbal_apicli_copy_parm_name(bcmcli_cmd_parm *parm, const char *name, const char *descr)
+{
+ parm->name = bcmos_alloc(strlen(name) + 1);
+ parm->description = bcmos_alloc(strlen(descr) + 1);
+ if ((parm->name == NULL) || (parm->description == NULL))
+ {
+ /* Successful allocation if any will be released by common cleanup
+ * along with the rest of dynamic parameter fields */
+ return BCM_ERR_NOMEM;
+ }
+ strcpy(BCMBAL_APICLI_CAST_DISCARD_CONST(parm->name, void *), name);
+ strcpy(BCMBAL_APICLI_CAST_DISCARD_CONST(parm->description, void *), descr);
+ return BCM_ERR_OK;
+}
+
+/* populate single parameter */
+static int bcmbal_apicli_populate_parm1(
+ const bcmbal_apicli_prop_descr *pd,
+ const bcmbal_apicli_field_descr *fd,
+ const bcmbal_apicli_type_descr *td,
+ const bcmbal_apicli_field_descr *array_fd,
+ uint32_t offset,
+ uint32_t array_fd_offset,
+ bcmcli_cmd_parm *cmd_parm,
+ uint32_t cmd_flags,
+ char *name,
+ char *help)
+{
+ bcmbal_apicli_parm_data *parm_data = cmd_parm->user_data;
+ int rc;
+
+ parm_data->prop = pd;
+ parm_data->field = fd;
+ parm_data->offset = offset;
+ parm_data->array_fd = array_fd;
+ parm_data->array_fd_offset = array_fd_offset;
+
+ rc = bcmbal_apicli_copy_parm_name(cmd_parm, name, help);
+ if (rc)
+ {
+ return rc;
+ }
+ cmd_parm->flags = cmd_flags;
+ if (td->min_val != td->max_val || td->min_val)
+ {
+ cmd_parm->flags |= BCMCLI_PARM_FLAG_RANGE;
+ cmd_parm->low_val = td->min_val;
+ cmd_parm->hi_val = td->max_val;
+ }
+ rc = bcmbal_apicli_map_type(td, array_fd ? array_fd->type : NULL, cmd_parm);
+ if (rc < 0)
+ {
+ return rc;
+ }
+
+ /* Arrays require more work.
+ * - Calculate size. Known for fixed arrays, hard-coded max for dynamic
+ * - Allocate either buffer or array of values based on CLI parameter type
+ * - Calculate offset from the beginning of array entry
+ */
+ if (array_fd)
+ {
+ uint32_t array_size;
+
+ if (array_fd->type->base_type == BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED)
+ {
+ array_size = array_fd->type->x.arr_fixed.size;
+ }
+ else
+ {
+ array_size = array_fd->type->x.arr_dyn.max_size;
+ }
+ if (!array_size)
+ {
+ bcmcli_print(current_session, "*** Error in %s array descriptor. Size is not set.\n", array_fd->name);
+ return BCM_ERR_INTERNAL;
+ }
+ if (cmd_parm->type == BCMCLI_PARM_BUFFER)
+ {
+ rc = bcmbal_buf_alloc(&cmd_parm->value.buffer, array_size);
+ if (rc)
+ {
+ return rc;
+ }
+ }
+ else
+ {
+ cmd_parm->values = bcmos_calloc(sizeof(bcmcli_parm_value) * array_size);
+ if (!cmd_parm->values)
+ {
+ return BCM_ERR_NOMEM;
+ }
+ cmd_parm->max_array_size = array_size;
+ }
+ }
+
+ return 1;
+}
+
+
+/* populate name buf and help buf */
+static void bcmbal_apicli_populate_name_help(const bcmbal_apicli_field_descr *fld, char *name_buf0, char *help_buf0,
+ char *name_buf, char *help_buf)
+{
+ name_buf[0] = 0;
+ help_buf[0] = 0;
+ bcmcli_strncpy(name_buf, name_buf0, BCMBAL_APICLI_MAX_PARM_NAME_LENGTH);
+ if (strlen(name_buf))
+ bcmcli_strncat(name_buf, ".", BCMBAL_APICLI_MAX_PARM_NAME_LENGTH);
+ bcmcli_strncat(name_buf, fld->cli_name ? fld->cli_name : fld->name, BCMBAL_APICLI_MAX_PARM_NAME_LENGTH);
+ bcmcli_strncpy(help_buf, help_buf0, BCMBAL_APICLI_MAX_PARM_HELP_LENGTH);
+ bcmcli_strncat(help_buf, " - ", BCMBAL_APICLI_MAX_PARM_HELP_LENGTH);
+ bcmcli_strncat(help_buf, fld->descr ? fld->descr : fld->name, BCMBAL_APICLI_MAX_PARM_HELP_LENGTH);
+}
+
+/* Allocate CLI parameter array. Set up parm->data */
+static bcmcli_cmd_parm *bcmbal_apicli_parm_alloc(int nparms)
+{
+ uint32_t size;
+ bcmcli_cmd_parm *parms;
+ bcmbal_apicli_parm_data *parm_data;
+ int i;
+
+ /* Allocate parameter table and populate it */
+ size = (sizeof(bcmcli_cmd_parm) + sizeof(bcmbal_apicli_parm_data)) * (nparms + 1);
+ parms = bcmos_calloc(size);
+ if (!parms)
+ return NULL;
+
+ /* Associate parameter_data structs with parameters */
+ parm_data = (bcmbal_apicli_parm_data *)(parms + nparms + 1);
+ for (i = 0; i < nparms; i++)
+ {
+ parms[i].user_data = &parm_data[i];
+ }
+ return parms;
+}
+
+/* clone enum table */
+static bcmcli_enum_val *bcmbal_apicli_clone_enum_table(bcmcli_cmd_parm *parm)
+{
+ bcmcli_enum_val *org_table = parm->enum_table;
+ bcmcli_enum_val *val = org_table;
+ bcmcli_enum_val *clone_table = org_table;
+ int i, n;
+
+ BUG_ON(parm->type != BCMCLI_PARM_ENUM);
+ while (val && val->name)
+ {
+ ++val;
+ }
+ n = val - org_table;
+
+ clone_table = bcmos_calloc(sizeof(bcmcli_enum_val) * (n + 1));
+ if (!clone_table)
+ {
+ return NULL;
+ }
+ for (i = 0; i < n; i++)
+ {
+ clone_table[i].name = org_table[i].name;
+ clone_table[i].val = org_table[i].val;
+ }
+ return clone_table;
+}
+
+
+/* populate CLI parameter(s) from a single property. Can be multiple parameters
+ * if property contains multiple fields.
+ * Returns number of parameters populated >= 0 or error < 0
+ */
+static int bcmbal_apicli_populate_parms_from_property(const bcmbal_apicli_prop_descr *pd,
+ const bcmbal_apicli_field_descr *fd, const bcmbal_apicli_field_descr *array_fd, uint32_t offset,
+ uint32_t array_fd_offset, bcmcli_cmd_parm *parms, bcmbal_apicli_prop_access_id access_level, uint32_t cmd_flags,
+ char *name_buf0, char *help_buf0)
+{
+ const bcmbal_apicli_type_descr *td = fd ? fd->type : pd->type;
+ uint32_t nf = 0;
+ char name_buf[BCMBAL_APICLI_MAX_PARM_NAME_LENGTH];
+ char help_buf[BCMBAL_APICLI_MAX_PARM_HELP_LENGTH];
+ int rc = 0;
+
+ /* presence masks are not set directly, they are calculated based on other fields */
+ if (fd != NULL && (fd->flags & BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK) != 0)
+ {
+ return BCM_ERR_READ_ONLY;
+ }
+
+ /* At top level take name from property */
+ if (td == pd->type)
+ {
+ /* In case there's a global prefix */
+ char *top_name_buf = name_buf0;
+ uint32_t top_name_buf_len = BCMBAL_APICLI_MAX_PARM_NAME_LENGTH;
+ uint32_t prefix_len = strlen(name_buf0);
+ if (prefix_len > 0)
+ {
+ top_name_buf += prefix_len;
+ top_name_buf_len -= prefix_len;
+ }
+
+ bcmcli_strncpy(top_name_buf, pd->cli_name ? pd->cli_name : pd->name, top_name_buf_len);
+ bcmcli_strncpy(help_buf0, pd->descr ? pd->descr : pd->name, BCMBAL_APICLI_MAX_PARM_HELP_LENGTH);
+ }
+
+ /* For read access we only mark whether read property or not. It is not field-by-field operation */
+ if (access_level == BCMBAL_APICLI_PROP_ACCESS_ID_R)
+ {
+ td = &bool_type_descr;
+ }
+
+ /* In case of arrays we should
+ * - check that there is no array in array. It is not supported
+ * - store array type descriptor FFU and replace the "current" type descriptor with element type
+ * - reset offset because for array fields it should be calculated from array base rather than property
+ */
+ if (td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN || td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED)
+ {
+ if (array_fd)
+ {
+ bcmcli_print(
+ current_session,
+ "*** %s in %s: arrays-in-arrays are not supported\n",
+ pd->name,
+ array_fd->name);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ /* store array type and fetch element type */
+ array_fd = fd ? fd : (const bcmbal_apicli_field_descr *)pd;
+ if (td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN)
+ {
+ td = td->x.arr_dyn.elem_type;
+ }
+ else
+ {
+ td = td->x.arr_fixed.elem_type;
+ }
+ array_fd_offset = offset;
+ offset = 0;
+ }
+
+ if (td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_STRUCT)
+ {
+ uint16_t f;
+ if (!td->x.s.num_fields)
+ return 0;
+ BUG_ON(!td->x.s.fields);
+ for (f = 0; f < td->x.s.num_fields; f++)
+ {
+ const bcmbal_apicli_field_descr *fld = &td->x.s.fields[f];
+ bcmbal_apicli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
+ rc = bcmbal_apicli_populate_parms_from_property(pd, fld, array_fd, offset+fld->offset,
+ array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
+ if (rc > 0)
+ nf += rc;
+ }
+ }
+ else if (td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNION)
+ {
+ /* Union */
+ uint16_t f;
+ const bcmbal_apicli_field_descr *fld;
+ bcmcli_cmd_parm *sel_parm;
+ bcmbal_apicli_parm_data *sel_data;
+ bcmcli_enum_val *e;
+
+ if (!td->x.u.num_common_fields)
+ return 0;
+ BUG_ON(!td->x.u.common_fields);
+
+ /* Populate parameters preceding the union selector */
+ for (f = 0; f < td->x.u.classifier_idx; f++)
+ {
+ fld = &td->x.u.common_fields[f];
+ bcmbal_apicli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
+ rc = bcmbal_apicli_populate_parms_from_property(pd, fld, array_fd,
+ offset+fld->offset, array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
+ if (rc > 0)
+ nf += rc;
+ }
+
+ /* Now populate parameter for selector */
+ sel_parm = &parms[nf];
+ fld = &td->x.u.common_fields[f];
+ bcmbal_apicli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
+ rc = bcmbal_apicli_populate_parms_from_property(pd, fld, array_fd,
+ offset+fld->offset, array_fd_offset, sel_parm, access_level, cmd_flags, name_buf, help_buf);
+ if (rc > 0)
+ nf += rc;
+ /* Clone enum table in order to allow modifying it */
+ if (rc >= 1)
+ {
+ sel_parm->enum_table = bcmbal_apicli_clone_enum_table(sel_parm);
+ if (!sel_parm->enum_table)
+ {
+ rc = BCM_ERR_NOMEM;
+ }
+ }
+
+ /* Now set-up selector */
+ sel_parm->flags |= BCMCLI_PARM_FLAG_SELECTOR;
+ sel_data = sel_parm->user_data;
+ e = sel_parm->enum_table;
+ while (e && e->name && rc >= 0)
+ {
+ fld = &td->x.u.union_fields[e - sel_parm->enum_table];
+ if (fld->type)
+ {
+ int np = bcmbal_apicli_get_num_fields_in_type(fld->type);
+ int i;
+
+ e->parms = bcmbal_apicli_parm_alloc(np);
+ if (!e->parms)
+ {
+ rc = BCM_ERR_NOMEM;
+ break;
+ }
+ for (i = 0; i < np; i++)
+ {
+ bcmbal_apicli_parm_data *data = e->parms[i].user_data;
+ data->group = sel_data->group;
+ }
+ /* Collapse substructure name */
+ if (fld->type->base_type == BCMBAL_APICLI_BASE_TYPE_ID_STRUCT ||
+ fld->type->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNION)
+ {
+ bcmcli_strncpy(name_buf, name_buf0, sizeof(name_buf));
+ bcmcli_strncpy(help_buf, help_buf0, sizeof(help_buf));
+ }
+ else
+ {
+ bcmbal_apicli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
+ }
+ rc = bcmbal_apicli_populate_parms_from_property(pd, fld, array_fd,
+ offset+fld->offset, array_fd_offset, e->parms, access_level, cmd_flags, name_buf, help_buf);
+ }
+ ++e;
+ }
+
+ /* Finally populate parameters following the selector parameter */
+ for (f = td->x.u.classifier_idx + 1; f < td->x.u.num_common_fields && rc >= 0; f++)
+ {
+ fld = &td->x.u.common_fields[f];
+ bcmbal_apicli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
+ rc = bcmbal_apicli_populate_parms_from_property(pd, fld, array_fd,
+ offset+fld->offset, array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
+ if (rc > 0)
+ nf += rc;
+ }
+ }
+ else
+ {
+ /* Finally! Simple type that maps to a single CLI parameter */
+ nf = bcmbal_apicli_populate_parm1(pd, fd, td, array_fd, offset, array_fd_offset,
+ &parms[0], cmd_flags, name_buf0, help_buf0);
+ }
+ return (rc >= 0) ? nf : rc;
+}
+
+/* populate CLI parameter table */
+static int bcmbal_apicli_populate_parms(
+ bcmbal_obj_id o,
+ bcmbal_mgt_group group,
+ uint16_t subgroup,
+ bcmbal_apicli_prop_access_id access_level,
+ bcmcli_cmd_parm *parms,
+ uint32_t cmd_flags,
+ const char *prefix)
+{
+ int nf = 0;
+ int i;
+ bcmos_errno rc = BCM_ERR_OK;
+
+ for (i = 0; rc != BCM_ERR_RANGE; i++)
+ {
+ const bcmbal_apicli_prop_descr *pd;
+ char name_buf[BCMBAL_APICLI_MAX_PARM_NAME_LENGTH] = "";
+ char help_buf[BCMBAL_APICLI_MAX_PARM_HELP_LENGTH] = "";
+
+ strncpy(name_buf, prefix, BCMBAL_APICLI_MAX_PARM_NAME_LENGTH-1);
+ name_buf[BCMBAL_APICLI_MAX_PARM_NAME_LENGTH-1] = 0;
+
+ rc = bcmbal_apicli_object_property(o, group, subgroup, i, &pd);
+ if (rc == BCM_ERR_OK && (pd->access & access_level))
+ {
+ rc = bcmbal_apicli_populate_parms_from_property(pd, NULL, NULL, 0, 0, &parms[nf],
+ access_level, cmd_flags, name_buf, help_buf);
+ if (rc > 0)
+ nf += rc;
+ }
+ }
+ return nf;
+}
+
+
+/* compact selector table. squeeze out values that don't have parameter table attached */
+static void bcmbal_apicli_compact_selector(bcmcli_enum_val *selector, int size)
+{
+ int i, j;
+
+ for (i = 0; i < size; i++)
+ {
+ if (!selector[i].parms)
+ {
+ for ( j = i + 1; j < size && !selector[j].parms; j ++)
+ ;
+ if (j < size)
+ {
+ memcpy(&selector[i], &selector[j], sizeof(bcmcli_enum_val));
+ memset(&selector[j], 0, sizeof(bcmcli_enum_val));
+ }
+ else
+ {
+ memset(&selector[i], 0, sizeof(bcmcli_enum_val));
+ }
+ }
+ }
+}
+
+/* Free CLI parameters. both name and description are allocated dynamically */
+static void bcmbal_apicli_free_parms(bcmcli_cmd_parm *parms)
+{
+ bcmcli_cmd_parm *p = parms;
+
+ while (p->name)
+ {
+ if ((p->flags & BCMCLI_PARM_FLAG_SELECTOR))
+ {
+ /* Remove selector table */
+ bcmcli_enum_val *sel = p->enum_table;
+ if (sel)
+ {
+ bcmcli_enum_val *e = sel;
+ while(e->name)
+ {
+ if (e->parms)
+ {
+ bcmbal_apicli_free_parms(e->parms);
+ }
+ ++e;
+ }
+ bcmos_free(sel);
+ }
+ }
+ if (p->description)
+ bcmos_free(BCMBAL_APICLI_CAST_DISCARD_CONST(p->description, void *));
+ if (p->name)
+ bcmos_free(BCMBAL_APICLI_CAST_DISCARD_CONST(p->name, void *));
+ if (p->max_array_size && p->values)
+ bcmos_free(p->values);
+ if (p->value.buffer.start)
+ bcmbal_buf_free(&p->value.buffer);
+
+ ++p;
+ }
+ bcmos_free(parms);
+}
+
+static uint8_t bcmbal_apicli_get_num_cmd_parms(bcmbal_mgt_group group, bcmbal_apicli_flags flags)
+{
+ if (group == BCMBAL_MGT_GROUP_STAT)
+ return 2; /* object + stat ID */
+ else
+ return 1; /* object */
+}
+
+/* Read generated info and add CLI command */
+static bcmos_errno bcmbal_apicli_add(bcmcli_entry *dir, const char *cmd_name, const char *cmd_descr,
+ bcmbal_mgt_group group, bcmbal_apicli_prop_access_id access_level, bcmcli_cmd_cb cmd_handler,
+ bcmbal_apicli_flags flags)
+{
+ bcmcli_cmd_extra_parm cmd_extras = { .free_parms = bcmbal_apicli_free_parms };
+ bcmcli_cmd_parm *cmd_parms;
+ bcmcli_enum_val *obj_selector;
+ bcmbal_obj_id o;
+ bcmos_errno rc = BCM_ERR_OK;
+ uint32_t cmd_flags = 0;
+ uint8_t num_cmd_parms = bcmbal_apicli_get_num_cmd_parms(group, flags);
+ int n_obj;
+ int i;
+
+ /* Command flags: parameters in the following groups are optional */
+ if (group == BCMBAL_MGT_GROUP_CFG || group == BCMBAL_MGT_GROUP_STAT || group == BCMBAL_MGT_GROUP_AUTO_CFG)
+ cmd_flags = BCMCLI_PARM_FLAG_OPTIONAL;
+
+ /* command parameters are:
+ * - object_name (selector)
+ * - object_key_fields
+ * - object_per_group_fields filtered by access
+ * Therefore, there is 1 top-level enum parameter (object type) with per-value parameter tables
+ * In the case of operations or proxy messages, there is also a top-level enum parameter for the oper/proxy name
+ */
+
+ /* Allocate enum table based on max number of objects. Will be compacted in the end */
+ cmd_parms = bcmos_calloc(sizeof(bcmcli_cmd_parm) * (num_cmd_parms + 1));
+ if (!cmd_parms)
+ return BCM_ERR_NOMEM;
+
+ /* Allocate enough space for all object entries as well as a terminator entry (which is left NULL) */
+ obj_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (BCMBAL_OBJ_ID__NUM_OF + 1));
+ if (!obj_selector)
+ goto nomem_cleanup;
+
+ /* Allocate parameter table */
+ n_obj = 0;
+ for (o = 0; o < BCMBAL_OBJ_ID__NUM_OF; o++)
+ {
+ uint32_t nkeyfields = 0;
+ uint32_t nfields = 0;
+ uint32_t nfilterfields = 0;
+ uint32_t size;
+ uint16_t s;
+ uint16_t subgroup_count = bcmbal_apicli_get_subgroup_count(o, group);
+ bcmcli_enum_val *sub_selector;
+
+ if (subgroup_count == 0)
+ continue;
+
+ obj_selector[n_obj].val = o;
+ rc = bcmbal_apicli_object_name(o, &obj_selector[n_obj].name, NULL);
+ if (rc)
+ continue;
+
+ /* Get number of key fields and save it */
+ if (group == BCMBAL_MGT_GROUP_AUTO_CFG)
+ {
+ nkeyfields = 0;
+ }
+ else
+ {
+ bcmbal_apicli_get_num_fields_in_group(
+ o, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_APICLI_PROP_ACCESS_ID_W, &nkeyfields);
+ }
+
+ /* Allocate subgroup enum table */
+ sub_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (subgroup_count + 1));
+ if (!sub_selector)
+ goto nomem_cleanup;
+
+ /* Allocate single subgroup command parameter */
+ size = sizeof(bcmcli_cmd_parm) * 2;
+ obj_selector[n_obj].parms = bcmos_calloc(size);
+ if (!obj_selector[n_obj].parms)
+ {
+ bcmos_free(sub_selector);
+ goto nomem_cleanup;
+ }
+
+ /* Setup single subgroup command parameter */
+ obj_selector[n_obj].parms[0].type = BCMCLI_PARM_ENUM;
+ obj_selector[n_obj].parms[0].flags = BCMCLI_PARM_FLAG_SELECTOR;
+ obj_selector[n_obj].parms[0].enum_table = sub_selector;
+ rc = bcmbal_apicli_copy_parm_name(&obj_selector[n_obj].parms[0],
+ "sub",
+ "Subgroup (specific operation / proxy msg)");
+ if (rc)
+ goto nomem_cleanup;
+
+ for (s = 0; s < subgroup_count; ++s)
+ {
+ const char *sub_name;
+ bcmcli_cmd_parm *parm_ptr;
+
+ /* Get name of specific subgroup */
+ rc = bcmbal_apicli_object_subgroup_name(o, group, s, &sub_name, NULL);
+ if (rc)
+ continue;
+
+ /* Setup entry in subgroup enum table */
+ sub_selector[s].name = sub_name;
+ sub_selector[s].val = s;
+
+ /* Get number of group fields */
+ rc = bcmbal_apicli_get_num_fields_in_group(o, group, s, access_level, &nfields);
+ if (rc)
+ continue;
+
+ if ((flags & BCMBAL_APICLI_FLAGS_IGNORE_FIELDS) != BCMBAL_APICLI_FLAGS_NONE)
+ {
+ nfilterfields = 0;
+ nfields = 0;
+ }
+
+ /* Allocate parameter table and populate it */
+ sub_selector[s].parms = bcmbal_apicli_parm_alloc(nfields + nkeyfields + nfilterfields);
+ if (!sub_selector[s].parms)
+ {
+ rc = BCM_ERR_NOMEM;
+ goto nomem_cleanup;
+ }
+ for (i = 0; i < nkeyfields + nfields + nfilterfields; i++)
+ {
+ bcmbal_apicli_parm_data *parm_data = sub_selector[s].parms[i].user_data;
+ parm_data->group = (i < nkeyfields) ? BCMBAL_MGT_GROUP_KEY : group;
+ }
+
+ parm_ptr = sub_selector[s].parms;
+ if (nkeyfields)
+ {
+ rc = bcmbal_apicli_populate_parms(
+ o, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_APICLI_PROP_ACCESS_ID_W, parm_ptr, 0, "");
+ if (rc < 0)
+ goto nomem_cleanup;
+ parm_ptr += rc;
+ }
+ if (nfilterfields)
+ {
+ rc = bcmbal_apicli_populate_parms(
+ o, group, s, BCMBAL_APICLI_PROP_ACCESS_ID_RW, parm_ptr, cmd_flags, "filter.");
+ if (rc < 0)
+ goto nomem_cleanup;
+ parm_ptr += rc;
+ }
+ if (nfields)
+ {
+ rc = bcmbal_apicli_populate_parms(o, group, s, access_level, parm_ptr, cmd_flags, "");
+ if (rc < 0)
+ goto nomem_cleanup;
+ parm_ptr += rc;
+ }
+ }
+
+ /* Compact sub_selector enum. Removes holes (values without parameter table) */
+ bcmbal_apicli_compact_selector(sub_selector, subgroup_count);
+
+ /* If the group type doesn't support subgroups, remove the subgroup param entry */
+ if (group == BCMBAL_MGT_GROUP_CFG || group == BCMBAL_MGT_GROUP_STAT || group == BCMBAL_MGT_GROUP_AUTO_CFG)
+ {
+ /* Free the memory associated with the (single) subgroup param */
+ bcmos_free(BCMBAL_APICLI_CAST_DISCARD_CONST(obj_selector[n_obj].parms[0].name, void *));
+ bcmos_free(BCMBAL_APICLI_CAST_DISCARD_CONST(obj_selector[n_obj].parms[0].description, void *));
+ bcmos_free(obj_selector[n_obj].parms);
+ /* Assign the subgroup params to the root object params */
+ obj_selector[n_obj].parms = sub_selector[0].parms;
+ bcmos_free(sub_selector);
+ }
+
+ ++n_obj; /* number of configured objects */
+ }
+
+ /* Compact obj_selector enum. Removes holes (values without parameter table) */
+ bcmbal_apicli_compact_selector(obj_selector, BCMBAL_OBJ_ID__NUM_OF);
+
+ /* Add a 'clear on read' to stats group */
+ if (group == BCMBAL_MGT_GROUP_STAT)
+ {
+ cmd_parms[0].type = BCMCLI_PARM_ENUM;
+ cmd_parms[0].enum_table = bool_enum;
+ rc = bcmbal_apicli_copy_parm_name(&cmd_parms[0], "clear", "clear on read");
+ if (rc)
+ goto nomem_cleanup;
+ }
+
+ /* We are ready to add this command */
+ cmd_parms[num_cmd_parms - 1].type = BCMCLI_PARM_ENUM;
+ cmd_parms[num_cmd_parms - 1].flags = BCMCLI_PARM_FLAG_SELECTOR;
+ cmd_parms[num_cmd_parms - 1].enum_table = obj_selector;
+ rc = bcmbal_apicli_copy_parm_name(&cmd_parms[num_cmd_parms - 1], "object", "Object Type");
+ if (rc)
+ goto nomem_cleanup;
+ rc = bcmcli_cmd_add(dir, cmd_name, cmd_handler, cmd_descr,
+ (access_level == BCMBAL_APICLI_PROP_ACCESS_ID_W) ? BCMCLI_ACCESS_ADMIN : BCMCLI_ACCESS_GUEST,
+ &cmd_extras, cmd_parms);
+ if (rc)
+ goto nomem_cleanup;
+ return 0;
+
+nomem_cleanup:
+ if (obj_selector)
+ {
+ for (o = 0; o < BCMBAL_OBJ_ID__NUM_OF; o++)
+ {
+ if (obj_selector[o].parms)
+ bcmbal_apicli_free_parms(obj_selector[o].parms);
+ }
+ bcmos_free(obj_selector);
+ }
+ bcmos_free(cmd_parms);
+ return rc;
+}
+
+static bcmcli_session *bcmbal_apicli_log;
+static FILE *bcmbal_apicli_log_file;
+
+static int bcmbal_apicli_log_write_cb(bcmcli_session *session, const char *buf, uint32_t size)
+{
+ if (bcmbal_apicli_log_file == NULL || buf == NULL)
+ return BCM_ERR_INTERNAL;
+ fwrite(buf, 1, size, bcmbal_apicli_log_file);
+ fflush(bcmbal_apicli_log_file);
+ return BCM_ERR_OK;
+}
+
+/* Enable/disable API logging
+ * BCMCLI_MAKE_PARM("file", "Log file. Use \"-\" to disable logging", BCMCLI_PARM_STRING, 0));
+ */
+static bcmos_errno bcmbal_apicli_log_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+ const char *fname = parm[0].value.string;
+ bcmcli_session_parm session_params =
+ {
+ .write = bcmbal_apicli_log_write_cb,
+ .name = "api_log"
+ };
+ bcmos_errno rc;
+ time_t start_time;
+
+ /* Close existing log session if any */
+ if (bcmbal_apicli_log)
+ {
+ bcmcli_log_set(BCMCLI_LOG_NONE, NULL);
+ bcmcli_session_close(bcmbal_apicli_log);
+ fclose(bcmbal_apicli_log_file);
+ bcmbal_apicli_log = NULL;
+ bcmbal_apicli_log_file = NULL;
+ }
+
+ if (!strcmp(fname, "-"))
+ return BCM_ERR_OK;
+
+ /* Starting a new log session */
+ bcmbal_apicli_log_file = fopen(fname, "a");
+ if (bcmbal_apicli_log_file == NULL)
+ {
+ bcmcli_print(session, "Can't open file %s for logging\n", fname);
+ return BCM_ERR_PARM;
+ }
+ rc = bcmcli_session_open_user(&session_params, &bcmbal_apicli_log);
+ if (rc)
+ {
+ fclose(bcmbal_apicli_log_file);
+ bcmbal_apicli_log_file = NULL;
+ bcmcli_print(session, "Can't open log session. Error %s\n", bcmos_strerror(rc));
+ return rc;
+ }
+ time(&start_time);
+ bcmcli_log_set(BCMCLI_LOG_C_COMMENT, bcmbal_apicli_log);
+ bcmcli_log("/* API logging session started. %s */\n", ctime(&start_time));
+ return BCM_ERR_OK;
+}
+
+static void bcmbal_apicli_find_del_cmd(bcmcli_entry *dir, const char *cmd_name)
+{
+ bcmcli_entry *cmd;
+ cmd = bcmcli_cmd_find(dir, cmd_name);
+ if (cmd)
+ {
+ bcmcli_token_destroy(cmd);
+ }
+}
+
+/* Unregisters commands and directories */
+void bcmbal_apicli_del_commands(bcmcli_session *session, bcmcli_entry *api_dir)
+{
+ bcmbal_apicli_find_del_cmd(api_dir, "set");
+ bcmbal_apicli_find_del_cmd(api_dir, "get");
+ bcmbal_apicli_find_del_cmd(api_dir, "clear");
+ bcmbal_apicli_find_del_cmd(api_dir, "stat");
+ bcmbal_apicli_find_del_cmd(api_dir, "objects");
+ bcmbal_apicli_find_del_cmd(api_dir, "log");
+}
+
+/* Registers commands and directories */
+bcmos_errno bcmbal_apicli_add_commands(bcmcli_session *session, bcmcli_entry *api_dir)
+{
+ bcmos_errno rc;
+
+ current_session = session;
+
+ /* Now generate and add commands */
+ rc = bcmbal_apicli_add(api_dir, "set", "Set object configuration", BCMBAL_MGT_GROUP_CFG,
+ BCMBAL_APICLI_PROP_ACCESS_ID_W, bcmbal_apicli_set_handler, BCMBAL_APICLI_FLAGS_NONE);
+ rc = rc ? rc : bcmbal_apicli_add(api_dir, "get", "Get object configuration", BCMBAL_MGT_GROUP_CFG,
+ BCMBAL_APICLI_PROP_ACCESS_ID_R, bcmbal_apicli_get_handler, BCMBAL_APICLI_FLAGS_NONE);
+ rc = rc ? rc : bcmbal_apicli_add(api_dir, "clear", "Clear object configuration", BCMBAL_MGT_GROUP_CFG,
+ BCMBAL_APICLI_PROP_ACCESS_ID_R, bcmbal_apicli_clear_handler, BCMBAL_APICLI_FLAGS_IGNORE_FIELDS);
+ rc = rc ? rc : bcmbal_apicli_add(api_dir, "stat", "Get statistics", BCMBAL_MGT_GROUP_STAT,
+ BCMBAL_APICLI_PROP_ACCESS_ID_R, bcmbal_apicli_stat_handler, BCMBAL_APICLI_FLAGS_NONE);
+
+ /* List all system objects */
+ rc = rc ? rc : bcmcli_cmd_add(api_dir, "objects", bcmbal_apicli_objects_handler,
+ "Object Types", BCMCLI_ACCESS_GUEST, NULL, NULL);
+
+ BCMCLI_MAKE_CMD(api_dir, "log", "Log API calls", bcmbal_apicli_log_handler,
+ BCMCLI_MAKE_PARM("file", "Log file. Use \"-\" to disable logging", BCMCLI_PARM_STRING, 0));
+
+ return rc;
+}
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli.h b/bal_release/src/lib/libbalapicli/bal_api_cli.h
new file mode 100644
index 0000000..2acc2a7
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli.h
@@ -0,0 +1,40 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#ifndef BCMBAL_APICLI_H_
+#define BCMBAL_APICLI_H_
+
+#include <bcmcli.h>
+
+void bcmbal_apicli_del_commands(bcmcli_session *session, bcmcli_entry *api_dir);
+
+/* Add BAL CLI commands */
+bcmos_errno bcmbal_apicli_add_commands(bcmcli_session *session, bcmcli_entry *api_dir);
+
+#endif /* BCMBAL_APICLI_H_ */
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_dump.c b/bal_release/src/lib/libbalapicli/bal_api_cli_dump.c
new file mode 100644
index 0000000..5a34961
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_dump.c
@@ -0,0 +1,823 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#include <bcmos_system.h>
+#include <bal_obj.h>
+#include <bcmcli.h>
+#include "bal_api_cli_helpers.h"
+
+typedef enum
+{
+ BCMBAL_APICLI_OUTPUT_STYLE_STD,
+ BCMBAL_APICLI_OUTPUT_STYLE_C_INIT
+} bcmbal_apicli_output_style;
+
+typedef struct
+{
+ const bcmbal_apicli_type_descr *type;
+ void *data;
+ uint8_t bit;
+} bcmbal_apicli_presence_mask_info;
+
+static bcmos_errno bcmbal_apicli_dump_array(
+ bcmcli_session *session,
+ const bcmbal_apicli_type_descr *td,
+ void *data,
+ uint32_t size,
+ const char *name,
+ bcmbal_apicli_output_style style,
+ const bcmbal_apicli_presence_mask_info *presence_mask);
+
+static bcmos_errno bcmbal_apicli_read_snum(
+ bcmcli_session *session, const bcmbal_apicli_type_descr *td, void *data, int64_t *n)
+{
+ switch (td->size)
+ {
+ case 1:
+ {
+ int8_t n1 = *(int8_t *)data;
+ *n = n1;
+ break;
+ }
+ case 2:
+ {
+ int16_t n2 = *(int16_t *)data;
+ *n = n2;
+ break;
+ }
+ case 4:
+ {
+ int32_t n4 = *(int32_t *)data;
+ *n = n4;
+ break;
+ }
+ case 8:
+ {
+ memcpy(n, data, sizeof(*n));
+ break;
+ }
+ default:
+ bcmcli_print(session, "*** number size %u is not supported\n", td->size);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bcmbal_apicli_read_unum(
+ bcmcli_session *session, const bcmbal_apicli_type_descr *td, void *data, uint64_t *n)
+{
+ switch (td->size)
+ {
+ case 1:
+ {
+ uint8_t n1 = *(uint8_t *)data;
+ *n = n1;
+ break;
+ }
+ case 2:
+ {
+ uint16_t n2 = *(uint16_t *)data;
+ *n = n2;
+ break;
+ }
+ case 4:
+ {
+ uint32_t n4 = *(uint32_t *)data;
+ *n = n4;
+ break;
+ }
+ case 8:
+ {
+ memcpy(n, data, sizeof(*n));
+ break;
+ }
+ default:
+ bcmcli_print(session, "*** number size %u is not supported\n", td->size);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ return BCM_ERR_OK;
+}
+
+static void bcmbal_apicli_strcat_upper(char *dest, uint32_t dest_len, const char *src, uint32_t src_len)
+{
+ uint32_t src_idx;
+ uint32_t dest_idx;
+
+ for (dest_idx = 0; dest_idx < dest_len - 1; ++dest_idx)
+ {
+ if (dest[dest_idx] == '\0')
+ {
+ break;
+ }
+ }
+
+ for (src_idx = 0; src_idx < src_len && dest_idx < dest_len - 1; ++src_idx, ++dest_idx)
+ {
+ dest[dest_idx] = src[src_idx];
+ if (dest[dest_idx] >= 'a' && dest[dest_idx] <= 'z')
+ {
+ dest[dest_idx] = 'A' + (dest[dest_idx] - 'a');
+ }
+ }
+
+ dest[dest_idx] = '\0';
+}
+
+static const char *bcmbal_apicli_get_c_enum_id(const bcmbal_apicli_type_descr *td, const char *name)
+{
+ static char full_name_buf[256];
+ full_name_buf[0] = '\0';
+ bcmbal_apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), td->name, strlen(td->name));
+ bcmbal_apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), "_", 1);
+ bcmbal_apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), name, strlen(name));
+ return full_name_buf;
+}
+
+static bcmos_errno bcmbal_apicli_dump_simple_data_type(
+ bcmcli_session *session,
+ const bcmbal_apicli_type_descr *td,
+ void *data,
+ const char *name,
+ bcmbal_apicli_output_style style)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ switch (td->base_type)
+ {
+ case BCMBAL_APICLI_BASE_TYPE_ID_SNUM: /* signed number */
+ {
+ int64_t n = 0;
+ rc = bcmbal_apicli_read_snum(session, td, data, &n);
+ bcmcli_print(session, "%lld", (long long)n);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNUM: /* unsigned number */
+ {
+ uint64_t n = 0;
+ rc = bcmbal_apicli_read_unum(session, td, data, &n);
+ bcmcli_print(session, "%llu", (unsigned long long)n);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX: /* unsigned number printed in hex */
+ {
+ uint64_t n = 0;
+ rc = bcmbal_apicli_read_unum(session, td, data, &n);
+ bcmcli_print(session, "0x%llx", (unsigned long long)n);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_FLOAT: /* floating-point number */
+ {
+ if (td->size == sizeof(float))
+ {
+ bcmcli_print(session, "%f", *(float *)data);
+ }
+ else if (td->size == sizeof(double))
+ {
+ bcmcli_print(session, "%f", *(double *)data);
+ }
+ else
+ {
+ bcmcli_print(session, "*** floating-point number of width %u is not supported\n", td->size);
+ rc = BCM_ERR_NOT_SUPPORTED;
+ }
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_BOOL:
+ {
+ const char *no_str = style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT ? "BCMOS_FALSE" : "no";
+ const char *yes_str = style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT ? "BCMOS_TRUE" : "yes";
+ uint64_t n = 0;
+ rc = bcmbal_apicli_read_unum(session, td, data, &n);
+ bcmcli_print(session, "%s", n == 0 ? no_str : yes_str);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_STRING: /* string */
+ {
+ if (td->size == 0)
+ {
+ bcmcli_print(session, "\"%s\"", (char *)data);
+ }
+ else
+ {
+ /* we know the size of the buffer */
+ bcmcli_print(session, "\"%.*s\"", td->size, (char *)data);
+ }
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_IPV4: /* IPv4 address */
+ {
+ uint32_t ip;
+ memcpy(&ip, data, sizeof(ip));
+ bcmcli_print(
+ session,
+ style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT ? "{ %d,%d,%d,%d }" : "%d.%d.%d.%d",
+ (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_MAC: /* MAC address */
+ {
+ bcmos_mac_address mac;
+ memcpy(mac.u8, data, sizeof(mac.u8));
+ bcmcli_print(
+ session,
+ style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT ?
+ "{{ 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x }}" :
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac.u8[0], mac.u8[1], mac.u8[2], mac.u8[3], mac.u8[4], mac.u8[5]);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ENUM: /* enum */
+ {
+ uint64_t n = 0;
+ const char *s;
+ rc = bcmbal_apicli_read_unum(session, td, data, &n);
+ BUG_ON(td->x.e == NULL);
+ s = bcmcli_enum_stringval(td->x.e, (long)n);
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ s = bcmbal_apicli_get_c_enum_id(td, s);
+ }
+ bcmcli_print(session, "%s", s);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK:
+ {
+ uint64_t n = 0;
+ const char *s;
+ const char *none = NULL;
+ bcmcli_enum_val *value = td->x.e;
+ bcmos_bool first = BCMOS_TRUE;
+ BUG_ON(value == NULL);
+ rc = bcmbal_apicli_read_unum(session, td, data, &n);
+ while (value->name != NULL)
+ {
+ if (value->val == 0)
+ {
+ none = value->name;
+ }
+ if ((value->val & n) != 0)
+ {
+ s = value->name;
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ s = bcmbal_apicli_get_c_enum_id(td, s);
+ }
+ bcmcli_print(session, "%s%s", first ? "" : (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT ? "|" : BCMCLI_ENUM_MASK_DEL_STR), s);
+ first = BCMOS_FALSE;
+ n -= value->val;
+ }
+ ++value;
+ }
+ if (first)
+ {
+ bcmcli_print(session, "%s", (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT) || (NULL == none) ? "0" : none);
+ }
+ break;
+ }
+
+ default:
+ bcmcli_print(session, "*** type %d is not supported\n", (int)td->base_type);
+ rc = BCM_ERR_NOT_SUPPORTED;
+ break;
+ }
+ return rc;
+}
+
+
+/* calculate number of enum values */
+static int bcmbal_apicli_get_num_enum_vals(const bcmcli_enum_val *vals)
+{
+ const bcmcli_enum_val *v = vals;
+ while (v && v->name)
+ {
+ ++v;
+ }
+ return (v - vals);
+}
+
+/* helper function to skip the "u." in front of union field names */
+static inline const char *bcmbal_apicli_skip_union_prefix(const char *name)
+{
+ if (name[0] == 'u' && name[1] == '.')
+ {
+ name += 2;
+ }
+ return name;
+}
+
+static bcmos_bool bcmbal_apicli_is_value_set(
+ bcmcli_session *session,
+ const bcmbal_apicli_presence_mask_info *presence_mask)
+{
+ uint64_t pm_value_num = 0;
+ if (!presence_mask || !presence_mask->type)
+ {
+ /* no presence mask - all values are implicitly set */
+ return BCMOS_TRUE;
+ }
+ bcmbal_apicli_read_unum(session, presence_mask->type, presence_mask->data, &pm_value_num);
+ return ((pm_value_num >> presence_mask->bit) & 1) != 0;
+}
+
+/* Dump data type */
+static bcmos_errno bcmbal_apicli_dump_data_type(
+ bcmcli_session *session,
+ const bcmbal_apicli_type_descr *td,
+ void *data,
+ const char *name,
+ uint32_t num_entries,
+ uint32_t entry_size,
+ bcmbal_apicli_output_style style,
+ const bcmbal_apicli_presence_mask_info *presence_mask)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ switch (td->base_type)
+ {
+ case BCMBAL_APICLI_BASE_TYPE_ID_STRUCT:
+ {
+ uint16_t f;
+ char full_name[BCMBAL_APICLI_MAX_PARM_NAME_LENGTH];
+ if (!td->x.s.num_fields)
+ return 0;
+ BUG_ON(!td->x.s.fields);
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, "{ ");
+ }
+ for (f = 0; f < td->x.s.num_fields; f++)
+ {
+ const bcmbal_apicli_field_descr *fld = &td->x.s.fields[f];
+ void *fdata = (void *)((long)data + fld->offset);
+ bcmbal_apicli_presence_mask_info field_pm = {};
+ if (((td->x.s.fields[0].flags & BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK) != 0) &&
+ style != BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ /* If the struct has a presence mask, skip the presence mask field itself, then record the position
+ * of the presence mask so we can check it later for each entry. */
+ if (f == 0)
+ {
+ continue;
+ }
+
+ field_pm.type = td->x.s.fields[0].type;
+ field_pm.data = (uint8_t *)data + td->x.s.fields[0].offset;
+ field_pm.bit = (uint8_t)(f - 1);
+ }
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT && f > 0)
+ {
+ bcmcli_print(session, ", ");
+ }
+ bcmcli_strncpy(full_name, name, sizeof(full_name));
+ bcmcli_strncat(full_name, ".", sizeof(full_name));
+ bcmcli_strncat(full_name, fld->name, sizeof(full_name));
+ rc = bcmbal_apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, &field_pm);
+ }
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, " }");
+ }
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_UNION:
+ {
+ /* Print fields up to selector, then selector, then selected sub-structure */
+ uint16_t f;
+ char full_name[BCMBAL_APICLI_MAX_PARM_NAME_LENGTH];
+ const bcmbal_apicli_field_descr *fld;
+ void *fdata;
+ int64_t selector_val = 0;
+ int num_union_vals;
+
+ if (!td->x.u.num_common_fields)
+ return 0;
+ BUG_ON(!td->x.u.common_fields);
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, "{ ");
+ }
+ /* Common fields, including selector */
+ for (f = 0; f <= td->x.u.classifier_idx && !rc; f++)
+ {
+ fld = &td->x.u.common_fields[f];
+ fdata = (void *)((long)data + fld->offset);
+
+ bcmcli_strncpy(full_name, name, sizeof(full_name));
+ if (fld->name && strlen(fld->name))
+ {
+ bcmcli_strncat(full_name, ".", sizeof(full_name));
+ bcmcli_strncat(full_name, fld->name, sizeof(full_name));
+ }
+ rc = bcmbal_apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask);
+ if (f == td->x.u.classifier_idx)
+ {
+ rc = rc ? rc : bcmbal_apicli_read_snum(session, fld->type, fdata, &selector_val);
+ }
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, ", ");
+ }
+ }
+ if (rc)
+ {
+ bcmcli_print(session, "***internal error when dumping field %s\n",
+ td->x.u.common_fields[f].name);
+ return rc;
+ }
+
+ num_union_vals = bcmbal_apicli_get_num_enum_vals(td->x.u.common_fields[td->x.u.classifier_idx].type->x.e);
+ if ((unsigned)selector_val >= num_union_vals)
+ {
+ bcmcli_print(session, "***invalid union selector value %lld\n", (long long)selector_val);
+ return BCM_ERR_INTERNAL;
+ }
+
+ /* Common fields following selector */
+ for (; f < td->x.u.num_common_fields; f++)
+ {
+ fld = &td->x.u.common_fields[f];
+ fdata = (void *)((long)data + fld->offset);
+
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, ", ");
+ }
+ bcmcli_strncpy(full_name, name, sizeof(full_name));
+ if (fld->name && strlen(fld->name))
+ {
+ bcmcli_strncat(full_name, ".", sizeof(full_name));
+ bcmcli_strncat(full_name, fld->name, sizeof(full_name));
+ }
+ rc = bcmbal_apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask);
+ }
+
+ /* Selected field */
+ fld = &td->x.u.union_fields[selector_val];
+ if (fld->type)
+ {
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, "{ .%s = ", bcmbal_apicli_skip_union_prefix(fld->name));
+ }
+ fdata = (void *)((long)data + fld->offset);
+
+ bcmcli_strncpy(full_name, name, sizeof(full_name));
+ if (fld->name && strlen(fld->name))
+ {
+ bcmcli_strncat(full_name, ".", sizeof(full_name));
+ bcmcli_strncat(full_name, fld->name, sizeof(full_name));
+ }
+ rc = bcmbal_apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask);
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, " }");
+ }
+ }
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, " }");
+ }
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED: /* fixed array */
+ {
+ rc = bcmbal_apicli_dump_array(session, td->x.arr_fixed.elem_type, data, td->x.arr_fixed.size, name, style, presence_mask);
+ break;
+ }
+
+ case BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN: /* dynamic array that should be printed as buffer */
+ {
+ /* Read length */
+ uint32_t array_size;
+ long base_ptr;
+
+ switch (td->x.arr_dyn.len_size )
+ {
+ case 1: array_size = *(uint8_t *)data; break;
+ case 2: array_size = *(uint16_t *)data; break;
+ case 4: array_size = *(uint32_t *)data; break;
+ default:
+ bcmcli_print(session,
+ "*** %s: dyn array len_size %u is not supported\n", name, td->x.arr_dyn.len_size);
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+ base_ptr = BCMOS_ROUND_UP((long)data + td->x.arr_dyn.len_size, sizeof(void *));
+ BUG_ON(!base_ptr);
+ data = *(void **)base_ptr;
+ rc = bcmbal_apicli_dump_array(session, td->x.arr_dyn.elem_type, data, array_size, name, style, presence_mask);
+ break;
+ }
+
+ default:
+ {
+ /* Finally! Simple type that maps to a single CLI parameter */
+ int n;
+ bcmbal_apicli_presence_mask_info local_pm;
+
+ /* If we have a single value and that value is not included in the presence mask, just skip it entirely */
+ if (num_entries == 1 && !bcmbal_apicli_is_value_set(session, presence_mask))
+ {
+ break;
+ }
+
+ if (style != BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ if (name)
+ {
+ bcmcli_print(session, " %s=", name);
+ }
+ if (!num_entries)
+ {
+ bcmcli_print(session, BCMCLI_ARRAY_EMPTY);
+ }
+ }
+
+ /* Dump simple value or array of simple values */
+ local_pm = presence_mask ? *presence_mask : (bcmbal_apicli_presence_mask_info){};
+ for (n = 0; n < num_entries; n++)
+ {
+ if (n)
+ {
+ bcmcli_print(session, ",");
+ }
+
+ /* If we have a presence mask, make sure to print a special token if the value is unset */
+ if (bcmbal_apicli_is_value_set(session, &local_pm))
+ {
+ rc = bcmbal_apicli_dump_simple_data_type(session, td, data, name, style);
+ }
+ else
+ {
+ bcmcli_print(session, BCMCLI_PARM_NO_VALUE);
+ }
+
+ data = (void *)((long)data + entry_size);
+ local_pm.data = (void *)((long)local_pm.data + entry_size);
+ }
+ if (style != BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, "\n");
+ }
+ break;
+ }
+ }
+ return rc;
+}
+
+/* Dump array */
+static bcmos_errno bcmbal_apicli_dump_array(
+ bcmcli_session *session,
+ const bcmbal_apicli_type_descr *td,
+ void *data,
+ uint32_t size,
+ const char *name,
+ bcmbal_apicli_output_style style,
+ const bcmbal_apicli_presence_mask_info *presence_mask)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+
+ /* Print as buffer or element by element ? */
+ if (style == BCMBAL_APICLI_OUTPUT_STYLE_C_INIT)
+ {
+ bcmcli_print(session, "{ ");
+ rc = bcmbal_apicli_dump_data_type(session, td, data, name, size, td->size, style, presence_mask);
+ bcmcli_print(session, " }");
+ }
+ else if ((td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNUM ||
+ td->base_type == BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX) && td->size == 1)
+ {
+ if (bcmbal_apicli_is_value_set(session, presence_mask))
+ {
+ bcmcli_print(session, " %s=\n", name);
+ bcmcli_session_hexdump(session, data, 0, size, " ");
+ }
+ }
+ else
+ {
+ rc = bcmbal_apicli_dump_data_type(session, td, data, name, size, td->size, style, presence_mask);
+ }
+ return rc;
+}
+
+/* Dump property */
+bcmos_errno bcmbal_apicli_dump_prop(bcmcli_session *session, const bcmbal_apicli_prop_descr *pd, void *prop_data)
+{
+ return bcmbal_apicli_dump_data_type(
+ session, pd->type, prop_data, pd->name, 1, 0, BCMBAL_APICLI_OUTPUT_STYLE_STD, NULL);
+}
+
+/* Dump a single property value in C initializer format */
+bcmos_errno bcmbal_apicli_dump_prop_initializer(
+ bcmcli_session *session, const bcmbal_apicli_prop_descr *pd, void *prop_data)
+{
+ return bcmbal_apicli_dump_data_type(
+ session, pd->type, prop_data, pd->name, 1, 0, BCMBAL_APICLI_OUTPUT_STYLE_C_INIT, NULL);
+}
+
+/* Calculate property pointer given the group data pointer and property description */
+static inline void *bcmbal_apicli_prop_data_ptr(void *group_ptr, const bcmbal_apicli_prop_descr *pd)
+{
+ return (void *)((long)group_ptr + pd->offset);
+}
+
+/* Dump object data */
+static bcmos_errno bcmbal_apicli_dump_data(bcmcli_session *session, bcmbal_obj *msg, void *data, uint32_t data_size)
+{
+ uint16_t prop;
+ bcmos_errno rc = BCM_ERR_OK;
+ const bcmbal_apicli_prop_descr *pd;
+
+ bcmcli_print(session, "data:\n");
+ for (prop = 0;
+ bcmbal_apicli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
+ ++prop)
+ {
+ void *prop_data = bcmbal_apicli_prop_data_ptr(data, pd);
+ if (!(msg->presence_mask & (1LL << prop)))
+ continue;
+ if (!prop_data)
+ {
+ continue;
+ }
+ BUG_ON(pd->offset > data_size);
+ rc = bcmbal_apicli_dump_prop(session, pd, prop_data);
+ if (rc != BCM_ERR_OK)
+ {
+ break;
+ }
+ }
+ return rc;
+}
+
+/* Dump object key */
+static bcmos_errno bcmbal_apicli_dump_key(bcmcli_session *session, bcmbal_obj *msg, void *key, uint32_t key_size)
+{
+ uint16_t prop;
+ bcmos_errno rc = BCM_ERR_OK;
+ const bcmbal_apicli_prop_descr *pd;
+
+ bcmcli_print(session, "key:\n");
+ for (prop = 0;
+ bcmbal_apicli_object_property(msg->obj_type, BCMBAL_MGT_GROUP_KEY, 0, prop, &pd) == BCM_ERR_OK;
+ ++prop)
+ {
+ void *prop_data = bcmbal_apicli_prop_data_ptr(key, pd);
+ if (!prop_data)
+ {
+ continue;
+ }
+ BUG_ON(pd->offset > key_size);
+ rc = bcmbal_apicli_dump_prop(session, pd, prop_data);
+ if (rc != BCM_ERR_OK)
+ {
+ break;
+ }
+ }
+ return rc;
+}
+
+const char *bcmbal_apicli_mgt_group_to_str(bcmbal_mgt_group group)
+{
+ static const char *str_table[BCMBAL_MGT_GROUP__NUM_OF] =
+ {
+ [BCMBAL_MGT_GROUP_KEY] = "key",
+ [BCMBAL_MGT_GROUP_CFG] = "cfg",
+ [BCMBAL_MGT_GROUP_STAT] = "stat",
+ [BCMBAL_MGT_GROUP_AUTO] = "auto",
+ [BCMBAL_MGT_GROUP_AUTO_CFG] = "auto_cfg",
+ };
+ return (group >= BCMBAL_MGT_GROUP__NUM_OF) ? "<unknown>" : str_table[group];
+}
+
+/* Dump message */
+bcmos_errno bcmbal_apicli_msg_dump(bcmcli_session *session, bcmbal_obj *msg)
+{
+ bcmos_errno rc;
+ const char *name, *descr;
+ uint32_t key_size;
+ uint32_t key_offset;
+ uint32_t data_size = 0;
+ uint32_t data_offset;
+ void *key = NULL;
+ void *data = NULL;
+
+ rc = bcmbal_apicli_object_name(msg->obj_type, &name, &descr);
+ if (rc)
+ {
+ goto dump_error;
+ }
+
+ bcmcli_print(session, "object: ");
+ if (name)
+ {
+ bcmcli_print(session, "%s", name);
+ }
+ if (descr)
+ {
+ bcmcli_print(session, " - %s", descr);
+ }
+ bcmcli_print(session, "\n");
+ rc = bcmbal_apicli_object_struct_size(msg->obj_type, BCMBAL_MGT_GROUP_KEY, 0, &key_size, &key_offset, &data_size, &data_offset);
+ rc = rc ? rc : bcmbal_apicli_object_struct_size(msg->obj_type, msg->group, msg->subgroup, &key_size, &key_offset, &data_size, &data_offset);
+ if (rc)
+ {
+ goto dump_error;
+ }
+
+ bcmcli_print(session, (msg->type & BCMBAL_OBJ_MSG_TYPE_GET) != 0 ? "get" : "set");
+ if ((msg->type & BCMBAL_OBJ_MSG_TYPE_CLEAR) != 0)
+ {
+ bcmcli_print(session, ",clear");
+ }
+ bcmcli_print(session, " %s ", bcmbal_apicli_mgt_group_to_str(msg->group));
+
+ if (msg->group != BCMBAL_MGT_GROUP_CFG &&
+ msg->group != BCMBAL_MGT_GROUP_STAT &&
+ msg->group != BCMBAL_MGT_GROUP_AUTO_CFG)
+ {
+ const char *sub_name, *sub_descr;
+ /* Get name of specific subgroup */
+ rc = bcmbal_apicli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &sub_name, &sub_descr);
+ if (rc)
+ {
+ goto dump_error;
+ }
+ bcmcli_print(session, "subgroup: %s-%s ", sub_name ? sub_name : "?", sub_descr ? sub_descr : "");
+ }
+ if (msg->dir == BCMBAL_OBJ_MSG_DIR_REQUEST)
+ {
+ bcmcli_print(session, "request\n");
+ }
+ else
+ {
+ bcmcli_print(session, "response: %s\n", bcmos_strerror(msg->status));
+ bcmcli_print(session, "is in-progress: %s\n", (msg->is_inprogress == BCMOS_TRUE) ? "yes" : "no");
+ }
+
+ if ((msg->group != BCMBAL_MGT_GROUP_AUTO_CFG) && key_size)
+ {
+ key = (void *)((long)msg + sizeof(bcmbal_obj));
+ rc = bcmbal_apicli_dump_key(session, msg, key, key_size);
+ if (rc)
+ {
+ goto dump_error;
+ }
+ }
+ if (data_size &&
+ ( ((msg->dir == BCMBAL_OBJ_MSG_DIR_REQUEST) && (msg->type & BCMBAL_OBJ_MSG_TYPE_SET)) ||
+ ((msg->dir == BCMBAL_OBJ_MSG_DIR_RESPONSE) && (msg->type & BCMBAL_OBJ_MSG_TYPE_GET)) ||
+ (msg->group == BCMBAL_MGT_GROUP_AUTO)
+ )
+ )
+ {
+ data = (void *)((long)msg + data_offset);
+ rc = bcmbal_apicli_dump_data(session, msg, data, data_size);
+ if (rc)
+ {
+ goto dump_error;
+ }
+ }
+ return BCM_ERR_OK;
+
+dump_error:
+ bcmcli_print(session, "*** Object dump error %s (%d)\n", bcmos_strerror(rc), rc);
+ return rc;
+}
+
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.c b/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.c
new file mode 100644
index 0000000..cc90bbf
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.c
@@ -0,0 +1,4516 @@
+#include <bcmos_system.h>
+#include <bal_api.h>
+#include <bcmcli.h>
+#include "bal_api_cli_helpers.h"
+#include "bal_api_cli_handlers.h"
+
+bcmcli_session *bcmbal_apicli_log_session = NULL;
+
+typedef struct
+{
+ uint8_t *start;
+ uint32_t used;
+} bcmbal_apicli_byte_pool;
+
+static bcmos_errno bcmbal_apicli_byte_pool_create(bcmbal_apicli_byte_pool *buf)
+{
+ buf->used = 0;
+ buf->start = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ return (buf->start == NULL) ? BCM_ERR_NOMEM : BCM_ERR_OK;
+}
+
+static void bcmbal_apicli_byte_pool_destroy(bcmbal_apicli_byte_pool *buf)
+{
+ bcmos_free(buf->start);
+}
+
+static void *bcmbal_apicli_byte_pool_calloc(bcmbal_apicli_byte_pool *buf, uint32_t num_bytes)
+{
+ void *ret;
+ if (buf->used + num_bytes > BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE)
+ {
+ return NULL;
+ }
+
+ ret = buf->start + buf->used;
+ buf->used += num_bytes;
+ memset(ret, 0, num_bytes);
+ return ret;
+}
+
+/*
+ * Start/end banners - these are specially formatted so listening apps can easily tell where API handling starts/ends.
+ */
+static void bcmbal_apicli_print_start(bcmcli_session *session, const char *api_name)
+{
+ bcmcli_print(session, "[-- API Start: %s --]\n", api_name);
+}
+
+static void bcmbal_apicli_print_data_start(bcmcli_session *session)
+{
+ bcmcli_print(session, "[-- API Message Data --]\n");
+}
+
+static void bcmbal_apicli_print_complete(bcmcli_session *session, bcmos_errno err, const char *err_text)
+{
+ if (err != BCM_ERR_OK && err_text != NULL && err_text[0] != '\0')
+ {
+ bcmcli_print(session, "ERROR: %s", err_text);
+ }
+
+ bcmcli_print(session, "[-- API Complete: %d (%s) --]\n", err, bcmos_strerror(err));
+}
+
+static int bcmbal_apicli_session_write_cb(bcmcli_session *cli_session, const char *buf, uint32_t size)
+{
+ bcmcli_log(buf, "%.*s", size, buf);
+ return (int)size;
+}
+
+/* Logs a property value to the CLI log in such a way that it is a valid RHS in an initializer. For a primitve, this
+ * will just print the value (e.g. "42"). For a struct, it will emit all members in between curly braces. */
+static void bcmbal_apicli_log_prop_val(bcmolt_obj_id obj, bcmolt_mgt_group group, uint16_t subgroup, uint16_t prop, void *value)
+{
+ bcmos_errno err;
+ const bcmbal_apicli_prop_descr *prop_descr;
+
+ if (bcmbal_apicli_log_session == NULL)
+ {
+ static bcmcli_session_parm session_params = { .write = bcmbal_apicli_session_write_cb };
+
+ err = bcmcli_session_open(&session_params, &bcmbal_apicli_log_session);
+ if (err != BCM_ERR_OK)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error opening session: %s", bcmos_strerror(err));
+ return;
+ }
+ }
+
+ err = bcmbal_apicli_object_property(obj, group, subgroup, prop, &prop_descr);
+ if (err != BCM_ERR_OK)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error getting info for property: %s", bcmos_strerror(err));
+ return;
+ }
+
+ err = bcmbal_apicli_dump_prop_initializer(bcmbal_apicli_log_session, prop_descr, value);
+ if (err != BCM_ERR_OK)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error printing property: %s", bcmos_strerror(err));
+ }
+}
+
+static inline bcmos_ipv4_address bcmbal_apicli_unumber_to_ipv4(uint32_t num)
+{
+ bcmos_ipv4_address ip = { .u32 = num };
+ return ip;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_access_terminal_cfg_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_access_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_access_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_access_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_access_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, access_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, access_terminal, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, access_terminal, admin_state);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, access_terminal, admin_state);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "oper_status");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, access_terminal, oper_status);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, access_terminal, oper_status);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "iwf_mode");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, access_terminal, iwf_mode);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, access_terminal, iwf_mode);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, access_terminal, admin_state) && !BCMBAL_CFG_PROP_IS_SET(&cfg, access_terminal, oper_status) && !BCMBAL_CFG_PROP_IS_SET(&cfg, access_terminal, iwf_mode))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, access_terminal, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, access_terminal, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_access_terminal_cfg_set(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_access_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_access_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_access_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_access_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, access_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, access_terminal, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ bcmbal_state val;
+ val = (bcmbal_state) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, access_terminal, admin_state, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, access_terminal, admin_state, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE, &val);
+ bcmcli_log(");\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_access_terminal_cfg_clear(bcmcli_session *session)
+{
+ bcmos_errno err;
+ bcmbal_access_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_access_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_access_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_access_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, access_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, access_terminal, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_flow_cfg_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_flow_cfg cfg; /**< declare main API struct */
+ bcmbal_flow_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_flow_cfg cfg;\n");
+ bcmcli_log("bcmbal_flow_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ key.flow_id = (bcmbal_flow_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_ID, &key.flow_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ key.flow_type = (bcmbal_flow_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_TYPE, &key.flow_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, flow, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, flow, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, admin_state);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, admin_state);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "oper_status");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, oper_status);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, oper_status);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "access_int_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, access_int_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, access_int_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "network_int_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, network_int_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, network_int_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, sub_term_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, sub_term_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_uni_idx");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, sub_term_uni_idx);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, sub_term_uni_idx);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, svc_port_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, svc_port_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "agg_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, agg_port_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, agg_port_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "resolve_mac");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, resolve_mac);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, resolve_mac);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, classifier);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, classifier);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, action);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, action);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sla");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, sla);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, sla);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "cookie");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, cookie);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, cookie);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "priority");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, priority);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, priority);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "group_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, group_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, group_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "queue");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, queue);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, queue);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, flow, admin_state) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, oper_status) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, access_int_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, network_int_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, sub_term_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, sub_term_uni_idx) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, svc_port_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, agg_port_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, resolve_mac) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, classifier) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, action) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, sla) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, cookie) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, priority) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, group_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, flow, queue))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, flow, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, flow, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_flow_cfg_set(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_flow_cfg cfg; /**< declare main API struct */
+ bcmbal_flow_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_flow_cfg cfg;\n");
+ bcmcli_log("bcmbal_flow_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ key.flow_id = (bcmbal_flow_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_ID, &key.flow_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ key.flow_type = (bcmbal_flow_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_TYPE, &key.flow_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, flow, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, flow, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ bcmbal_state val;
+ val = (bcmbal_state) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_ADMIN_STATE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "access_int_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_intf_id val;
+ val = (bcmbal_intf_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "network_int_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_intf_id val;
+ val = (bcmbal_intf_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_sub_id val;
+ val = (bcmbal_sub_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_SUB_TERM_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_uni_idx");
+ if (cli_parm != NULL)
+ {
+ uint8_t val;
+ val = cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_uni_idx, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_uni_idx, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_service_port_id val;
+ val = (bcmbal_service_port_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_SVC_PORT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "agg_port_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_aggregation_port_id val;
+ val = (bcmbal_aggregation_port_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, agg_port_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, agg_port_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_AGG_PORT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "resolve_mac");
+ if (cli_parm != NULL)
+ {
+ bcmos_bool val;
+ val = cli_parm->value.number;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, resolve_mac, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, resolve_mac, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_RESOLVE_MAC, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "classifier.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_classifier val = { };
+ cli_parm = bcmcli_find_named_parm(session, "classifier.o_tpid");
+ if (cli_parm != NULL)
+ {
+ val.o_tpid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_TPID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.o_vid");
+ if (cli_parm != NULL)
+ {
+ val.o_vid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_VID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.i_tpid");
+ if (cli_parm != NULL)
+ {
+ val.i_tpid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_TPID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.i_vid");
+ if (cli_parm != NULL)
+ {
+ val.i_vid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_VID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.o_pbits");
+ if (cli_parm != NULL)
+ {
+ val.o_pbits = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_PBITS;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.i_pbits");
+ if (cli_parm != NULL)
+ {
+ val.i_pbits = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_PBITS;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.ether_type");
+ if (cli_parm != NULL)
+ {
+ val.ether_type = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_ETHER_TYPE;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.dst_mac");
+ if (cli_parm != NULL)
+ {
+ val.dst_mac = cli_parm->value.mac;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_MAC;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.src_mac");
+ if (cli_parm != NULL)
+ {
+ val.src_mac = cli_parm->value.mac;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_MAC;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.ip_proto");
+ if (cli_parm != NULL)
+ {
+ val.ip_proto = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_IP_PROTO;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.dst_ip");
+ if (cli_parm != NULL)
+ {
+ val.dst_ip = bcmbal_apicli_unumber_to_ipv4(cli_parm->value.unumber);
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_IP;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.src_ip");
+ if (cli_parm != NULL)
+ {
+ val.src_ip = bcmbal_apicli_unumber_to_ipv4(cli_parm->value.unumber);
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_IP;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.src_port");
+ if (cli_parm != NULL)
+ {
+ val.src_port = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_PORT;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.dst_port");
+ if (cli_parm != NULL)
+ {
+ val.dst_port = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_PORT;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "classifier.pkt_tag_type");
+ if (cli_parm != NULL)
+ {
+ val.pkt_tag_type = (bcmbal_pkt_tag_type) cli_parm->value.enum_val;
+ val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_classifier val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_CLASSIFIER, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "action.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_action val = { };
+ cli_parm = bcmcli_find_named_parm(session, "action.cmds_bitmask");
+ if (cli_parm != NULL)
+ {
+ val.cmds_bitmask = (bcmbal_action_cmd_id) cli_parm->value.enum_val;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_CMDS_BITMASK;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.o_vid");
+ if (cli_parm != NULL)
+ {
+ val.o_vid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_VID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.o_pbits");
+ if (cli_parm != NULL)
+ {
+ val.o_pbits = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_PBITS;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.o_tpid");
+ if (cli_parm != NULL)
+ {
+ val.o_tpid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_TPID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.i_vid");
+ if (cli_parm != NULL)
+ {
+ val.i_vid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_VID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.i_pbits");
+ if (cli_parm != NULL)
+ {
+ val.i_pbits = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_PBITS;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "action.i_tpid");
+ if (cli_parm != NULL)
+ {
+ val.i_tpid = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_TPID;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_action val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_ACTION, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "sla.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_sla val = { };
+ cli_parm = bcmcli_find_named_parm(session, "sla.min_rate");
+ if (cli_parm != NULL)
+ {
+ val.min_rate = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_SLA_ID_MIN_RATE;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sla.max_rate");
+ if (cli_parm != NULL)
+ {
+ val.max_rate = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_SLA_ID_MAX_RATE;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, flow, sla, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_sla val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_SLA, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, sla, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "cookie");
+ if (cli_parm != NULL)
+ {
+ bcmbal_cookie val;
+ val = (bcmbal_cookie) cli_parm->value.unumber64;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, cookie, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, cookie, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_COOKIE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "priority");
+ if (cli_parm != NULL)
+ {
+ uint16_t val;
+ val = cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, priority, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, priority, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_PRIORITY, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "group_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_group_id val;
+ val = (bcmbal_group_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, flow, group_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, group_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_GROUP_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "queue.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_queue_ref val = { };
+ cli_parm = bcmcli_find_named_parm(session, "queue.sched_id");
+ if (cli_parm != NULL)
+ {
+ val.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "queue.sched_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "queue.queue_id");
+ if (cli_parm != NULL)
+ {
+ val.queue_id = (bcmbal_tm_queue_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "queue.queue_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_queue_ref val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_FLOW_CFG_ID_QUEUE, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_flow_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_flow_cfg cfg; /**< declare main API struct */
+ bcmbal_flow_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_flow_cfg cfg;\n");
+ bcmcli_log("bcmbal_flow_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ key.flow_id = (bcmbal_flow_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_ID, &key.flow_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ key.flow_type = (bcmbal_flow_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_TYPE, &key.flow_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, flow, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, flow, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_flow_stat_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_flow_stat stat; /**< declare main API struct */
+ bcmbal_flow_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_flow_stat stat;\n");
+ bcmcli_log("bcmbal_flow_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_stat_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ key.flow_id = (bcmbal_flow_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_ID, &key.flow_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ key.flow_type = (bcmbal_flow_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "flow_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.flow_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_FLOW_KEY_ID_FLOW_TYPE, &key.flow_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_STAT_INIT(&stat, flow, key);
+ bcmcli_log("BCMBAL_STAT_INIT(&stat, flow, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "rx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, flow, rx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, flow, rx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, flow, rx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, flow, rx_bytes);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, flow, tx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, flow, tx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, flow, tx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, flow, tx_bytes);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_STAT_PROP_IS_SET(&stat, flow, rx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, flow, rx_bytes) && !BCMBAL_STAT_PROP_IS_SET(&stat, flow, tx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, flow, tx_bytes))
+ {
+ BCMBAL_STAT_PROP_GET(&stat, flow, all_properties);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, flow, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_stat_get(&stat.hdr);
+ bcmcli_log("bcmbal_stat_get(&stat.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &stat.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_group_cfg_get(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_group_cfg cfg; /**< declare main API struct */
+ bcmbal_group_key key = { }; /**< declare key */
+ uint8_t *list_mem; /**< declare memory buffer for variable-sized lists */
+ bcmcli_log("bcmbal_group_cfg cfg;\n");
+ bcmcli_log("bcmbal_group_key key = { };\n");
+ bcmcli_log("uint8_t* list_mem;\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "group_id");
+ if (cli_parm != NULL)
+ {
+ key.group_id = (bcmbal_group_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "group_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.group_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_GROUP_KEY_ID_GROUP_ID, &key.group_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, group, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, group, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "members_cmd");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, members_cmd);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, members_cmd);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, members);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, members);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "cookie");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, cookie);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, cookie);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flows");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, flows);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, flows);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, owner);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, owner);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, group, members_cmd) && !BCMBAL_CFG_PROP_IS_SET(&cfg, group, members) && !BCMBAL_CFG_PROP_IS_SET(&cfg, group, cookie) && !BCMBAL_CFG_PROP_IS_SET(&cfg, group, flows) && !BCMBAL_CFG_PROP_IS_SET(&cfg, group, owner))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, group, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, group, all_properties);\n");
+ }
+
+ /* set memory to use for variable-sized lists */
+ list_mem = bcmbal_apicli_byte_pool_calloc(byte_pool, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ if (list_mem == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmcli_log("list_mem = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+ BCMBAL_CFG_LIST_BUF_SET(&cfg, group, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ bcmcli_log("BCMBAL_CFG_LIST_BUF_SET(&cfg, group, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_group_cfg_set(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_group_cfg cfg; /**< declare main API struct */
+ bcmbal_group_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_group_cfg cfg;\n");
+ bcmcli_log("bcmbal_group_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "group_id");
+ if (cli_parm != NULL)
+ {
+ key.group_id = (bcmbal_group_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "group_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.group_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_GROUP_KEY_ID_GROUP_ID, &key.group_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, group, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, group, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "members_cmd");
+ if (cli_parm != NULL)
+ {
+ bcmbal_group_member_cmd val;
+ val = (bcmbal_group_member_cmd) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, group, members_cmd, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, group, members_cmd, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_GROUP_CFG_ID_MEMBERS_CMD, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "members.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_group_member_info_list_u16 val = { };
+ int32_t i0;
+ val.val = bcmbal_apicli_byte_pool_calloc(byte_pool, cli_parm->array_size * sizeof(*val.val));
+ if (val.val == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ val.len = cli_parm->array_size;
+ cli_parm = bcmcli_find_named_parm(session, "members.intf_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.intf_id is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ val.val[i0].intf_id = (bcmbal_intf_id) cli_parm->values[i0].unumber;
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.svc_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.svc_port_id is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ val.val[i0].svc_port_id = (bcmbal_service_port_id) cli_parm->values[i0].unumber;
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.cmds_bitmask");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.cmds_bitmask is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.cmds_bitmask = (bcmbal_action_cmd_id) cli_parm->values[i0].enum_val;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_CMDS_BITMASK;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.o_vid");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.o_vid is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.o_vid = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_O_VID;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.o_pbits");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.o_pbits is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.o_pbits = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_O_PBITS;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.o_tpid");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.o_tpid is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.o_tpid = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_O_TPID;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.i_vid");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.i_vid is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.i_vid = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_I_VID;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.i_pbits");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.i_pbits is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.i_pbits = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_I_PBITS;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.action.i_tpid");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.action.i_tpid is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ if (bcmcli_parm_value_is_set(session, cli_parm, i0))
+ {
+ val.val[i0].action.i_tpid = cli_parm->values[i0].unumber;
+ val.val[i0].action.presence_mask = val.val[i0].action.presence_mask | BCMBAL_ACTION_ID_I_TPID;
+ }
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.queue.sched_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.queue.sched_id is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ val.val[i0].queue.sched_id = (bcmbal_tm_sched_id) cli_parm->values[i0].unumber;
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "members.queue.queue_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->array_size != val.len)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "members.queue.queue_id is a different size than other arrays in the struct\n");
+ return BCM_ERR_PARM;
+ }
+
+ for (i0 = 0; i0 < val.len; i0++)
+ {
+ val.val[i0].queue.queue_id = (bcmbal_tm_queue_id) cli_parm->values[i0].unumber;
+ }
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, group, members, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_group_member_info_list_u16 val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_GROUP_CFG_ID_MEMBERS, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, group, members, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "cookie");
+ if (cli_parm != NULL)
+ {
+ bcmbal_cookie val;
+ val = (bcmbal_cookie) cli_parm->value.unumber64;
+ BCMBAL_CFG_PROP_SET(&cfg, group, cookie, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, group, cookie, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_GROUP_CFG_ID_COOKIE, &val);
+ bcmcli_log(");\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_group_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_group_cfg cfg; /**< declare main API struct */
+ bcmbal_group_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_group_cfg cfg;\n");
+ bcmcli_log("bcmbal_group_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "group_id");
+ if (cli_parm != NULL)
+ {
+ key.group_id = (bcmbal_group_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "group_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.group_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_GROUP_KEY_ID_GROUP_ID, &key.group_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, group, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, group, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_interface_cfg_get(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_interface_cfg cfg; /**< declare main API struct */
+ bcmbal_interface_key key = { }; /**< declare key */
+ uint8_t *list_mem; /**< declare memory buffer for variable-sized lists */
+ bcmcli_log("bcmbal_interface_cfg cfg;\n");
+ bcmcli_log("bcmbal_interface_key key = { };\n");
+ bcmcli_log("uint8_t* list_mem;\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ key.intf_type = (bcmbal_intf_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_TYPE, &key.intf_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, interface, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, interface, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, admin_state);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, admin_state);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "oper_status");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, oper_status);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, oper_status);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "min_data_agg_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, min_data_agg_port_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, min_data_agg_port_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "min_data_svc_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, min_data_svc_port_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, min_data_svc_port_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "transceiver_type");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, transceiver_type);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, transceiver_type);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_miss_mode");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, ds_miss_mode);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, ds_miss_mode);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "mtu");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, mtu);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, mtu);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_control");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, flow_control);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, flow_control);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_tm");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, ds_tm);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, ds_tm);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "us_tm");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, us_tm);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, us_tm);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id_list");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, sub_term_id_list);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, sub_term_id_list);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, interface, admin_state) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, oper_status) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, min_data_agg_port_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, min_data_svc_port_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, transceiver_type) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, ds_miss_mode) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, mtu) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, flow_control) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, ds_tm) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, us_tm) && !BCMBAL_CFG_PROP_IS_SET(&cfg, interface, sub_term_id_list))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, interface, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, interface, all_properties);\n");
+ }
+
+ /* set memory to use for variable-sized lists */
+ list_mem = bcmbal_apicli_byte_pool_calloc(byte_pool, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ if (list_mem == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmcli_log("list_mem = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+ BCMBAL_CFG_LIST_BUF_SET(&cfg, interface, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ bcmcli_log("BCMBAL_CFG_LIST_BUF_SET(&cfg, interface, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_interface_cfg_set(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_interface_cfg cfg; /**< declare main API struct */
+ bcmbal_interface_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_interface_cfg cfg;\n");
+ bcmcli_log("bcmbal_interface_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ key.intf_type = (bcmbal_intf_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_TYPE, &key.intf_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, interface, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, interface, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ bcmbal_state val;
+ val = (bcmbal_state) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, admin_state, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, admin_state, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "min_data_agg_port_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_aggregation_port_id val;
+ val = (bcmbal_aggregation_port_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, min_data_agg_port_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, min_data_agg_port_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "min_data_svc_port_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_service_port_id val;
+ val = (bcmbal_service_port_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, min_data_svc_port_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, min_data_svc_port_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "transceiver_type");
+ if (cli_parm != NULL)
+ {
+ bcmbal_trx_type val;
+ val = (bcmbal_trx_type) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, transceiver_type, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, transceiver_type, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_miss_mode");
+ if (cli_parm != NULL)
+ {
+ bcmbal_ds_miss_mode val;
+ val = (bcmbal_ds_miss_mode) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, ds_miss_mode, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, ds_miss_mode, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "mtu");
+ if (cli_parm != NULL)
+ {
+ uint16_t val;
+ val = cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, mtu, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, mtu, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_MTU, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_control");
+ if (cli_parm != NULL)
+ {
+ bcmbal_control val;
+ val = (bcmbal_control) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, flow_control, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, flow_control, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_tm");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_id val;
+ val = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, ds_tm, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, ds_tm, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_DS_TM, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "us_tm");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_id val;
+ val = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, interface, us_tm, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, interface, us_tm, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_INTERFACE_CFG_ID_US_TM, &val);
+ bcmcli_log(");\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_interface_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_interface_cfg cfg; /**< declare main API struct */
+ bcmbal_interface_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_interface_cfg cfg;\n");
+ bcmcli_log("bcmbal_interface_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ key.intf_type = (bcmbal_intf_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_TYPE, &key.intf_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, interface, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, interface, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_interface_stat_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_interface_stat stat; /**< declare main API struct */
+ bcmbal_interface_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_interface_stat stat;\n");
+ bcmcli_log("bcmbal_interface_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_stat_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ key.intf_type = (bcmbal_intf_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_type = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_INTERFACE_KEY_ID_INTF_TYPE, &key.intf_type);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_STAT_INIT(&stat, interface, key);
+ bcmcli_log("BCMBAL_STAT_INIT(&stat, interface, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "rx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, interface, rx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, interface, rx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, interface, rx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, interface, rx_bytes);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, interface, tx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, interface, tx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, interface, tx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, interface, tx_bytes);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_STAT_PROP_IS_SET(&stat, interface, rx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, interface, rx_bytes) && !BCMBAL_STAT_PROP_IS_SET(&stat, interface, tx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, interface, tx_bytes))
+ {
+ BCMBAL_STAT_PROP_GET(&stat, interface, all_properties);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, interface, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_stat_get(&stat.hdr);
+ bcmcli_log("bcmbal_stat_get(&stat.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &stat.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_packet_cfg_get(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_packet_cfg cfg; /**< declare main API struct */
+ bcmbal_packet_key key = { }; /**< declare key */
+ uint8_t *list_mem; /**< declare memory buffer for variable-sized lists */
+ bcmcli_log("bcmbal_packet_cfg cfg;\n");
+ bcmcli_log("bcmbal_packet_key key = { };\n");
+ bcmcli_log("uint8_t* list_mem;\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "reserved");
+ if (cli_parm != NULL)
+ {
+ key.reserved = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "reserved is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.reserved = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_RESERVED, &key.reserved);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_parm_by_prefix(session, "packet_send_dest.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.type");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.type = (bcmbal_dest_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (key.packet_send_dest.type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.nni.int_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_uni");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_uni = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_uni is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.int_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ break;
+ default:
+ bcmbal_apicli_print_complete(session, BCM_ERR_RANGE, "\n");
+ return BCM_ERR_RANGE;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.packet_send_dest = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST, &key.packet_send_dest);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, packet, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, packet, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, flow_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, flow_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, flow_type);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, flow_type);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, intf_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, intf_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, intf_type);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, intf_type);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, svc_port);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, svc_port);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_cookie");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, flow_cookie);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, flow_cookie);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "pkt");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, pkt);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, pkt);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, packet, flow_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, flow_type) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, intf_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, intf_type) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, svc_port) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, flow_cookie) && !BCMBAL_CFG_PROP_IS_SET(&cfg, packet, pkt))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, packet, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, packet, all_properties);\n");
+ }
+
+ /* set memory to use for variable-sized lists */
+ list_mem = bcmbal_apicli_byte_pool_calloc(byte_pool, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ if (list_mem == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmcli_log("list_mem = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+ BCMBAL_CFG_LIST_BUF_SET(&cfg, packet, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ bcmcli_log("BCMBAL_CFG_LIST_BUF_SET(&cfg, packet, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_packet_cfg_set(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_packet_cfg cfg; /**< declare main API struct */
+ bcmbal_packet_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_packet_cfg cfg;\n");
+ bcmcli_log("bcmbal_packet_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "reserved");
+ if (cli_parm != NULL)
+ {
+ key.reserved = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "reserved is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.reserved = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_RESERVED, &key.reserved);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_parm_by_prefix(session, "packet_send_dest.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.type");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.type = (bcmbal_dest_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (key.packet_send_dest.type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.nni.int_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_uni");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_uni = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_uni is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.int_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ break;
+ default:
+ bcmbal_apicli_print_complete(session, BCM_ERR_RANGE, "\n");
+ return BCM_ERR_RANGE;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.packet_send_dest = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST, &key.packet_send_dest);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, packet, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, packet, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "flow_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_flow_id val;
+ val = (bcmbal_flow_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, flow_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, flow_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_FLOW_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_type");
+ if (cli_parm != NULL)
+ {
+ bcmbal_flow_type val;
+ val = (bcmbal_flow_type) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, flow_type, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, flow_type, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_FLOW_TYPE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ bcmbal_intf_id val;
+ val = (bcmbal_intf_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, intf_id, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, intf_id, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_INTF_ID, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "intf_type");
+ if (cli_parm != NULL)
+ {
+ bcmbal_intf_type val;
+ val = (bcmbal_intf_type) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, intf_type, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, intf_type, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_INTF_TYPE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port");
+ if (cli_parm != NULL)
+ {
+ bcmbal_service_port_id val;
+ val = (bcmbal_service_port_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, svc_port, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, svc_port, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_SVC_PORT, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "flow_cookie");
+ if (cli_parm != NULL)
+ {
+ bcmbal_cookie val;
+ val = (bcmbal_cookie) cli_parm->value.unumber64;
+ BCMBAL_CFG_PROP_SET(&cfg, packet, flow_cookie, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, flow_cookie, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_FLOW_COOKIE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "pkt");
+ if (cli_parm != NULL)
+ {
+ bcmbal_u8_list_u32 val = { };
+ val.len = bcmbal_buf_get_used(&cli_parm->value.buffer);
+ val.val = bcmbal_apicli_byte_pool_calloc(byte_pool, val.len);
+ if (val.val == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmbal_buf_set_pos(&cli_parm->value.buffer, 0);
+ bcmbal_buf_read(&cli_parm->value.buffer, val.val, val.len);
+ BCMBAL_CFG_PROP_SET(&cfg, packet, pkt, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_u8_list_u32 val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_PACKET_CFG_ID_PKT, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, packet, pkt, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_packet_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_packet_cfg cfg; /**< declare main API struct */
+ bcmbal_packet_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_packet_cfg cfg;\n");
+ bcmcli_log("bcmbal_packet_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "reserved");
+ if (cli_parm != NULL)
+ {
+ key.reserved = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "reserved is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.reserved = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_RESERVED, &key.reserved);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_parm_by_prefix(session, "packet_send_dest.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.type");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.type = (bcmbal_dest_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (key.packet_send_dest.type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.nni.int_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.sub_term_uni");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.sub_term_uni = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.sub_term_uni is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packet_send_dest.int_id");
+ if (cli_parm != NULL)
+ {
+ key.packet_send_dest.u.sub_term.int_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest.int_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ break;
+ default:
+ bcmbal_apicli_print_complete(session, BCM_ERR_RANGE, "\n");
+ return BCM_ERR_RANGE;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "packet_send_dest is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.packet_send_dest = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST, &key.packet_send_dest);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, packet, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, packet, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_subscriber_terminal_cfg_get(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_subscriber_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_subscriber_terminal_key key = { }; /**< declare key */
+ uint8_t *list_mem; /**< declare memory buffer for variable-sized lists */
+ bcmcli_log("bcmbal_subscriber_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_subscriber_terminal_key key = { };\n");
+ bcmcli_log("uint8_t* list_mem;\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sub_term_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID, &key.sub_term_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, admin_state);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, admin_state);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "oper_status");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, oper_status);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, oper_status);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "serial_number");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, serial_number);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, serial_number);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "password");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, password);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, password);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "registration_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, registration_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, registration_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port_id");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, svc_port_id);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, svc_port_id);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "mac_address");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, mac_address);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, mac_address);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_tm");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, ds_tm);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, ds_tm);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "us_tm");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, us_tm);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, us_tm);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "svc_port_id_list");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, svc_port_id_list);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, svc_port_id_list);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "agg_port_id_list");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, agg_port_id_list);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, agg_port_id_list);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, admin_state) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, oper_status) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, serial_number) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, password) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, registration_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, svc_port_id) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, mac_address) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, ds_tm) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, us_tm) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, svc_port_id_list) && !BCMBAL_CFG_PROP_IS_SET(&cfg, subscriber_terminal, agg_port_id_list))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, all_properties);\n");
+ }
+
+ /* set memory to use for variable-sized lists */
+ list_mem = bcmbal_apicli_byte_pool_calloc(byte_pool, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ if (list_mem == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmcli_log("list_mem = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+ BCMBAL_CFG_LIST_BUF_SET(&cfg, subscriber_terminal, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ bcmcli_log("BCMBAL_CFG_LIST_BUF_SET(&cfg, subscriber_terminal, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_subscriber_terminal_cfg_set(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_subscriber_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_subscriber_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_subscriber_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_subscriber_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sub_term_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID, &key.sub_term_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "admin_state");
+ if (cli_parm != NULL)
+ {
+ bcmbal_state val;
+ val = (bcmbal_state) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, admin_state, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, admin_state, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "serial_number.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_serial_number val = { };
+ cli_parm = bcmcli_find_named_parm(session, "serial_number.vendor_id");
+ if (cli_parm != NULL)
+ {
+ if (bcmbal_buf_get_used(&cli_parm->value.buffer) != 4)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "buffer serial_number.vendor_id must have 4 bytes\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmbal_buf_set_pos(&cli_parm->value.buffer, 0);
+ bcmbal_buf_read(&cli_parm->value.buffer, val.vendor_id, 4);
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "serial_number.vendor_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "serial_number.vendor_specific");
+ if (cli_parm != NULL)
+ {
+ if (bcmbal_buf_get_used(&cli_parm->value.buffer) != 4)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "buffer serial_number.vendor_specific must have 4 bytes\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmbal_buf_set_pos(&cli_parm->value.buffer, 0);
+ bcmbal_buf_read(&cli_parm->value.buffer, val.vendor_specific, 4);
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "serial_number.vendor_specific is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, serial_number, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_serial_number val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, serial_number, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "password.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_password val = { };
+ cli_parm = bcmcli_find_named_parm(session, "password.arr");
+ if (cli_parm != NULL)
+ {
+ if (bcmbal_buf_get_used(&cli_parm->value.buffer) != 10)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "buffer password.arr must have 10 bytes\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmbal_buf_set_pos(&cli_parm->value.buffer, 0);
+ bcmbal_buf_read(&cli_parm->value.buffer, val.arr, 10);
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "password.arr is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, password, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_password val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, password, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "registration_id.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_registration_id val = { };
+ cli_parm = bcmcli_find_named_parm(session, "registration_id.arr");
+ if (cli_parm != NULL)
+ {
+ if (bcmbal_buf_get_used(&cli_parm->value.buffer) != 36)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "buffer registration_id.arr must have 36 bytes\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmbal_buf_set_pos(&cli_parm->value.buffer, 0);
+ bcmbal_buf_read(&cli_parm->value.buffer, val.arr, 36);
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "registration_id.arr is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, registration_id, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_registration_id val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, registration_id, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "mac_address");
+ if (cli_parm != NULL)
+ {
+ bcmos_mac_address val;
+ val = cli_parm->value.mac;
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, mac_address, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, mac_address, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ds_tm");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_id val;
+ val = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, ds_tm, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, ds_tm, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "us_tm");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_id val;
+ val = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, us_tm, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, subscriber_terminal, us_tm, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM, &val);
+ bcmcli_log(");\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_subscriber_terminal_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_subscriber_terminal_cfg cfg; /**< declare main API struct */
+ bcmbal_subscriber_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_subscriber_terminal_cfg cfg;\n");
+ bcmcli_log("bcmbal_subscriber_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sub_term_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID, &key.sub_term_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_subscriber_terminal_stat_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_subscriber_terminal_stat stat; /**< declare main API struct */
+ bcmbal_subscriber_terminal_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_subscriber_terminal_stat stat;\n");
+ bcmcli_log("bcmbal_subscriber_terminal_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_stat_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sub_term_id");
+ if (cli_parm != NULL)
+ {
+ key.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sub_term_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID, &key.sub_term_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "intf_id");
+ if (cli_parm != NULL)
+ {
+ key.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.intf_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID, &key.intf_id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_STAT_INIT(&stat, subscriber_terminal, key);
+ bcmcli_log("BCMBAL_STAT_INIT(&stat, subscriber_terminal, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "rx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, rx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, rx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, rx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, rx_bytes);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_packets");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, tx_packets);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, tx_packets);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tx_bytes");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, tx_bytes);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, tx_bytes);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_STAT_PROP_IS_SET(&stat, subscriber_terminal, rx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, subscriber_terminal, rx_bytes) && !BCMBAL_STAT_PROP_IS_SET(&stat, subscriber_terminal, tx_packets) && !BCMBAL_STAT_PROP_IS_SET(&stat, subscriber_terminal, tx_bytes))
+ {
+ BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, all_properties);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, subscriber_terminal, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_stat_get(&stat.hdr);
+ bcmcli_log("bcmbal_stat_get(&stat.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &stat.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_queue_cfg_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_queue_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_queue_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_queue_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_queue_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sched_id");
+ if (cli_parm != NULL)
+ {
+ key.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID, &key.sched_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "sched_dir");
+ if (cli_parm != NULL)
+ {
+ key.sched_dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR, &key.sched_dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_queue_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_queue, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_queue, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "priority");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, priority);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, priority);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "weight");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, weight);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, weight);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, rate);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, rate);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, bac);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, bac);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "creation_mode");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, creation_mode);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, creation_mode);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "ref_count");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, ref_count);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, ref_count);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, priority) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, weight) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, rate) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, bac) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, creation_mode) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_queue, ref_count))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_queue, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_queue, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_queue_cfg_set(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_queue_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_queue_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_queue_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_queue_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sched_id");
+ if (cli_parm != NULL)
+ {
+ key.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID, &key.sched_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "sched_dir");
+ if (cli_parm != NULL)
+ {
+ key.sched_dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR, &key.sched_dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_queue_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_queue, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_queue, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "priority");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_priority val;
+ val = (bcmbal_tm_priority) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, tm_queue, priority, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_queue, priority, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_QUEUE_CFG_ID_PRIORITY, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "weight");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_weight val;
+ val = (bcmbal_tm_weight) cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_QUEUE_CFG_ID_WEIGHT, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "rate.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_shaping val = { };
+ cli_parm = bcmcli_find_named_parm(session, "rate.sbr");
+ if (cli_parm != NULL)
+ {
+ val.sbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_SBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate.pbr");
+ if (cli_parm != NULL)
+ {
+ val.pbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_PBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate.burst");
+ if (cli_parm != NULL)
+ {
+ val.burst = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_BURST;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_queue, rate, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_shaping val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_QUEUE_CFG_ID_RATE, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_queue, rate, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "bac.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_bac val = { };
+ cli_parm = bcmcli_find_named_parm(session, "bac.type");
+ if (cli_parm != NULL)
+ {
+ val.type = (bcmbal_tm_bac_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (val.type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ cli_parm = bcmcli_find_named_parm(session, "bac.max_size");
+ if (cli_parm != NULL)
+ {
+ val.u.taildrop.max_size = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.max_size is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ cli_parm = bcmcli_find_parm_by_prefix(session, "bac.red.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.min_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.red.red.min_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.min_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.max_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.red.red.max_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.max_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.max_probability");
+ if (cli_parm != NULL)
+ {
+ val.u.red.red.max_probability = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.max_probability is not set\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ cli_parm = bcmcli_find_parm_by_prefix(session, "bac.green.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "bac.green.min_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.green.min_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.green.min_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.green.max_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.green.max_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.green.max_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.green.max_probability");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.green.max_probability = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.green.max_probability is not set\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.green is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "bac.yellow.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "bac.yellow.min_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.yellow.min_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.yellow.min_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.yellow.max_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.yellow.max_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.yellow.max_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.yellow.max_probability");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.yellow.max_probability = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.yellow.max_probability is not set\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.yellow is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "bac.red.");
+ if (cli_parm != NULL)
+ {
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.min_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.red.min_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.min_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.max_threshold");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.red.max_threshold = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.max_threshold is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bac.red.max_probability");
+ if (cli_parm != NULL)
+ {
+ val.u.wred.red.max_probability = (bcmbal_percent) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red.max_probability is not set\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "bac.red is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ default:
+ bcmbal_apicli_print_complete(session, BCM_ERR_RANGE, "\n");
+ return BCM_ERR_RANGE;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_queue, bac, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_bac val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_QUEUE_CFG_ID_BAC, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_queue, bac, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_queue_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_queue_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_queue_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_queue_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_queue_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sched_id");
+ if (cli_parm != NULL)
+ {
+ key.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID, &key.sched_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "sched_dir");
+ if (cli_parm != NULL)
+ {
+ key.sched_dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR, &key.sched_dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_queue_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_queue, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_queue, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_queue_stat_get(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_queue_stat stat; /**< declare main API struct */
+ bcmbal_tm_queue_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_queue_stat stat;\n");
+ bcmcli_log("bcmbal_tm_queue_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_stat_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "sched_id");
+ if (cli_parm != NULL)
+ {
+ key.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID, &key.sched_id);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "sched_dir");
+ if (cli_parm != NULL)
+ {
+ key.sched_dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "sched_dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.sched_dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR, &key.sched_dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_queue_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_QUEUE_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_STAT_INIT(&stat, tm_queue, key);
+ bcmcli_log("BCMBAL_STAT_INIT(&stat, tm_queue, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "packets_ok");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, tm_queue, packets_ok);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, tm_queue, packets_ok);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bytes_ok");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, tm_queue, bytes_ok);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, tm_queue, bytes_ok);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "packets_discarded");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, tm_queue, packets_discarded);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, tm_queue, packets_discarded);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "bytes_discarded");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_STAT_PROP_GET(&stat, tm_queue, bytes_discarded);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, tm_queue, bytes_discarded);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_STAT_PROP_IS_SET(&stat, tm_queue, packets_ok) && !BCMBAL_STAT_PROP_IS_SET(&stat, tm_queue, bytes_ok) && !BCMBAL_STAT_PROP_IS_SET(&stat, tm_queue, packets_discarded) && !BCMBAL_STAT_PROP_IS_SET(&stat, tm_queue, bytes_discarded))
+ {
+ BCMBAL_STAT_PROP_GET(&stat, tm_queue, all_properties);
+ bcmcli_log("BCMBAL_STAT_PROP_GET(&stat, tm_queue, all_properties);\n");
+ }
+
+ /* call API */
+ err = bcmbal_stat_get(&stat.hdr);
+ bcmcli_log("bcmbal_stat_get(&stat.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &stat.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_sched_cfg_get(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_sched_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_sched_key key = { }; /**< declare key */
+ uint8_t *list_mem; /**< declare memory buffer for variable-sized lists */
+ bcmcli_log("bcmbal_tm_sched_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_sched_key key = { };\n");
+ bcmcli_log("uint8_t* list_mem;\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_get");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "dir");
+ if (cli_parm != NULL)
+ {
+ key.dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_DIR, &key.dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_sched, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_sched, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_named_parm(session, "owner");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, owner);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, owner);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_type");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_type);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_type);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_parent");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_parent);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_parent);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_child_type");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_child_type);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sched_child_type);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, rate);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, rate);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, tcont_sla);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, tcont_sla);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "creation_mode");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, creation_mode);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, creation_mode);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "queues");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, queues);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, queues);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sub_scheds");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sub_scheds);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, sub_scheds);\n");
+ }
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "num_priorities");
+ if (cli_parm != NULL)
+ {
+ if (cli_parm->value.number)
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, num_priorities);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, num_priorities);\n");
+ }
+ }
+
+ /* if no properties were requested, include everything */
+ if (!BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, owner) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, sched_type) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, sched_parent) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, sched_child_type) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, rate) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, tcont_sla) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, creation_mode) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, queues) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, sub_scheds) && !BCMBAL_CFG_PROP_IS_SET(&cfg, tm_sched, num_priorities))
+ {
+ BCMBAL_CFG_PROP_GET(&cfg, tm_sched, all_properties);
+ bcmcli_log("BCMBAL_CFG_PROP_GET(&cfg, tm_sched, all_properties);\n");
+ }
+
+ /* set memory to use for variable-sized lists */
+ list_mem = bcmbal_apicli_byte_pool_calloc(byte_pool, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ if (list_mem == NULL)
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_NOMEM, "\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmcli_log("list_mem = bcmos_calloc(BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+ BCMBAL_CFG_LIST_BUF_SET(&cfg, tm_sched, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);
+ bcmcli_log("BCMBAL_CFG_LIST_BUF_SET(&cfg, tm_sched, list_mem, BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE);\n");
+
+ /* call API */
+ err = bcmbal_cfg_get(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_get(&cfg.hdr);\n");
+ if (err == BCM_ERR_OK)
+ {
+ /* print API contents to the CLI */
+ bcmbal_apicli_print_data_start(session);
+ err = bcmbal_apicli_msg_dump(session, &cfg.hdr.hdr);
+ }
+
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_sched_cfg_set(bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_sched_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_sched_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_sched_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_sched_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_set");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "dir");
+ if (cli_parm != NULL)
+ {
+ key.dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_DIR, &key.dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_sched, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_sched, key);\n");
+
+ /* decode API parameters from CLI */
+ cli_parm = bcmcli_find_parm_by_prefix(session, "owner.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_owner val = { };
+ cli_parm = bcmcli_find_named_parm(session, "owner.type");
+ if (cli_parm != NULL)
+ {
+ val.type = (bcmbal_tm_sched_owner_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (val.type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ cli_parm = bcmcli_find_named_parm(session, "owner.intf_type");
+ if (cli_parm != NULL)
+ {
+ val.u.interface.intf_type = (bcmbal_intf_type) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.intf_type is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.intf_id");
+ if (cli_parm != NULL)
+ {
+ val.u.interface.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ cli_parm = bcmcli_find_named_parm(session, "owner.intf_id");
+ if (cli_parm != NULL)
+ {
+ val.u.sub_term.intf_id = (bcmbal_intf_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ val.u.sub_term.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ cli_parm = bcmcli_find_named_parm(session, "owner.intf_id");
+ if (cli_parm != NULL)
+ {
+ val.u.agg_port.intf_id = cli_parm->value.unumber;
+ val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ val.u.agg_port.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.agg_port_id");
+ if (cli_parm != NULL)
+ {
+ val.u.agg_port.agg_port_id = (bcmbal_aggregation_port_id) cli_parm->value.unumber;
+ val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ cli_parm = bcmcli_find_named_parm(session, "owner.intf_id");
+ if (cli_parm != NULL)
+ {
+ val.u.uni.intf_id = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.intf_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.sub_term_id");
+ if (cli_parm != NULL)
+ {
+ val.u.uni.sub_term_id = (bcmbal_sub_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.sub_term_id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "owner.idx");
+ if (cli_parm != NULL)
+ {
+ val.u.uni.idx = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.idx is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ cli_parm = bcmcli_find_named_parm(session, "owner.idx");
+ if (cli_parm != NULL)
+ {
+ val.u.virtual.idx = cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "owner.idx is not set\n");
+ return BCM_ERR_PARM;
+ }
+ break;
+ default:
+ bcmbal_apicli_print_complete(session, BCM_ERR_RANGE, "\n");
+ return BCM_ERR_RANGE;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_sched_owner val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_OWNER, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_type");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_type val;
+ val = (bcmbal_tm_sched_type) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_type, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_type, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "sched_parent.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_parent val = { };
+ cli_parm = bcmcli_find_named_parm(session, "sched_parent.sched_id");
+ if (cli_parm != NULL)
+ {
+ val.sched_id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SCHED_PARENT_ID_SCHED_ID;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_parent.priority");
+ if (cli_parm != NULL)
+ {
+ val.priority = (bcmbal_tm_priority) cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SCHED_PARENT_ID_PRIORITY;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_parent.weight");
+ if (cli_parm != NULL)
+ {
+ val.weight = (bcmbal_tm_weight) cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SCHED_PARENT_ID_WEIGHT;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_parent, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_sched_parent val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_parent, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "sched_child_type");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_sched_child_type val;
+ val = (bcmbal_tm_sched_child_type) cli_parm->value.enum_val;
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_child_type, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_child_type, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE, &val);
+ bcmcli_log(");\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "rate.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_shaping val = { };
+ cli_parm = bcmcli_find_named_parm(session, "rate.sbr");
+ if (cli_parm != NULL)
+ {
+ val.sbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_SBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate.pbr");
+ if (cli_parm != NULL)
+ {
+ val.pbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_PBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "rate.burst");
+ if (cli_parm != NULL)
+ {
+ val.burst = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_SHAPING_ID_BURST;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, rate, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_shaping val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_RATE, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, rate, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_parm_by_prefix(session, "tcont_sla.");
+ if (cli_parm != NULL)
+ {
+ bcmbal_tm_tcont_sla val = { };
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla.extra_bw_elig");
+ if (cli_parm != NULL)
+ {
+ val.extra_bw_elig = (bcmbal_extra_bw_eligibility_type) cli_parm->value.enum_val;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_TCONT_SLA_ID_EXTRA_BW_ELIG;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla.nrt_cbr");
+ if (cli_parm != NULL)
+ {
+ val.nrt_cbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_TCONT_SLA_ID_NRT_CBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla.rt_cbr");
+ if (cli_parm != NULL)
+ {
+ val.rt_cbr = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_TCONT_SLA_ID_RT_CBR;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla.rt_profile");
+ if (cli_parm != NULL)
+ {
+ val.rt_profile = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_TCONT_SLA_ID_RT_PROFILE;
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "tcont_sla.nrt_profile");
+ if (cli_parm != NULL)
+ {
+ val.nrt_profile = cli_parm->value.unumber;
+ val.presence_mask = val.presence_mask | BCMBAL_TM_TCONT_SLA_ID_NRT_PROFILE;
+ }
+
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, tcont_sla, val);
+ bcmcli_log("{\n");
+ bcmcli_log("bcmbal_tm_tcont_sla val = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA, &val);
+ bcmcli_log(";\n");
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, tcont_sla, val);\n");
+ bcmcli_log("}\n");
+ }
+
+ cli_parm = bcmcli_find_named_parm(session, "num_priorities");
+ if (cli_parm != NULL)
+ {
+ uint8_t val;
+ val = cli_parm->value.unumber;
+ BCMBAL_CFG_PROP_SET(&cfg, tm_sched, num_priorities, val);
+ bcmcli_log("BCMBAL_CFG_PROP_SET(&cfg, tm_sched, num_priorities, ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES, &val);
+ bcmcli_log(");\n");
+ }
+
+ /* call API */
+ err = bcmbal_cfg_set(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_set(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_cli_tm_sched_cfg_clear(bcmcli_session *session)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmos_errno err;
+ bcmbal_tm_sched_cfg cfg; /**< declare main API struct */
+ bcmbal_tm_sched_key key = { }; /**< declare key */
+ bcmcli_log("bcmbal_tm_sched_cfg cfg;\n");
+ bcmcli_log("bcmbal_tm_sched_key key = { };\n");
+ bcmbal_apicli_print_start(session, "bcmbal_cfg_clear");
+
+ /* build key from CLI parameters */
+ cli_parm = bcmcli_find_named_parm(session, "dir");
+ if (cli_parm != NULL)
+ {
+ key.dir = (bcmbal_tm_sched_dir) cli_parm->value.enum_val;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "dir is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.dir = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_DIR, &key.dir);
+ bcmcli_log(";\n");
+ cli_parm = bcmcli_find_named_parm(session, "id");
+ if (cli_parm != NULL)
+ {
+ key.id = (bcmbal_tm_sched_id) cli_parm->value.unumber;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "id is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ bcmcli_log("key.id = ");
+ bcmbal_apicli_log_prop_val(BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, BCMBAL_TM_SCHED_KEY_ID_ID, &key.id);
+ bcmcli_log(";\n");
+
+ /* init the API struct */
+ BCMBAL_CFG_INIT(&cfg, tm_sched, key);
+ bcmcli_log("BCMBAL_CFG_INIT(&cfg, tm_sched, key);\n");
+
+ /* call API */
+ err = bcmbal_cfg_clear(&cfg.hdr);
+ bcmcli_log("bcmbal_cfg_clear(&cfg.hdr);\n");
+ bcmbal_apicli_print_complete(session, err, NULL);
+ return err;
+}
+
+/******************************************************************************/
+static bcmos_errno bcmbal_apicli_root(bcmbal_mgt_group group_type, bcmbal_obj_msg_type msg_type, bcmcli_session *session, bcmbal_apicli_byte_pool *byte_pool)
+{
+ bcmcli_cmd_parm *cli_parm;
+ bcmbal_obj_id obj_id;
+ cli_parm = bcmcli_find_named_parm(session, "object");
+ if (cli_parm != NULL)
+ {
+ obj_id = cli_parm->value.number;
+ }
+ else
+ {
+ bcmbal_apicli_print_complete(session, BCM_ERR_PARM, "object is not set\n");
+ return BCM_ERR_PARM;
+ }
+
+ switch (obj_id)
+ {
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_access_terminal_cfg_get(session);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_access_terminal_cfg_set(session);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_access_terminal_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_FLOW:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_flow_cfg_get(session);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_flow_cfg_set(session);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_flow_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ return bcmbal_cli_flow_stat_get(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_group_cfg_get(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_group_cfg_set(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_group_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_interface_cfg_get(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_interface_cfg_set(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_interface_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ return bcmbal_cli_interface_stat_get(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_PACKET:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_packet_cfg_get(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_packet_cfg_set(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_packet_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_subscriber_terminal_cfg_get(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_subscriber_terminal_cfg_set(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_subscriber_terminal_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ return bcmbal_cli_subscriber_terminal_stat_get(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_QUEUE:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_tm_queue_cfg_get(session);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_tm_queue_cfg_set(session);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_tm_queue_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ return bcmbal_cli_tm_queue_stat_get(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ switch (group_type)
+ {
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (msg_type)
+ {
+ case BCMBAL_OBJ_MSG_TYPE_GET:
+ return bcmbal_cli_tm_sched_cfg_get(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_SET:
+ return bcmbal_cli_tm_sched_cfg_set(session, byte_pool);
+ case BCMBAL_OBJ_MSG_TYPE_CLEAR:
+ return bcmbal_cli_tm_sched_cfg_clear(session);
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+}
+
+/* Perform an API call based on CLI input */
+bcmos_errno bcmbal_apicli_call(bcmbal_mgt_group group_type, bcmbal_obj_msg_type msg_type, bcmcli_session *session)
+{
+ bcmos_errno err;
+ bcmbal_apicli_byte_pool byte_pool;
+
+ /* setup memory pool for dynamically-sized list memory allocation */
+ err = bcmbal_apicli_byte_pool_create(&byte_pool);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ /* call the root API handler */
+ err = bcmbal_apicli_root(group_type, msg_type, session, &byte_pool);
+
+ /* free all dynamically allocated memory */
+ bcmbal_apicli_byte_pool_destroy(&byte_pool);
+
+ return err;
+}
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.h b/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.h
new file mode 100644
index 0000000..dc7f1fc
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_handlers.h
@@ -0,0 +1,46 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+*/
+
+#ifndef BCMBAL_APICLI_HANDLERS_H_
+#define BCMBAL_APICLI_HANDLERS_H_
+
+#include <bcmos_system.h>
+#include <bal_api.h>
+#include <bcmcli.h>
+
+/* the maximum amount of memory that could possibly by used by all variable-sized lists within a GET request */
+#define BCMBAL_APICLI_DYNAMIC_LIST_BUFFER_SIZE (32 * 1024)
+
+/* Perform an API call based on CLI input */
+bcmos_errno bcmbal_apicli_call(
+ bcmbal_mgt_group group_type,
+ bcmbal_obj_msg_type msg_type,
+ bcmcli_session *session);
+
+#endif
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.c b/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.c
new file mode 100644
index 0000000..d9b6e43
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.c
@@ -0,0 +1,1913 @@
+#include <bcmos_system.h>
+#include <bcmcli.h>
+#include <bal_api.h>
+#include "bal_api_cli_helpers.h"
+
+/* allow possibly unused descriptors to make the code easier to generate */
+#ifdef __GNUC__
+#define BCM_DESCR __attribute__((unused))
+#else
+#define BCM_DESCR
+#endif
+
+/* Unless specified in the XML model, dynamic arrays will have this max size (in bytes, will divide by element size) */
+#define DEFAULT_DYN_ARR_MAX_SIZE 2048
+
+/* ==== Base Type Descriptors ==== */
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint8_t = { .name = "uint8", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM, .size = sizeof(uint8_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint16_t = { .name = "uint16", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM, .size = sizeof(uint16_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint32_t = { .name = "uint32", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM, .size = sizeof(uint32_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint64_t = { .name = "uint64", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM, .size = sizeof(uint64_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint8_t_hex = { .name = "uint8_hex", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX, .size = sizeof(uint8_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint16_t_hex = { .name = "uint16_hex", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX, .size = sizeof(uint16_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint32_t_hex = { .name = "uint32_hex", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX, .size = sizeof(uint32_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint64_t_hex = { .name = "uint64_hex", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX, .size = sizeof(uint64_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_int8_t = { .name = "int8", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_SNUM, .size = sizeof(int8_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_int16_t = { .name = "int16", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_SNUM, .size = sizeof(int16_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_int32_t = { .name = "int32", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_SNUM, .size = sizeof(int32_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_int64_t = { .name = "int64", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_SNUM, .size = sizeof(int64_t) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_float = { .name = "float", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_FLOAT, .size = sizeof(float) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_double = { .name = "double", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_FLOAT, .size = sizeof(double) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmos_mac_address = { .name = "mac", .descr = "MAC address", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_MAC, .size = sizeof(bcmos_mac_address) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmos_ipv4_address = { .name = "ipv4", .descr = "IPv4 address", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_IPV4, .size = sizeof(bcmos_ipv4_address) };
+
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmos_bool = { .name = "bool", .descr = "Boolean", .base_type = BCMBAL_APICLI_BASE_TYPE_ID_BOOL, .size = sizeof(bcmos_bool) };
+
+/* ==== Object Type Information ==== */
+static char *object_name[] = { "access_terminal", "flow", "group", "interface", "packet", "subscriber_terminal", "tm_queue", "tm_sched" };
+static char *object_descr[] = { "BAL Access Terminal Object", "BAL Flow", "BAL Group", "BAL interface object", "Packet that can be transmitted or received", "BAL Subscriber Terminal", "Transmit queue", "Scheduling node" };
+
+/* ==== Supporting Types ==== */
+bcmcli_enum_val bcmbal_access_terminal_cfg_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS }, { .name = "iwf_mode", .val = BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_cfg_id = { .name = "bcmbal_access_terminal_cfg_id", .descr = "Identifiers for all properties contained in the access_terminal_cfg group.", .size = sizeof(bcmbal_access_terminal_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_access_terminal_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_access_terminal_ind_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS }, { .name = "iwf_mode", .val = BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_ind_id = { .name = "bcmbal_access_terminal_ind_id", .descr = "Identifiers for all properties contained in the access_terminal_ind group.", .size = sizeof(bcmbal_access_terminal_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_access_terminal_ind_id_string_table } };
+bcmcli_enum_val bcmbal_access_terminal_key_id_string_table[] = { { .name = "access_term_id", .val = BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_key_id = { .name = "bcmbal_access_terminal_key_id", .descr = "Identifiers for all properties contained in the access_terminal_key group.", .size = sizeof(bcmbal_access_terminal_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_access_terminal_key_id_string_table } };
+bcmcli_enum_val bcmbal_action_id_string_table[] = { { .name = "none", .val = BCMBAL_ACTION_ID_NONE }, { .name = "cmds_bitmask", .val = BCMBAL_ACTION_ID_CMDS_BITMASK }, { .name = "o_vid", .val = BCMBAL_ACTION_ID_O_VID }, { .name = "o_pbits", .val = BCMBAL_ACTION_ID_O_PBITS }, { .name = "o_tpid", .val = BCMBAL_ACTION_ID_O_TPID }, { .name = "i_vid", .val = BCMBAL_ACTION_ID_I_VID }, { .name = "i_pbits", .val = BCMBAL_ACTION_ID_I_PBITS }, { .name = "i_tpid", .val = BCMBAL_ACTION_ID_I_TPID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_action_id = { .name = "bcmbal_action_id", .descr = "action ID", .size = sizeof(bcmbal_action_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_action_id_string_table } };
+bcmcli_enum_val bcmbal_action_cmd_id_string_table[] = { { .name = "none", .val = BCMBAL_ACTION_CMD_ID_NONE }, { .name = "add_outer_tag", .val = BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG }, { .name = "remove_outer_tag", .val = BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG }, { .name = "xlate_outer_tag", .val = BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG }, { .name = "xlate_two_tags", .val = BCMBAL_ACTION_CMD_ID_XLATE_TWO_TAGS }, { .name = "discard_ds_bcast", .val = BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST }, { .name = "discard_ds_unknown", .val = BCMBAL_ACTION_CMD_ID_DISCARD_DS_UNKNOWN }, { .name = "add_two_tags", .val = BCMBAL_ACTION_CMD_ID_ADD_TWO_TAGS }, { .name = "remove_two_tags", .val = BCMBAL_ACTION_CMD_ID_REMOVE_TWO_TAGS }, { .name = "remark_pbits", .val = BCMBAL_ACTION_CMD_ID_REMARK_PBITS }, { .name = "copy_pbits", .val = BCMBAL_ACTION_CMD_ID_COPY_PBITS }, { .name = "reverse_copy_pbits", .val = BCMBAL_ACTION_CMD_ID_REVERSE_COPY_PBITS }, { .name = "dscp_to_pbits", .val = BCMBAL_ACTION_CMD_ID_DSCP_TO_PBITS }, { .name = "trap_to_host", .val = BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_action_cmd_id = { .name = "bcmbal_action_cmd_id", .descr = "action_cmd_id", .size = sizeof(bcmbal_action_cmd_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_action_cmd_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_action_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_action, presence_mask), .type = &type_descr_bcmbal_action_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "cmds_bitmask", .descr = "Commands bitmask", .offset = offsetof(bcmbal_action, cmds_bitmask), .type = &type_descr_bcmbal_action_cmd_id }, { .name = "o_vid", .descr = "Outer vid", .offset = offsetof(bcmbal_action, o_vid), .type = &type_descr_uint16_t }, { .name = "o_pbits", .descr = "Outer pbits", .offset = offsetof(bcmbal_action, o_pbits), .type = &type_descr_uint8_t }, { .name = "o_tpid", .descr = "Outer tpid", .offset = offsetof(bcmbal_action, o_tpid), .type = &type_descr_uint16_t }, { .name = "i_vid", .descr = "Inner vid", .offset = offsetof(bcmbal_action, i_vid), .type = &type_descr_uint16_t }, { .name = "i_pbits", .descr = "Inner pbits", .offset = offsetof(bcmbal_action, i_pbits), .type = &type_descr_uint8_t }, { .name = "i_tpid", .descr = "Inner tpid", .offset = offsetof(bcmbal_action, i_tpid), .type = &type_descr_uint16_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_action = { .name = "bcmbal_action", .descr = "action", .size = sizeof(bcmbal_action), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_action_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_action_fields } } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_aggregation_port_id_list_u8 = { .name = "bcmbal_aggregation_port_id_list_u8", .descr = "Variable-length list of aggregation_port_id", .size = sizeof(bcmbal_aggregation_port_id_list_u8), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint16_t, .len_size = 1, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_aggregation_port_id) } } };
+bcmcli_enum_val bcmbal_classifier_id_string_table[] = { { .name = "none", .val = BCMBAL_CLASSIFIER_ID_NONE }, { .name = "o_tpid", .val = BCMBAL_CLASSIFIER_ID_O_TPID }, { .name = "o_vid", .val = BCMBAL_CLASSIFIER_ID_O_VID }, { .name = "i_tpid", .val = BCMBAL_CLASSIFIER_ID_I_TPID }, { .name = "i_vid", .val = BCMBAL_CLASSIFIER_ID_I_VID }, { .name = "o_pbits", .val = BCMBAL_CLASSIFIER_ID_O_PBITS }, { .name = "i_pbits", .val = BCMBAL_CLASSIFIER_ID_I_PBITS }, { .name = "ether_type", .val = BCMBAL_CLASSIFIER_ID_ETHER_TYPE }, { .name = "dst_mac", .val = BCMBAL_CLASSIFIER_ID_DST_MAC }, { .name = "src_mac", .val = BCMBAL_CLASSIFIER_ID_SRC_MAC }, { .name = "ip_proto", .val = BCMBAL_CLASSIFIER_ID_IP_PROTO }, { .name = "dst_ip", .val = BCMBAL_CLASSIFIER_ID_DST_IP }, { .name = "src_ip", .val = BCMBAL_CLASSIFIER_ID_SRC_IP }, { .name = "src_port", .val = BCMBAL_CLASSIFIER_ID_SRC_PORT }, { .name = "dst_port", .val = BCMBAL_CLASSIFIER_ID_DST_PORT }, { .name = "pkt_tag_type", .val = BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_classifier_id = { .name = "bcmbal_classifier_id", .descr = "classifier ID", .size = sizeof(bcmbal_classifier_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_classifier_id_string_table } };
+bcmcli_enum_val bcmbal_pkt_tag_type_string_table[] = { { .name = "none", .val = BCMBAL_PKT_TAG_TYPE_NONE }, { .name = "untagged", .val = BCMBAL_PKT_TAG_TYPE_UNTAGGED }, { .name = "single_tag", .val = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG }, { .name = "double_tag", .val = BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_pkt_tag_type = { .name = "bcmbal_pkt_tag_type", .descr = "Packet tag type", .size = sizeof(bcmbal_pkt_tag_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_pkt_tag_type_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_classifier_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_classifier, presence_mask), .type = &type_descr_bcmbal_classifier_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "o_tpid", .descr = "Outer TPID of the packet to be classified", .offset = offsetof(bcmbal_classifier, o_tpid), .type = &type_descr_uint16_t }, { .name = "o_vid", .descr = "Outer VID of the packet to be classified", .offset = offsetof(bcmbal_classifier, o_vid), .type = &type_descr_uint16_t }, { .name = "i_tpid", .descr = "Inner TPID of the packet to be classified", .offset = offsetof(bcmbal_classifier, i_tpid), .type = &type_descr_uint16_t }, { .name = "i_vid", .descr = "Inner VID of the packet to be classified", .offset = offsetof(bcmbal_classifier, i_vid), .type = &type_descr_uint16_t }, { .name = "o_pbits", .descr = "Outer PBITS of the packet to be classified", .offset = offsetof(bcmbal_classifier, o_pbits), .type = &type_descr_uint8_t }, { .name = "i_pbits", .descr = "Inner PBITS of the packet to be classified", .offset = offsetof(bcmbal_classifier, i_pbits), .type = &type_descr_uint8_t }, { .name = "ether_type", .descr = "Ethertype of the packet to be classified", .offset = offsetof(bcmbal_classifier, ether_type), .type = &type_descr_uint16_t }, { .name = "dst_mac", .descr = "Destination MAC address of the packet to be classified", .offset = offsetof(bcmbal_classifier, dst_mac), .type = &type_descr_bcmos_mac_address }, { .name = "src_mac", .descr = "Source MAC address of the packet to be classified", .offset = offsetof(bcmbal_classifier, src_mac), .type = &type_descr_bcmos_mac_address }, { .name = "ip_proto", .descr = "IP protocol of the packet to be classified", .offset = offsetof(bcmbal_classifier, ip_proto), .type = &type_descr_uint8_t }, { .name = "dst_ip", .descr = "Destination IP address of the packet to be classified", .offset = offsetof(bcmbal_classifier, dst_ip), .type = &type_descr_bcmos_ipv4_address }, { .name = "src_ip", .descr = "Source IP address of the packet to be classified", .offset = offsetof(bcmbal_classifier, src_ip), .type = &type_descr_bcmos_ipv4_address }, { .name = "src_port", .descr = "Source port of the packet to be classified", .offset = offsetof(bcmbal_classifier, src_port), .type = &type_descr_uint16_t }, { .name = "dst_port", .descr = "Destination port of the packet to be classified", .offset = offsetof(bcmbal_classifier, dst_port), .type = &type_descr_uint16_t }, { .name = "pkt_tag_type", .descr = "The tag type of the ingress packets", .offset = offsetof(bcmbal_classifier, pkt_tag_type), .type = &type_descr_bcmbal_pkt_tag_type } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_classifier = { .name = "bcmbal_classifier", .descr = "classifier", .size = sizeof(bcmbal_classifier), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_classifier_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_classifier_fields } } };
+bcmcli_enum_val bcmbal_control_string_table[] = { { .name = "disable", .val = BCMBAL_CONTROL_DISABLE }, { .name = "enable", .val = BCMBAL_CONTROL_ENABLE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_control = { .name = "bcmbal_control", .descr = "Generic enable/disable enumeration", .size = sizeof(bcmbal_control), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_control_string_table } };
+bcmcli_enum_val bcmbal_dest_type_string_table[] = { { .name = "nni", .val = BCMBAL_DEST_TYPE_NNI }, { .name = "sub_term", .val = BCMBAL_DEST_TYPE_SUB_TERM }, { .name = "host", .val = BCMBAL_DEST_TYPE_HOST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_dest_type = { .name = "bcmbal_dest_type", .descr = "Destination type", .size = sizeof(bcmbal_dest_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_dest_type_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_dest_fields[] = { { .name = "type", .descr = "packet destination", .offset = offsetof(bcmbal_dest, type), .type = &type_descr_bcmbal_dest_type } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_dest_nni_fields[] = { { .name = "int_id", .descr = "Interface ID", .offset = offsetof(bcmbal_dest, u.nni.int_id) - offsetof(bcmbal_dest, u.nni.int_id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_dest_nni = { .name = "bcmbal_dest_nni", .descr = "Packet destination nni", .size = sizeof(((bcmbal_dest *)0)->u.nni), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_dest_nni_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_dest_nni_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_dest_sub_term_fields[] = { { .name = "sub_term_id", .descr = "Subscriber terminal ID", .offset = offsetof(bcmbal_dest, u.sub_term.sub_term_id) - offsetof(bcmbal_dest, u.sub_term.sub_term_id), .type = &type_descr_uint32_t }, { .name = "sub_term_uni", .descr = "Subscriber terminal UNI", .offset = offsetof(bcmbal_dest, u.sub_term.sub_term_uni) - offsetof(bcmbal_dest, u.sub_term.sub_term_id), .type = &type_descr_uint16_t }, { .name = "int_id", .descr = "Interface ID", .offset = offsetof(bcmbal_dest, u.sub_term.int_id) - offsetof(bcmbal_dest, u.sub_term.sub_term_id), .type = &type_descr_uint16_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_dest_sub_term = { .name = "bcmbal_dest_sub_term", .descr = "Packet destination subscriber terminal", .size = sizeof(((bcmbal_dest *)0)->u.sub_term), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_dest_sub_term_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_dest_sub_term_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_dest_union_fields[] = { { .name = "u.nni", .descr = "", .offset = offsetof(bcmbal_dest, u.nni), .type = &type_descr_bcmbal_dest_nni }, { .name = "u.sub_term", .descr = "", .offset = offsetof(bcmbal_dest, u.sub_term), .type = &type_descr_bcmbal_dest_sub_term }, { }, { } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_dest = { .name = "bcmbal_dest", .descr = "Packet destination", .size = sizeof(bcmbal_dest), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNION, .x = { .u = { .num_common_fields = sizeof(type_descr_bcmbal_dest_fields) / sizeof(bcmbal_apicli_field_descr), .common_fields = type_descr_bcmbal_dest_fields, .classifier_idx = 0, .union_fields = type_descr_bcmbal_dest_union_fields } } };
+bcmcli_enum_val bcmbal_ds_miss_mode_string_table[] = { { .name = "discard", .val = BCMBAL_DS_MISS_MODE_DISCARD }, { .name = "broadcast", .val = BCMBAL_DS_MISS_MODE_BROADCAST }, { .name = "vid", .val = BCMBAL_DS_MISS_MODE_VID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_ds_miss_mode = { .name = "bcmbal_ds_miss_mode", .descr = "Downstrean action for unknown packets", .size = sizeof(bcmbal_ds_miss_mode), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_ds_miss_mode_string_table } };
+bcmcli_enum_val bcmbal_extra_bw_eligibility_type_string_table[] = { { .name = "none", .val = BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NONE }, { .name = "not_assured", .val = BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NOT_ASSURED }, { .name = "best_effort", .val = BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_BEST_EFFORT }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_extra_bw_eligibility_type = { .name = "bcmbal_extra_bw_eligibility_type", .descr = "Extra BW Eligibility Type", .size = sizeof(bcmbal_extra_bw_eligibility_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_extra_bw_eligibility_type_string_table } };
+bcmcli_enum_val bcmbal_flow_cfg_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_FLOW_CFG_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_FLOW_CFG_ID_OPER_STATUS }, { .name = "access_int_id", .val = BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID }, { .name = "network_int_id", .val = BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID }, { .name = "sub_term_id", .val = BCMBAL_FLOW_CFG_ID_SUB_TERM_ID }, { .name = "sub_term_uni_idx", .val = BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX }, { .name = "svc_port_id", .val = BCMBAL_FLOW_CFG_ID_SVC_PORT_ID }, { .name = "agg_port_id", .val = BCMBAL_FLOW_CFG_ID_AGG_PORT_ID }, { .name = "resolve_mac", .val = BCMBAL_FLOW_CFG_ID_RESOLVE_MAC }, { .name = "classifier", .val = BCMBAL_FLOW_CFG_ID_CLASSIFIER }, { .name = "action", .val = BCMBAL_FLOW_CFG_ID_ACTION }, { .name = "sla", .val = BCMBAL_FLOW_CFG_ID_SLA }, { .name = "cookie", .val = BCMBAL_FLOW_CFG_ID_COOKIE }, { .name = "priority", .val = BCMBAL_FLOW_CFG_ID_PRIORITY }, { .name = "group_id", .val = BCMBAL_FLOW_CFG_ID_GROUP_ID }, { .name = "queue", .val = BCMBAL_FLOW_CFG_ID_QUEUE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_cfg_id = { .name = "bcmbal_flow_cfg_id", .descr = "Identifiers for all properties contained in the flow_cfg group.", .size = sizeof(bcmbal_flow_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_flow_cfg_id_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_id_list_u32 = { .name = "bcmbal_flow_id_list_u32", .descr = "Variable-length list of flow_id", .size = sizeof(bcmbal_flow_id_list_u32), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint32_t, .len_size = 4, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_flow_id) } } };
+bcmcli_enum_val bcmbal_flow_ind_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_FLOW_IND_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_FLOW_IND_ID_OPER_STATUS }, { .name = "access_int_id", .val = BCMBAL_FLOW_IND_ID_ACCESS_INT_ID }, { .name = "network_int_id", .val = BCMBAL_FLOW_IND_ID_NETWORK_INT_ID }, { .name = "sub_term_id", .val = BCMBAL_FLOW_IND_ID_SUB_TERM_ID }, { .name = "svc_port_id", .val = BCMBAL_FLOW_IND_ID_SVC_PORT_ID }, { .name = "agg_port_id", .val = BCMBAL_FLOW_IND_ID_AGG_PORT_ID }, { .name = "resolve_mac", .val = BCMBAL_FLOW_IND_ID_RESOLVE_MAC }, { .name = "base_tc_id", .val = BCMBAL_FLOW_IND_ID_BASE_TC_ID }, { .name = "classifier", .val = BCMBAL_FLOW_IND_ID_CLASSIFIER }, { .name = "action", .val = BCMBAL_FLOW_IND_ID_ACTION }, { .name = "sla", .val = BCMBAL_FLOW_IND_ID_SLA }, { .name = "cookie", .val = BCMBAL_FLOW_IND_ID_COOKIE }, { .name = "priority", .val = BCMBAL_FLOW_IND_ID_PRIORITY }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_ind_id = { .name = "bcmbal_flow_ind_id", .descr = "Identifiers for all properties contained in the flow_ind group.", .size = sizeof(bcmbal_flow_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_flow_ind_id_string_table } };
+bcmcli_enum_val bcmbal_flow_key_id_string_table[] = { { .name = "flow_id", .val = BCMBAL_FLOW_KEY_ID_FLOW_ID }, { .name = "flow_type", .val = BCMBAL_FLOW_KEY_ID_FLOW_TYPE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_key_id = { .name = "bcmbal_flow_key_id", .descr = "Identifiers for all properties contained in the flow_key group.", .size = sizeof(bcmbal_flow_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_flow_key_id_string_table } };
+bcmcli_enum_val bcmbal_flow_stat_id_string_table[] = { { .name = "rx_packets", .val = BCMBAL_FLOW_STAT_ID_RX_PACKETS }, { .name = "rx_bytes", .val = BCMBAL_FLOW_STAT_ID_RX_BYTES }, { .name = "tx_packets", .val = BCMBAL_FLOW_STAT_ID_TX_PACKETS }, { .name = "tx_bytes", .val = BCMBAL_FLOW_STAT_ID_TX_BYTES }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_stat_id = { .name = "bcmbal_flow_stat_id", .descr = "Identifiers for all properties contained in the flow_stat group.", .size = sizeof(bcmbal_flow_stat_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_flow_stat_id_string_table } };
+bcmcli_enum_val bcmbal_flow_type_string_table[] = { { .name = "upstream", .val = BCMBAL_FLOW_TYPE_UPSTREAM }, { .name = "downstream", .val = BCMBAL_FLOW_TYPE_DOWNSTREAM }, { .name = "broadcast", .val = BCMBAL_FLOW_TYPE_BROADCAST }, { .name = "multicast", .val = BCMBAL_FLOW_TYPE_MULTICAST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_type = { .name = "bcmbal_flow_type", .descr = "Flow Type", .size = sizeof(bcmbal_flow_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_flow_type_string_table } };
+bcmcli_enum_val bcmbal_group_cfg_id_string_table[] = { { .name = "members_cmd", .val = BCMBAL_GROUP_CFG_ID_MEMBERS_CMD }, { .name = "members", .val = BCMBAL_GROUP_CFG_ID_MEMBERS }, { .name = "cookie", .val = BCMBAL_GROUP_CFG_ID_COOKIE }, { .name = "flows", .val = BCMBAL_GROUP_CFG_ID_FLOWS }, { .name = "owner", .val = BCMBAL_GROUP_CFG_ID_OWNER }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_cfg_id = { .name = "bcmbal_group_cfg_id", .descr = "Identifiers for all properties contained in the group_cfg group.", .size = sizeof(bcmbal_group_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_group_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_group_key_id_string_table[] = { { .name = "group_id", .val = BCMBAL_GROUP_KEY_ID_GROUP_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_key_id = { .name = "bcmbal_group_key_id", .descr = "Identifiers for all properties contained in the group_key group.", .size = sizeof(bcmbal_group_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_group_key_id_string_table } };
+bcmcli_enum_val bcmbal_group_member_cmd_string_table[] = { { .name = "add_members", .val = BCMBAL_GROUP_MEMBER_CMD_ADD_MEMBERS }, { .name = "rem_members", .val = BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS }, { .name = "set_members", .val = BCMBAL_GROUP_MEMBER_CMD_SET_MEMBERS }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_member_cmd = { .name = "bcmbal_group_member_cmd", .descr = "Member operation type", .size = sizeof(bcmbal_group_member_cmd), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_group_member_cmd_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_queue_ref_fields[] = { { .name = "sched_id", .descr = "Scheduler (tm_sched) ID", .offset = offsetof(bcmbal_tm_queue_ref, sched_id), .type = &type_descr_uint32_t }, { .name = "queue_id", .descr = "Queue ID", .offset = offsetof(bcmbal_tm_queue_ref, queue_id), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_ref = { .name = "bcmbal_tm_queue_ref", .descr = "Queue Reference", .size = sizeof(bcmbal_tm_queue_ref), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_queue_ref_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_queue_ref_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_group_member_info_fields[] = { { .name = "intf_id", .descr = "Access interface id for this member", .offset = offsetof(bcmbal_group_member_info, intf_id), .type = &type_descr_uint32_t }, { .name = "svc_port_id", .descr = "The multicast \"GEM\" for this member", .offset = offsetof(bcmbal_group_member_info, svc_port_id), .type = &type_descr_uint16_t }, { .name = "action", .descr = "VLAN actions", .offset = offsetof(bcmbal_group_member_info, action), .type = &type_descr_bcmbal_action }, { .name = "queue", .descr = "Egress queue", .offset = offsetof(bcmbal_group_member_info, queue), .type = &type_descr_bcmbal_tm_queue_ref } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_member_info = { .name = "bcmbal_group_member_info", .descr = "Group Member Info", .size = sizeof(bcmbal_group_member_info), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_group_member_info_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_group_member_info_fields } } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_member_info_list_u16 = { .name = "bcmbal_group_member_info_list_u16", .descr = "Variable-length list of group_member_info", .size = sizeof(bcmbal_group_member_info_list_u16), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_bcmbal_group_member_info, .len_size = 2, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_group_member_info) } } };
+bcmcli_enum_val bcmbal_group_owner_string_table[] = { { .name = "none", .val = BCMBAL_GROUP_OWNER_NONE }, { .name = "multicast", .val = BCMBAL_GROUP_OWNER_MULTICAST }, { .name = "unicast", .val = BCMBAL_GROUP_OWNER_UNICAST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_owner = { .name = "bcmbal_group_owner", .descr = "owner of the group", .size = sizeof(bcmbal_group_owner), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_group_owner_string_table } };
+bcmcli_enum_val bcmbal_interface_cfg_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_INTERFACE_CFG_ID_OPER_STATUS }, { .name = "min_data_agg_port_id", .val = BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID }, { .name = "min_data_svc_port_id", .val = BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID }, { .name = "transceiver_type", .val = BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE }, { .name = "ds_miss_mode", .val = BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE }, { .name = "mtu", .val = BCMBAL_INTERFACE_CFG_ID_MTU }, { .name = "flow_control", .val = BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL }, { .name = "ds_tm", .val = BCMBAL_INTERFACE_CFG_ID_DS_TM }, { .name = "us_tm", .val = BCMBAL_INTERFACE_CFG_ID_US_TM }, { .name = "sub_term_id_list", .val = BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_cfg_id = { .name = "bcmbal_interface_cfg_id", .descr = "Identifiers for all properties contained in the interface_cfg group.", .size = sizeof(bcmbal_interface_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_interface_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_interface_ind_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_INTERFACE_IND_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_INTERFACE_IND_ID_OPER_STATUS }, { .name = "min_data_agg_port_id", .val = BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID }, { .name = "min_data_svc_port_id", .val = BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID }, { .name = "transceiver_type", .val = BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE }, { .name = "ds_miss_mode", .val = BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE }, { .name = "mtu", .val = BCMBAL_INTERFACE_IND_ID_MTU }, { .name = "flow_control", .val = BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL }, { .name = "ds_tm", .val = BCMBAL_INTERFACE_IND_ID_DS_TM }, { .name = "us_tm", .val = BCMBAL_INTERFACE_IND_ID_US_TM }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_ind_id = { .name = "bcmbal_interface_ind_id", .descr = "Identifiers for all properties contained in the interface_ind group.", .size = sizeof(bcmbal_interface_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_interface_ind_id_string_table } };
+bcmcli_enum_val bcmbal_interface_key_id_string_table[] = { { .name = "intf_id", .val = BCMBAL_INTERFACE_KEY_ID_INTF_ID }, { .name = "intf_type", .val = BCMBAL_INTERFACE_KEY_ID_INTF_TYPE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_key_id = { .name = "bcmbal_interface_key_id", .descr = "Identifiers for all properties contained in the interface_key group.", .size = sizeof(bcmbal_interface_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_interface_key_id_string_table } };
+bcmcli_enum_val bcmbal_interface_stat_id_string_table[] = { { .name = "rx_packets", .val = BCMBAL_INTERFACE_STAT_ID_RX_PACKETS }, { .name = "rx_bytes", .val = BCMBAL_INTERFACE_STAT_ID_RX_BYTES }, { .name = "tx_packets", .val = BCMBAL_INTERFACE_STAT_ID_TX_PACKETS }, { .name = "tx_bytes", .val = BCMBAL_INTERFACE_STAT_ID_TX_BYTES }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_stat_id = { .name = "bcmbal_interface_stat_id", .descr = "Identifiers for all properties contained in the interface_stat group.", .size = sizeof(bcmbal_interface_stat_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_interface_stat_id_string_table } };
+bcmcli_enum_val bcmbal_intf_type_string_table[] = { { .name = "nni", .val = BCMBAL_INTF_TYPE_NNI }, { .name = "pon", .val = BCMBAL_INTF_TYPE_PON }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_intf_type = { .name = "bcmbal_intf_type", .descr = "Interface type", .size = sizeof(bcmbal_intf_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_intf_type_string_table } };
+bcmcli_enum_val bcmbal_iwf_mode_string_table[] = { { .name = "direct_mapping", .val = BCMBAL_IWF_MODE_DIRECT_MAPPING }, { .name = "per_flow", .val = BCMBAL_IWF_MODE_PER_FLOW }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_iwf_mode = { .name = "bcmbal_iwf_mode", .descr = "Interworking Function Mode", .size = sizeof(bcmbal_iwf_mode), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_iwf_mode_string_table } };
+bcmcli_enum_val bcmbal_packet_cfg_id_string_table[] = { { .name = "flow_id", .val = BCMBAL_PACKET_CFG_ID_FLOW_ID }, { .name = "flow_type", .val = BCMBAL_PACKET_CFG_ID_FLOW_TYPE }, { .name = "intf_id", .val = BCMBAL_PACKET_CFG_ID_INTF_ID }, { .name = "intf_type", .val = BCMBAL_PACKET_CFG_ID_INTF_TYPE }, { .name = "svc_port", .val = BCMBAL_PACKET_CFG_ID_SVC_PORT }, { .name = "flow_cookie", .val = BCMBAL_PACKET_CFG_ID_FLOW_COOKIE }, { .name = "pkt", .val = BCMBAL_PACKET_CFG_ID_PKT }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_cfg_id = { .name = "bcmbal_packet_cfg_id", .descr = "Identifiers for all properties contained in the packet_cfg group.", .size = sizeof(bcmbal_packet_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_packet_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_packet_ind_id_string_table[] = { { .name = "flow_id", .val = BCMBAL_PACKET_IND_ID_FLOW_ID }, { .name = "flow_type", .val = BCMBAL_PACKET_IND_ID_FLOW_TYPE }, { .name = "intf_id", .val = BCMBAL_PACKET_IND_ID_INTF_ID }, { .name = "intf_type", .val = BCMBAL_PACKET_IND_ID_INTF_TYPE }, { .name = "svc_port", .val = BCMBAL_PACKET_IND_ID_SVC_PORT }, { .name = "flow_cookie", .val = BCMBAL_PACKET_IND_ID_FLOW_COOKIE }, { .name = "pkt", .val = BCMBAL_PACKET_IND_ID_PKT }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_ind_id = { .name = "bcmbal_packet_ind_id", .descr = "Identifiers for all properties contained in the packet_ind group.", .size = sizeof(bcmbal_packet_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_packet_ind_id_string_table } };
+bcmcli_enum_val bcmbal_packet_key_id_string_table[] = { { .name = "reserved", .val = BCMBAL_PACKET_KEY_ID_RESERVED }, { .name = "packet_send_dest", .val = BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_key_id = { .name = "bcmbal_packet_key_id", .descr = "Identifiers for all properties contained in the packet_key group.", .size = sizeof(bcmbal_packet_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_packet_key_id_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint8_t_arr_10 = { .name = "uint8_t[10]", .descr = "Array of 10 elements of type uint8_t", .size = sizeof(uint8_t[10]), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED, .x = { .arr_fixed = { .elem_type = &type_descr_uint8_t, .size = 10 } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_password_fields[] = { { .name = "arr", .descr = "Array", .offset = offsetof(bcmbal_password, arr), .type = &type_descr_uint8_t_arr_10 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_password = { .name = "bcmbal_password", .descr = "Password", .size = sizeof(bcmbal_password), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_password_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_password_fields } } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint8_t_arr_36 = { .name = "uint8_t[36]", .descr = "Array of 36 elements of type uint8_t", .size = sizeof(uint8_t[36]), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED, .x = { .arr_fixed = { .elem_type = &type_descr_uint8_t, .size = 36 } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_registration_id_fields[] = { { .name = "arr", .descr = "ONU registration ID", .offset = offsetof(bcmbal_registration_id, arr), .type = &type_descr_uint8_t_arr_36 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_registration_id = { .name = "bcmbal_registration_id", .descr = "Registration id", .size = sizeof(bcmbal_registration_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_registration_id_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_registration_id_fields } } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_uint8_t_arr_4 = { .name = "uint8_t[4]", .descr = "Array of 4 elements of type uint8_t", .size = sizeof(uint8_t[4]), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED, .x = { .arr_fixed = { .elem_type = &type_descr_uint8_t, .size = 4 } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_serial_number_fields[] = { { .name = "vendor_id", .descr = "vendor id", .offset = offsetof(bcmbal_serial_number, vendor_id), .type = &type_descr_uint8_t_arr_4 }, { .name = "vendor_specific", .descr = "vendor specific", .offset = offsetof(bcmbal_serial_number, vendor_specific), .type = &type_descr_uint8_t_arr_4 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_serial_number = { .name = "bcmbal_serial_number", .descr = "Serial number", .size = sizeof(bcmbal_serial_number), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_serial_number_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_serial_number_fields } } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_service_port_id_list_u8 = { .name = "bcmbal_service_port_id_list_u8", .descr = "Variable-length list of service_port_id", .size = sizeof(bcmbal_service_port_id_list_u8), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint16_t, .len_size = 1, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_service_port_id) } } };
+bcmcli_enum_val bcmbal_sla_id_string_table[] = { { .name = "none", .val = BCMBAL_SLA_ID_NONE }, { .name = "min_rate", .val = BCMBAL_SLA_ID_MIN_RATE }, { .name = "max_rate", .val = BCMBAL_SLA_ID_MAX_RATE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_sla_id = { .name = "bcmbal_sla_id", .descr = "SLA ID", .size = sizeof(bcmbal_sla_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_sla_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_sla_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_sla, presence_mask), .type = &type_descr_bcmbal_sla_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "min_rate", .descr = "The minimal rate for this flow, in kilobits per second (optional)", .offset = offsetof(bcmbal_sla, min_rate), .type = &type_descr_uint32_t }, { .name = "max_rate", .descr = "The maximum rate for this flow, in kilobits per second (optional)", .offset = offsetof(bcmbal_sla, max_rate), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_sla = { .name = "bcmbal_sla", .descr = "SLA", .size = sizeof(bcmbal_sla), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_sla_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_sla_fields } } };
+bcmcli_enum_val bcmbal_state_string_table[] = { { .name = "up", .val = BCMBAL_STATE_UP }, { .name = "down", .val = BCMBAL_STATE_DOWN }, { .name = "testing", .val = BCMBAL_STATE_TESTING }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_state = { .name = "bcmbal_state", .descr = "Admin state values for access terminal object", .size = sizeof(bcmbal_state), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_state_string_table } };
+bcmcli_enum_val bcmbal_status_string_table[] = { { .name = "up", .val = BCMBAL_STATUS_UP }, { .name = "down", .val = BCMBAL_STATUS_DOWN }, { .name = "testing", .val = BCMBAL_STATUS_TESTING }, { .name = "not_present", .val = BCMBAL_STATUS_NOT_PRESENT }, { .name = "lower_layer_down", .val = BCMBAL_STATUS_LOWER_LAYER_DOWN }, { .name = "unknown", .val = BCMBAL_STATUS_UNKNOWN }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_status = { .name = "bcmbal_status", .descr = "Oper status values", .size = sizeof(bcmbal_status), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_status_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_sub_id_list_u16 = { .name = "bcmbal_sub_id_list_u16", .descr = "Variable-length list of sub_id", .size = sizeof(bcmbal_sub_id_list_u16), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint32_t, .len_size = 2, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_sub_id) } } };
+bcmcli_enum_val bcmbal_subscriber_terminal_cfg_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS }, { .name = "serial_number", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER }, { .name = "password", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD }, { .name = "registration_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID }, { .name = "svc_port_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID }, { .name = "mac_address", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS }, { .name = "ds_tm", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM }, { .name = "us_tm", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM }, { .name = "svc_port_id_list", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST }, { .name = "agg_port_id_list", .val = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_cfg_id = { .name = "bcmbal_subscriber_terminal_cfg_id", .descr = "Identifiers for all properties contained in the subscriber_terminal_cfg group.", .size = sizeof(bcmbal_subscriber_terminal_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_subscriber_terminal_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_subscriber_terminal_ind_id_string_table[] = { { .name = "admin_state", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE }, { .name = "oper_status", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS }, { .name = "serial_number", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER }, { .name = "password", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD }, { .name = "registration_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID }, { .name = "svc_port_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID }, { .name = "mac_address", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS }, { .name = "ds_tm", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM }, { .name = "us_tm", .val = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_ind_id = { .name = "bcmbal_subscriber_terminal_ind_id", .descr = "Identifiers for all properties contained in the subscriber_terminal_ind group.", .size = sizeof(bcmbal_subscriber_terminal_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_subscriber_terminal_ind_id_string_table } };
+bcmcli_enum_val bcmbal_subscriber_terminal_key_id_string_table[] = { { .name = "sub_term_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID }, { .name = "intf_id", .val = BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_key_id = { .name = "bcmbal_subscriber_terminal_key_id", .descr = "Identifiers for all properties contained in the subscriber_terminal_key group.", .size = sizeof(bcmbal_subscriber_terminal_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_subscriber_terminal_key_id_string_table } };
+bcmcli_enum_val bcmbal_subscriber_terminal_stat_id_string_table[] = { { .name = "rx_packets", .val = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS }, { .name = "rx_bytes", .val = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES }, { .name = "tx_packets", .val = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS }, { .name = "tx_bytes", .val = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_stat_id = { .name = "bcmbal_subscriber_terminal_stat_id", .descr = "Identifiers for all properties contained in the subscriber_terminal_stat group.", .size = sizeof(bcmbal_subscriber_terminal_stat_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_subscriber_terminal_stat_id_string_table } };
+bcmcli_enum_val bcmbal_tm_bac_type_string_table[] = { { .name = "taildrop", .val = BCMBAL_TM_BAC_TYPE_TAILDROP }, { .name = "wtaildrop", .val = BCMBAL_TM_BAC_TYPE_WTAILDROP }, { .name = "red", .val = BCMBAL_TM_BAC_TYPE_RED }, { .name = "wred", .val = BCMBAL_TM_BAC_TYPE_WRED }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_bac_type = { .name = "bcmbal_tm_bac_type", .descr = "Buffer Admission Control Type", .size = sizeof(bcmbal_tm_bac_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_bac_type_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_red_fields[] = { { .name = "min_threshold", .descr = "Min threshold in percent of max queue size", .offset = offsetof(bcmbal_tm_red, min_threshold), .type = &type_descr_uint8_t }, { .name = "max_threshold", .descr = "Max threshold in percent of max queue size", .offset = offsetof(bcmbal_tm_red, max_threshold), .type = &type_descr_uint8_t }, { .name = "max_probability", .descr = "Discard probability for occupancy between min_threshold and max_threshold", .offset = offsetof(bcmbal_tm_red, max_probability), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_red = { .name = "bcmbal_tm_red", .descr = "Random Early Discard Configuration", .size = sizeof(bcmbal_tm_red), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_red_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_red_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_bac_fields[] = { { .name = "type", .descr = "Buffer Admission Control Type", .offset = offsetof(bcmbal_tm_bac, type), .type = &type_descr_bcmbal_tm_bac_type } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_bac_taildrop_fields[] = { { .name = "max_size", .descr = "max number of packets in the queue", .offset = offsetof(bcmbal_tm_bac, u.taildrop.max_size) - offsetof(bcmbal_tm_bac, u.taildrop.max_size), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_bac_taildrop = { .name = "bcmbal_tm_bac_taildrop", .descr = "tm_bac taildrop", .size = sizeof(((bcmbal_tm_bac *)0)->u.taildrop), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_bac_taildrop_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_bac_taildrop_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_bac_red_fields[] = { { .name = "red", .descr = "Random Early Discard configuration", .offset = offsetof(bcmbal_tm_bac, u.red.red) - offsetof(bcmbal_tm_bac, u.red.red), .type = &type_descr_bcmbal_tm_red } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_bac_red = { .name = "bcmbal_tm_bac_red", .descr = "tm_bac red", .size = sizeof(((bcmbal_tm_bac *)0)->u.red), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_bac_red_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_bac_red_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_bac_wred_fields[] = { { .name = "green", .descr = "Green Random Early Discard Configuration", .offset = offsetof(bcmbal_tm_bac, u.wred.green) - offsetof(bcmbal_tm_bac, u.wred.green), .type = &type_descr_bcmbal_tm_red }, { .name = "yellow", .descr = "Yellow Random Early Discard Configuration", .offset = offsetof(bcmbal_tm_bac, u.wred.yellow) - offsetof(bcmbal_tm_bac, u.wred.green), .type = &type_descr_bcmbal_tm_red }, { .name = "red", .descr = "Red Random Early Discard Configuration", .offset = offsetof(bcmbal_tm_bac, u.wred.red) - offsetof(bcmbal_tm_bac, u.wred.green), .type = &type_descr_bcmbal_tm_red } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_bac_wred = { .name = "bcmbal_tm_bac_wred", .descr = "tm_bac wred", .size = sizeof(((bcmbal_tm_bac *)0)->u.wred), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_bac_wred_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_bac_wred_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_bac_union_fields[] = { { .name = "u.taildrop", .descr = "", .offset = offsetof(bcmbal_tm_bac, u.taildrop), .type = &type_descr_bcmbal_tm_bac_taildrop }, { }, { .name = "u.red", .descr = "", .offset = offsetof(bcmbal_tm_bac, u.red), .type = &type_descr_bcmbal_tm_bac_red }, { .name = "u.wred", .descr = "", .offset = offsetof(bcmbal_tm_bac, u.wred), .type = &type_descr_bcmbal_tm_bac_wred }, { } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_bac = { .name = "bcmbal_tm_bac", .descr = "Queue Buffer Admission Control", .size = sizeof(bcmbal_tm_bac), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNION, .x = { .u = { .num_common_fields = sizeof(type_descr_bcmbal_tm_bac_fields) / sizeof(bcmbal_apicli_field_descr), .common_fields = type_descr_bcmbal_tm_bac_fields, .classifier_idx = 0, .union_fields = type_descr_bcmbal_tm_bac_union_fields } } };
+bcmcli_enum_val bcmbal_tm_creation_mode_string_table[] = { { .name = "manual", .val = BCMBAL_TM_CREATION_MODE_MANUAL }, { .name = "auto", .val = BCMBAL_TM_CREATION_MODE_AUTO }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_creation_mode = { .name = "bcmbal_tm_creation_mode", .descr = "TM Creation Mode", .size = sizeof(bcmbal_tm_creation_mode), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_creation_mode_string_table } };
+bcmcli_enum_val bcmbal_tm_queue_cfg_id_string_table[] = { { .name = "priority", .val = BCMBAL_TM_QUEUE_CFG_ID_PRIORITY }, { .name = "weight", .val = BCMBAL_TM_QUEUE_CFG_ID_WEIGHT }, { .name = "rate", .val = BCMBAL_TM_QUEUE_CFG_ID_RATE }, { .name = "bac", .val = BCMBAL_TM_QUEUE_CFG_ID_BAC }, { .name = "creation_mode", .val = BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE }, { .name = "ref_count", .val = BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_cfg_id = { .name = "bcmbal_tm_queue_cfg_id", .descr = "Identifiers for all properties contained in the tm_queue_cfg group.", .size = sizeof(bcmbal_tm_queue_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_queue_cfg_id_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_id_list_u8 = { .name = "bcmbal_tm_queue_id_list_u8", .descr = "Variable-length list of tm_queue_id", .size = sizeof(bcmbal_tm_queue_id_list_u8), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint8_t, .len_size = 1, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_tm_queue_id) } } };
+bcmcli_enum_val bcmbal_tm_queue_ind_id_string_table[] = { { .name = "ret", .val = BCMBAL_TM_QUEUE_IND_ID_RET }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_ind_id = { .name = "bcmbal_tm_queue_ind_id", .descr = "Identifiers for all properties contained in the tm_queue_ind group.", .size = sizeof(bcmbal_tm_queue_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_queue_ind_id_string_table } };
+bcmcli_enum_val bcmbal_tm_queue_key_id_string_table[] = { { .name = "sched_id", .val = BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID }, { .name = "sched_dir", .val = BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR }, { .name = "id", .val = BCMBAL_TM_QUEUE_KEY_ID_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_key_id = { .name = "bcmbal_tm_queue_key_id", .descr = "Identifiers for all properties contained in the tm_queue_key group.", .size = sizeof(bcmbal_tm_queue_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_queue_key_id_string_table } };
+bcmcli_enum_val bcmbal_tm_queue_stat_id_string_table[] = { { .name = "packets_ok", .val = BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK }, { .name = "bytes_ok", .val = BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK }, { .name = "packets_discarded", .val = BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED }, { .name = "bytes_discarded", .val = BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_stat_id = { .name = "bcmbal_tm_queue_stat_id", .descr = "Identifiers for all properties contained in the tm_queue_stat group.", .size = sizeof(bcmbal_tm_queue_stat_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_queue_stat_id_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_cfg_id_string_table[] = { { .name = "owner", .val = BCMBAL_TM_SCHED_CFG_ID_OWNER }, { .name = "sched_type", .val = BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE }, { .name = "sched_parent", .val = BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT }, { .name = "sched_child_type", .val = BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE }, { .name = "rate", .val = BCMBAL_TM_SCHED_CFG_ID_RATE }, { .name = "tcont_sla", .val = BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA }, { .name = "creation_mode", .val = BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE }, { .name = "queues", .val = BCMBAL_TM_SCHED_CFG_ID_QUEUES }, { .name = "sub_scheds", .val = BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS }, { .name = "num_priorities", .val = BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_cfg_id = { .name = "bcmbal_tm_sched_cfg_id", .descr = "Identifiers for all properties contained in the tm_sched_cfg group.", .size = sizeof(bcmbal_tm_sched_cfg_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_cfg_id_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_child_type_string_table[] = { { .name = "queue", .val = BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE }, { .name = "sched", .val = BCMBAL_TM_SCHED_CHILD_TYPE_SCHED }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_child_type = { .name = "bcmbal_tm_sched_child_type", .descr = "Scheduling Level for the Children TM ", .size = sizeof(bcmbal_tm_sched_child_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_child_type_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_dir_string_table[] = { { .name = "us", .val = BCMBAL_TM_SCHED_DIR_US }, { .name = "ds", .val = BCMBAL_TM_SCHED_DIR_DS }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_dir = { .name = "bcmbal_tm_sched_dir", .descr = "Traffic Direction", .size = sizeof(bcmbal_tm_sched_dir), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_dir_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_id_list_u8 = { .name = "bcmbal_tm_sched_id_list_u8", .descr = "Variable-length list of tm_sched_id", .size = sizeof(bcmbal_tm_sched_id_list_u8), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint32_t, .len_size = 1, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(bcmbal_tm_sched_id) } } };
+bcmcli_enum_val bcmbal_tm_sched_ind_id_string_table[] = { { .name = "ret", .val = BCMBAL_TM_SCHED_IND_ID_RET }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_ind_id = { .name = "bcmbal_tm_sched_ind_id", .descr = "Identifiers for all properties contained in the tm_sched_ind group.", .size = sizeof(bcmbal_tm_sched_ind_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_ind_id_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_key_id_string_table[] = { { .name = "dir", .val = BCMBAL_TM_SCHED_KEY_ID_DIR }, { .name = "id", .val = BCMBAL_TM_SCHED_KEY_ID_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_key_id = { .name = "bcmbal_tm_sched_key_id", .descr = "Identifiers for all properties contained in the tm_sched_key group.", .size = sizeof(bcmbal_tm_sched_key_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_key_id_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_owner_type_string_table[] = { { .name = "undefined", .val = BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED }, { .name = "interface", .val = BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE }, { .name = "sub_term", .val = BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM }, { .name = "agg_port", .val = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT }, { .name = "uni", .val = BCMBAL_TM_SCHED_OWNER_TYPE_UNI }, { .name = "virtual", .val = BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_type = { .name = "bcmbal_tm_sched_owner_type", .descr = "TM Scheduler Owner Type", .size = sizeof(bcmbal_tm_sched_owner_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_owner_type_string_table } };
+bcmcli_enum_val bcmbal_tm_sched_owner_agg_port_id_string_table[] = { { .name = "none", .val = BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_NONE }, { .name = "intf_id", .val = BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID }, { .name = "sub_term_id", .val = BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID }, { .name = "agg_port_id", .val = BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_agg_port_id = { .name = "bcmbal_tm_sched_owner_agg_port_id", .descr = "tm_sched_owner agg_port ID", .size = sizeof(bcmbal_tm_sched_owner_agg_port_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_tm_sched_owner_agg_port_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_fields[] = { { .name = "type", .descr = "Owner type", .offset = offsetof(bcmbal_tm_sched_owner, type), .type = &type_descr_bcmbal_tm_sched_owner_type } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_interface_fields[] = { { .name = "intf_type", .descr = "Interface Type", .offset = offsetof(bcmbal_tm_sched_owner, u.interface.intf_type) - offsetof(bcmbal_tm_sched_owner, u.interface.intf_type), .type = &type_descr_bcmbal_intf_type }, { .name = "intf_id", .descr = "Interface ID", .offset = offsetof(bcmbal_tm_sched_owner, u.interface.intf_id) - offsetof(bcmbal_tm_sched_owner, u.interface.intf_type), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_interface = { .name = "bcmbal_tm_sched_owner_interface", .descr = "tm_sched_owner interface", .size = sizeof(((bcmbal_tm_sched_owner *)0)->u.interface), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_owner_interface_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_owner_interface_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_sub_term_fields[] = { { .name = "intf_id", .descr = "PON interface id", .offset = offsetof(bcmbal_tm_sched_owner, u.sub_term.intf_id) - offsetof(bcmbal_tm_sched_owner, u.sub_term.intf_id), .type = &type_descr_uint32_t }, { .name = "sub_term_id", .descr = "Subscriber terminal ID", .offset = offsetof(bcmbal_tm_sched_owner, u.sub_term.sub_term_id) - offsetof(bcmbal_tm_sched_owner, u.sub_term.intf_id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_sub_term = { .name = "bcmbal_tm_sched_owner_sub_term", .descr = "tm_sched_owner subs_term", .size = sizeof(((bcmbal_tm_sched_owner *)0)->u.sub_term), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_owner_sub_term_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_owner_sub_term_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_agg_port_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_tm_sched_owner, u.agg_port.presence_mask) - offsetof(bcmbal_tm_sched_owner, u.agg_port.presence_mask), .type = &type_descr_bcmbal_tm_sched_owner_agg_port_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "intf_id", .descr = "PON interface id", .offset = offsetof(bcmbal_tm_sched_owner, u.agg_port.intf_id) - offsetof(bcmbal_tm_sched_owner, u.agg_port.presence_mask), .type = &type_descr_uint8_t }, { .name = "sub_term_id", .descr = "Subscriber terminal id", .offset = offsetof(bcmbal_tm_sched_owner, u.agg_port.sub_term_id) - offsetof(bcmbal_tm_sched_owner, u.agg_port.presence_mask), .type = &type_descr_uint32_t }, { .name = "agg_port_id", .descr = "Aggregation port id", .offset = offsetof(bcmbal_tm_sched_owner, u.agg_port.agg_port_id) - offsetof(bcmbal_tm_sched_owner, u.agg_port.presence_mask), .type = &type_descr_uint16_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_agg_port = { .name = "bcmbal_tm_sched_owner_agg_port", .descr = "tm_sched_owner agg_port", .size = sizeof(((bcmbal_tm_sched_owner *)0)->u.agg_port), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_owner_agg_port_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_owner_agg_port_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_uni_fields[] = { { .name = "intf_id", .descr = "PON interface id", .offset = offsetof(bcmbal_tm_sched_owner, u.uni.intf_id) - offsetof(bcmbal_tm_sched_owner, u.uni.intf_id), .type = &type_descr_uint8_t }, { .name = "sub_term_id", .descr = "Subscriber terminal id", .offset = offsetof(bcmbal_tm_sched_owner, u.uni.sub_term_id) - offsetof(bcmbal_tm_sched_owner, u.uni.intf_id), .type = &type_descr_uint32_t }, { .name = "idx", .descr = "Index at subscriber terminal", .offset = offsetof(bcmbal_tm_sched_owner, u.uni.idx) - offsetof(bcmbal_tm_sched_owner, u.uni.intf_id), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_uni = { .name = "bcmbal_tm_sched_owner_uni", .descr = "tm_sched_owner uni", .size = sizeof(((bcmbal_tm_sched_owner *)0)->u.uni), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_owner_uni_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_owner_uni_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_virtual_fields[] = { { .name = "idx", .descr = "Owner index", .offset = offsetof(bcmbal_tm_sched_owner, u.virtual.idx) - offsetof(bcmbal_tm_sched_owner, u.virtual.idx), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_virtual = { .name = "bcmbal_tm_sched_owner_virtual", .descr = "tm_sched_owner virtual", .size = sizeof(((bcmbal_tm_sched_owner *)0)->u.virtual), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_owner_virtual_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_owner_virtual_fields } } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner_union_fields[] = { { }, { .name = "u.interface", .descr = "", .offset = offsetof(bcmbal_tm_sched_owner, u.interface), .type = &type_descr_bcmbal_tm_sched_owner_interface }, { .name = "u.sub_term", .descr = "", .offset = offsetof(bcmbal_tm_sched_owner, u.sub_term), .type = &type_descr_bcmbal_tm_sched_owner_sub_term }, { .name = "u.agg_port", .descr = "", .offset = offsetof(bcmbal_tm_sched_owner, u.agg_port), .type = &type_descr_bcmbal_tm_sched_owner_agg_port }, { .name = "u.uni", .descr = "", .offset = offsetof(bcmbal_tm_sched_owner, u.uni), .type = &type_descr_bcmbal_tm_sched_owner_uni }, { .name = "u.virtual", .descr = "", .offset = offsetof(bcmbal_tm_sched_owner, u.virtual), .type = &type_descr_bcmbal_tm_sched_owner_virtual }, { } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_owner = { .name = "bcmbal_tm_sched_owner", .descr = "TM Scheduler Owner", .size = sizeof(bcmbal_tm_sched_owner), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_UNION, .x = { .u = { .num_common_fields = sizeof(type_descr_bcmbal_tm_sched_owner_fields) / sizeof(bcmbal_apicli_field_descr), .common_fields = type_descr_bcmbal_tm_sched_owner_fields, .classifier_idx = 0, .union_fields = type_descr_bcmbal_tm_sched_owner_union_fields } } };
+bcmcli_enum_val bcmbal_tm_sched_parent_id_string_table[] = { { .name = "none", .val = BCMBAL_TM_SCHED_PARENT_ID_NONE }, { .name = "sched_id", .val = BCMBAL_TM_SCHED_PARENT_ID_SCHED_ID }, { .name = "priority", .val = BCMBAL_TM_SCHED_PARENT_ID_PRIORITY }, { .name = "weight", .val = BCMBAL_TM_SCHED_PARENT_ID_WEIGHT }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_parent_id = { .name = "bcmbal_tm_sched_parent_id", .descr = "tm_sched_parent ID", .size = sizeof(bcmbal_tm_sched_parent_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_tm_sched_parent_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_parent_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_tm_sched_parent, presence_mask), .type = &type_descr_bcmbal_tm_sched_parent_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "sched_id", .descr = "Parent scheduler id", .offset = offsetof(bcmbal_tm_sched_parent, sched_id), .type = &type_descr_uint32_t }, { .name = "priority", .descr = "Priority", .offset = offsetof(bcmbal_tm_sched_parent, priority), .type = &type_descr_uint8_t }, { .name = "weight", .descr = "Weight", .offset = offsetof(bcmbal_tm_sched_parent, weight), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_parent = { .name = "bcmbal_tm_sched_parent", .descr = "Scheduling Parent Connect Point", .size = sizeof(bcmbal_tm_sched_parent), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_parent_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_parent_fields } } };
+bcmcli_enum_val bcmbal_tm_sched_type_string_table[] = { { .name = "none", .val = BCMBAL_TM_SCHED_TYPE_NONE }, { .name = "wfq", .val = BCMBAL_TM_SCHED_TYPE_WFQ }, { .name = "sp", .val = BCMBAL_TM_SCHED_TYPE_SP }, { .name = "sp_wfq", .val = BCMBAL_TM_SCHED_TYPE_SP_WFQ }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_type = { .name = "bcmbal_tm_sched_type", .descr = "Scheduler Type", .size = sizeof(bcmbal_tm_sched_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_tm_sched_type_string_table } };
+bcmcli_enum_val bcmbal_tm_shaping_id_string_table[] = { { .name = "none", .val = BCMBAL_TM_SHAPING_ID_NONE }, { .name = "sbr", .val = BCMBAL_TM_SHAPING_ID_SBR }, { .name = "pbr", .val = BCMBAL_TM_SHAPING_ID_PBR }, { .name = "burst", .val = BCMBAL_TM_SHAPING_ID_BURST }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_shaping_id = { .name = "bcmbal_tm_shaping_id", .descr = "tm_shaping ID", .size = sizeof(bcmbal_tm_shaping_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_tm_shaping_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_shaping_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_tm_shaping, presence_mask), .type = &type_descr_bcmbal_tm_shaping_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "sbr", .descr = "Sustained Bit Rate (kbps)", .offset = offsetof(bcmbal_tm_shaping, sbr), .type = &type_descr_uint32_t }, { .name = "pbr", .descr = "Peak Bit Rate (kbps)", .offset = offsetof(bcmbal_tm_shaping, pbr), .type = &type_descr_uint32_t }, { .name = "burst", .descr = "Max Burst Bytes at Peak Bit Rate", .offset = offsetof(bcmbal_tm_shaping, burst), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_shaping = { .name = "bcmbal_tm_shaping", .descr = "Shaping Parameters", .size = sizeof(bcmbal_tm_shaping), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_shaping_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_shaping_fields } } };
+bcmcli_enum_val bcmbal_tm_tcont_sla_id_string_table[] = { { .name = "none", .val = BCMBAL_TM_TCONT_SLA_ID_NONE }, { .name = "extra_bw_elig", .val = BCMBAL_TM_TCONT_SLA_ID_EXTRA_BW_ELIG }, { .name = "nrt_cbr", .val = BCMBAL_TM_TCONT_SLA_ID_NRT_CBR }, { .name = "rt_cbr", .val = BCMBAL_TM_TCONT_SLA_ID_RT_CBR }, { .name = "rt_profile", .val = BCMBAL_TM_TCONT_SLA_ID_RT_PROFILE }, { .name = "nrt_profile", .val = BCMBAL_TM_TCONT_SLA_ID_NRT_PROFILE }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_tcont_sla_id = { .name = "bcmbal_tm_tcont_sla_id", .descr = "tm_tcont_sla ID", .size = sizeof(bcmbal_tm_tcont_sla_id), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, .x = { .e = bcmbal_tm_tcont_sla_id_string_table } };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_tcont_sla_fields[] = { { .name = "presence_mask", .descr = "Presence Mask", .offset = offsetof(bcmbal_tm_tcont_sla, presence_mask), .type = &type_descr_bcmbal_tm_tcont_sla_id, .flags = BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK }, { .name = "extra_bw_elig", .descr = "Extra BW eligibility type", .offset = offsetof(bcmbal_tm_tcont_sla, extra_bw_elig), .type = &type_descr_bcmbal_extra_bw_eligibility_type }, { .name = "nrt_cbr", .descr = "NRT CBR", .offset = offsetof(bcmbal_tm_tcont_sla, nrt_cbr), .type = &type_descr_uint8_t }, { .name = "rt_cbr", .descr = "RT_CBR", .offset = offsetof(bcmbal_tm_tcont_sla, rt_cbr), .type = &type_descr_uint8_t }, { .name = "rt_profile", .descr = "RT Profile", .offset = offsetof(bcmbal_tm_tcont_sla, rt_profile), .type = &type_descr_uint8_t }, { .name = "nrt_profile", .descr = "NRT Profile", .offset = offsetof(bcmbal_tm_tcont_sla, nrt_profile), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_tcont_sla = { .name = "bcmbal_tm_tcont_sla", .descr = "ITU-PON Extended SLA Parameters", .size = sizeof(bcmbal_tm_tcont_sla), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_tcont_sla_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_tcont_sla_fields } } };
+bcmcli_enum_val bcmbal_trx_type_string_table[] = { { .name = "gpon_sps_43_48", .val = BCMBAL_TRX_TYPE_GPON_SPS_43_48 }, { .name = "gpon_sps_sog_4321", .val = BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321 }, { .name = "gpon_lte_3680_m", .val = BCMBAL_TRX_TYPE_GPON_LTE_3680_M }, { .name = "gpon_source_photonics", .val = BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS }, { .name = "gpon_lte_3680_p", .val = BCMBAL_TRX_TYPE_GPON_LTE_3680_P }, { .name = "xgpon_lth_7222_pc", .val = BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC }, { .name = "xgpon_lth_7226_pc", .val = BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC }, { .name = "xgpon_lth_5302_pc", .val = BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC }, BCMCLI_ENUM_LAST };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_trx_type = { .name = "bcmbal_trx_type", .descr = "Transceiver types", .size = sizeof(bcmbal_trx_type), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ENUM, .x = { .e = bcmbal_trx_type_string_table } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_u8_list_u32 = { .name = "bcmbal_u8_list_u32", .descr = "Variable-length list of U8", .size = sizeof(bcmbal_u8_list_u32), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, .x = { .arr_dyn = { .elem_type = &type_descr_uint8_t, .len_size = 4, .max_size = DEFAULT_DYN_ARR_MAX_SIZE / sizeof(uint8_t) } } };
+
+/* ==== Object: access_terminal ==== */
+
+/* Group: access_terminal - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_key_access_term_id = { .name = "access_term_id", .descr = "Reserved (set to 0)", .access = 0, .property = BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID, .offset = offsetof(bcmbal_access_terminal_key, access_term_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR access_terminal_key_prop_array[] = { &prop_descr_access_terminal_key_access_term_id };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_access_terminal_key_fields[] = { { .name = "access_term_id", .descr = "Reserved (set to 0)", .offset = offsetof(bcmbal_access_terminal_key, access_term_id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_key = { .name = "bcmbal_access_terminal_key", .descr = "key", .size = sizeof(bcmbal_access_terminal_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_access_terminal_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_access_terminal_key_fields } } };
+
+/* Group: access_terminal - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_cfg_admin_state = { .name = "admin_state", .descr = "Administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE, .offset = offsetof(bcmbal_access_terminal_cfg_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_cfg_oper_status = { .name = "oper_status", .descr = "Operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS, .offset = offsetof(bcmbal_access_terminal_cfg_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_cfg_iwf_mode = { .name = "iwf_mode", .descr = "The interworking mode", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE, .offset = offsetof(bcmbal_access_terminal_cfg_data, iwf_mode), .type = &type_descr_bcmbal_iwf_mode };
+static bcmbal_apicli_prop_descr * BCM_DESCR access_terminal_cfg_prop_array[] = { &prop_descr_access_terminal_cfg_admin_state, &prop_descr_access_terminal_cfg_oper_status, &prop_descr_access_terminal_cfg_iwf_mode };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_access_terminal_cfg_data_fields[] = { { .name = "admin_state", .descr = "Administrative state", .offset = offsetof(bcmbal_access_terminal_cfg_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Operational status", .offset = offsetof(bcmbal_access_terminal_cfg_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "iwf_mode", .descr = "The interworking mode", .offset = offsetof(bcmbal_access_terminal_cfg_data, iwf_mode), .type = &type_descr_bcmbal_iwf_mode } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_cfg_data = { .name = "bcmbal_access_terminal_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_access_terminal_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_access_terminal_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_access_terminal_cfg_data_fields } } };
+
+/* Group: access_terminal - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_ind_admin_state = { .name = "admin_state", .descr = "Current administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE, .offset = offsetof(bcmbal_access_terminal_ind_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_ind_oper_status = { .name = "oper_status", .descr = "Current operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS, .offset = offsetof(bcmbal_access_terminal_ind_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_access_terminal_ind_iwf_mode = { .name = "iwf_mode", .descr = "The interworking mode", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE, .offset = offsetof(bcmbal_access_terminal_ind_data, iwf_mode), .type = &type_descr_bcmbal_iwf_mode };
+static bcmbal_apicli_prop_descr * BCM_DESCR access_terminal_ind_prop_array[] = { &prop_descr_access_terminal_ind_admin_state, &prop_descr_access_terminal_ind_oper_status, &prop_descr_access_terminal_ind_iwf_mode };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_access_terminal_ind_data_fields[] = { { .name = "admin_state", .descr = "Current administrative state", .offset = offsetof(bcmbal_access_terminal_ind_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Current operational status", .offset = offsetof(bcmbal_access_terminal_ind_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "iwf_mode", .descr = "The interworking mode", .offset = offsetof(bcmbal_access_terminal_ind_data, iwf_mode), .type = &type_descr_bcmbal_iwf_mode } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_access_terminal_ind_data = { .name = "bcmbal_access_terminal_ind_data", .descr = "Access Terminal Indication", .size = sizeof(bcmbal_access_terminal_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_access_terminal_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_access_terminal_ind_data_fields } } };
+
+/* ==== Object: flow ==== */
+
+/* Group: flow - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_admin_state = { .name = "admin_state", .descr = "Administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_ADMIN_STATE, .offset = offsetof(bcmbal_flow_cfg_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_oper_status = { .name = "oper_status", .descr = "Operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_FLOW_CFG_ID_OPER_STATUS, .offset = offsetof(bcmbal_flow_cfg_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_access_int_id = { .name = "access_int_id", .descr = "The ID of the subscriber side interface; i.e. PON", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID, .offset = offsetof(bcmbal_flow_cfg_data, access_int_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_network_int_id = { .name = "network_int_id", .descr = "The ID of the network side interface; i.e. NNI", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID, .offset = offsetof(bcmbal_flow_cfg_data, network_int_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_sub_term_id = { .name = "sub_term_id", .descr = "The ID of the subsccriber terminal device", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_SUB_TERM_ID, .offset = offsetof(bcmbal_flow_cfg_data, sub_term_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_sub_term_uni_idx = { .name = "sub_term_uni_idx", .descr = "The index of the subsccriber terminal uni port the flow is related to", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX, .offset = offsetof(bcmbal_flow_cfg_data, sub_term_uni_idx), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_svc_port_id = { .name = "svc_port_id", .descr = "The ID of the service port (for GPON/XGPON - GEM ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_SVC_PORT_ID, .offset = offsetof(bcmbal_flow_cfg_data, svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_agg_port_id = { .name = "agg_port_id", .descr = "The ID of the aggregate port (for GPON/XGPON - ALLOC ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_AGG_PORT_ID, .offset = offsetof(bcmbal_flow_cfg_data, agg_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_resolve_mac = { .name = "resolve_mac", .descr = "A flag indicating if the MAC address table should be used in DS GEM resolution", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_RESOLVE_MAC, .offset = offsetof(bcmbal_flow_cfg_data, resolve_mac), .type = &type_descr_bcmos_bool };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_classifier = { .name = "classifier", .descr = "The classifier for this flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_CLASSIFIER, .offset = offsetof(bcmbal_flow_cfg_data, classifier), .type = &type_descr_bcmbal_classifier };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_action = { .name = "action", .descr = "The action associated with the flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_ACTION, .offset = offsetof(bcmbal_flow_cfg_data, action), .type = &type_descr_bcmbal_action };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_sla = { .name = "sla", .descr = "SLA parameters for this flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_SLA, .offset = offsetof(bcmbal_flow_cfg_data, sla), .type = &type_descr_bcmbal_sla };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_cookie = { .name = "cookie", .descr = "Application cookie", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_COOKIE, .offset = offsetof(bcmbal_flow_cfg_data, cookie), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_priority = { .name = "priority", .descr = "Priority", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_PRIORITY, .offset = offsetof(bcmbal_flow_cfg_data, priority), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_group_id = { .name = "group_id", .descr = "RW - The multicast group associated with this flow, valid for type MULTICAST only", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_GROUP_ID, .offset = offsetof(bcmbal_flow_cfg_data, group_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_cfg_queue = { .name = "queue", .descr = "Egress queue", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_CFG_ID_QUEUE, .offset = offsetof(bcmbal_flow_cfg_data, queue), .type = &type_descr_bcmbal_tm_queue_ref };
+static bcmbal_apicli_prop_descr * BCM_DESCR flow_cfg_prop_array[] = { &prop_descr_flow_cfg_admin_state, &prop_descr_flow_cfg_oper_status, &prop_descr_flow_cfg_access_int_id, &prop_descr_flow_cfg_network_int_id, &prop_descr_flow_cfg_sub_term_id, &prop_descr_flow_cfg_sub_term_uni_idx, &prop_descr_flow_cfg_svc_port_id, &prop_descr_flow_cfg_agg_port_id, &prop_descr_flow_cfg_resolve_mac, &prop_descr_flow_cfg_classifier, &prop_descr_flow_cfg_action, &prop_descr_flow_cfg_sla, &prop_descr_flow_cfg_cookie, &prop_descr_flow_cfg_priority, &prop_descr_flow_cfg_group_id, &prop_descr_flow_cfg_queue };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_flow_cfg_data_fields[] = { { .name = "admin_state", .descr = "Administrative state", .offset = offsetof(bcmbal_flow_cfg_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Operational status", .offset = offsetof(bcmbal_flow_cfg_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "access_int_id", .descr = "The ID of the subscriber side interface; i.e. PON", .offset = offsetof(bcmbal_flow_cfg_data, access_int_id), .type = &type_descr_uint32_t }, { .name = "network_int_id", .descr = "The ID of the network side interface; i.e. NNI", .offset = offsetof(bcmbal_flow_cfg_data, network_int_id), .type = &type_descr_uint32_t }, { .name = "sub_term_id", .descr = "The ID of the subsccriber terminal device", .offset = offsetof(bcmbal_flow_cfg_data, sub_term_id), .type = &type_descr_uint32_t }, { .name = "sub_term_uni_idx", .descr = "The index of the subsccriber terminal uni port the flow is related to", .offset = offsetof(bcmbal_flow_cfg_data, sub_term_uni_idx), .type = &type_descr_uint8_t }, { .name = "svc_port_id", .descr = "The ID of the service port (for GPON/XGPON - GEM ID)", .offset = offsetof(bcmbal_flow_cfg_data, svc_port_id), .type = &type_descr_uint16_t }, { .name = "agg_port_id", .descr = "The ID of the aggregate port (for GPON/XGPON - ALLOC ID)", .offset = offsetof(bcmbal_flow_cfg_data, agg_port_id), .type = &type_descr_uint16_t }, { .name = "resolve_mac", .descr = "A flag indicating if the MAC address table should be used in DS GEM resolution", .offset = offsetof(bcmbal_flow_cfg_data, resolve_mac), .type = &type_descr_bcmos_bool }, { .name = "classifier", .descr = "The classifier for this flow", .offset = offsetof(bcmbal_flow_cfg_data, classifier), .type = &type_descr_bcmbal_classifier }, { .name = "action", .descr = "The action associated with the flow", .offset = offsetof(bcmbal_flow_cfg_data, action), .type = &type_descr_bcmbal_action }, { .name = "sla", .descr = "SLA parameters for this flow", .offset = offsetof(bcmbal_flow_cfg_data, sla), .type = &type_descr_bcmbal_sla }, { .name = "cookie", .descr = "Application cookie", .offset = offsetof(bcmbal_flow_cfg_data, cookie), .type = &type_descr_uint64_t }, { .name = "priority", .descr = "Priority", .offset = offsetof(bcmbal_flow_cfg_data, priority), .type = &type_descr_uint16_t }, { .name = "group_id", .descr = "RW - The multicast group associated with this flow, valid for type MULTICAST only", .offset = offsetof(bcmbal_flow_cfg_data, group_id), .type = &type_descr_uint32_t }, { .name = "queue", .descr = "Egress queue", .offset = offsetof(bcmbal_flow_cfg_data, queue), .type = &type_descr_bcmbal_tm_queue_ref } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_cfg_data = { .name = "bcmbal_flow_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_flow_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_flow_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_flow_cfg_data_fields } } };
+
+/* Group: flow - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_key_flow_id = { .name = "flow_id", .descr = "The ID of the flow object instance being referenced", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_KEY_ID_FLOW_ID, .offset = offsetof(bcmbal_flow_key, flow_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_key_flow_type = { .name = "flow_type", .descr = "The type of the flow, Upstream, Downstream, Broadcast or Multicast", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_KEY_ID_FLOW_TYPE, .offset = offsetof(bcmbal_flow_key, flow_type), .type = &type_descr_bcmbal_flow_type };
+static bcmbal_apicli_prop_descr * BCM_DESCR flow_key_prop_array[] = { &prop_descr_flow_key_flow_id, &prop_descr_flow_key_flow_type };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_flow_key_fields[] = { { .name = "flow_id", .descr = "The ID of the flow object instance being referenced", .offset = offsetof(bcmbal_flow_key, flow_id), .type = &type_descr_uint32_t }, { .name = "flow_type", .descr = "The type of the flow, Upstream, Downstream, Broadcast or Multicast", .offset = offsetof(bcmbal_flow_key, flow_type), .type = &type_descr_bcmbal_flow_type } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_key = { .name = "bcmbal_flow_key", .descr = "key", .size = sizeof(bcmbal_flow_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_flow_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_flow_key_fields } } };
+
+/* Group: flow - stat */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_stat_rx_packets = { .name = "rx_packets", .descr = "Received packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_STAT_ID_RX_PACKETS, .offset = offsetof(bcmbal_flow_stat_data, rx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_stat_rx_bytes = { .name = "rx_bytes", .descr = "Received bytes", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_STAT_ID_RX_BYTES, .offset = offsetof(bcmbal_flow_stat_data, rx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_stat_tx_packets = { .name = "tx_packets", .descr = "Transmitted packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_STAT_ID_TX_PACKETS, .offset = offsetof(bcmbal_flow_stat_data, tx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_stat_tx_bytes = { .name = "tx_bytes", .descr = "Transmitted bytes", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_STAT_ID_TX_BYTES, .offset = offsetof(bcmbal_flow_stat_data, tx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR flow_stat_prop_array[] = { &prop_descr_flow_stat_rx_packets, &prop_descr_flow_stat_rx_bytes, &prop_descr_flow_stat_tx_packets, &prop_descr_flow_stat_tx_bytes };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_flow_stat_data_fields[] = { { .name = "rx_packets", .descr = "Received packets", .offset = offsetof(bcmbal_flow_stat_data, rx_packets), .type = &type_descr_uint64_t }, { .name = "rx_bytes", .descr = "Received bytes", .offset = offsetof(bcmbal_flow_stat_data, rx_bytes), .type = &type_descr_uint64_t }, { .name = "tx_packets", .descr = "Transmitted packets", .offset = offsetof(bcmbal_flow_stat_data, tx_packets), .type = &type_descr_uint64_t }, { .name = "tx_bytes", .descr = "Transmitted bytes", .offset = offsetof(bcmbal_flow_stat_data, tx_bytes), .type = &type_descr_uint64_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_stat_data = { .name = "bcmbal_flow_stat_data", .descr = "stat", .size = sizeof(bcmbal_flow_stat_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_flow_stat_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_flow_stat_data_fields } } };
+
+/* Group: flow - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_admin_state = { .name = "admin_state", .descr = "Administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_ADMIN_STATE, .offset = offsetof(bcmbal_flow_ind_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_oper_status = { .name = "oper_status", .descr = "Operational Status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_OPER_STATUS, .offset = offsetof(bcmbal_flow_ind_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_access_int_id = { .name = "access_int_id", .descr = "The ID of the subscriber side interface; i.e. PON", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_ACCESS_INT_ID, .offset = offsetof(bcmbal_flow_ind_data, access_int_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_network_int_id = { .name = "network_int_id", .descr = "The ID of the network side interface; i.e. NNI", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_NETWORK_INT_ID, .offset = offsetof(bcmbal_flow_ind_data, network_int_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_sub_term_id = { .name = "sub_term_id", .descr = "The ID of the subsccriber terminal device", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_SUB_TERM_ID, .offset = offsetof(bcmbal_flow_ind_data, sub_term_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_svc_port_id = { .name = "svc_port_id", .descr = "The ID of the service port (for GPON/XGPON - GEM ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_SVC_PORT_ID, .offset = offsetof(bcmbal_flow_ind_data, svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_agg_port_id = { .name = "agg_port_id", .descr = "The ID of the aggregate port (for GPON/XGPON - ALLOC ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_AGG_PORT_ID, .offset = offsetof(bcmbal_flow_ind_data, agg_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_resolve_mac = { .name = "resolve_mac", .descr = "A flag indicating if the MAC address table should be used in DS GEM resolution", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_RESOLVE_MAC, .offset = offsetof(bcmbal_flow_ind_data, resolve_mac), .type = &type_descr_bcmos_bool };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_base_tc_id = { .name = "base_tc_id", .descr = "The base index of the TC object(s) to be used for this flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_BASE_TC_ID, .offset = offsetof(bcmbal_flow_ind_data, base_tc_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_classifier = { .name = "classifier", .descr = "The classifier for this flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_CLASSIFIER, .offset = offsetof(bcmbal_flow_ind_data, classifier), .type = &type_descr_bcmbal_classifier };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_action = { .name = "action", .descr = "The action associated with the flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_ACTION, .offset = offsetof(bcmbal_flow_ind_data, action), .type = &type_descr_bcmbal_action };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_sla = { .name = "sla", .descr = "SLA parameters for this flow", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_SLA, .offset = offsetof(bcmbal_flow_ind_data, sla), .type = &type_descr_bcmbal_sla };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_cookie = { .name = "cookie", .descr = "Application cookie", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_COOKIE, .offset = offsetof(bcmbal_flow_ind_data, cookie), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_flow_ind_priority = { .name = "priority", .descr = "Priority", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_FLOW_IND_ID_PRIORITY, .offset = offsetof(bcmbal_flow_ind_data, priority), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR flow_ind_prop_array[] = { &prop_descr_flow_ind_admin_state, &prop_descr_flow_ind_oper_status, &prop_descr_flow_ind_access_int_id, &prop_descr_flow_ind_network_int_id, &prop_descr_flow_ind_sub_term_id, &prop_descr_flow_ind_svc_port_id, &prop_descr_flow_ind_agg_port_id, &prop_descr_flow_ind_resolve_mac, &prop_descr_flow_ind_base_tc_id, &prop_descr_flow_ind_classifier, &prop_descr_flow_ind_action, &prop_descr_flow_ind_sla, &prop_descr_flow_ind_cookie, &prop_descr_flow_ind_priority };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_flow_ind_data_fields[] = { { .name = "admin_state", .descr = "Administrative state", .offset = offsetof(bcmbal_flow_ind_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Operational Status", .offset = offsetof(bcmbal_flow_ind_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "access_int_id", .descr = "The ID of the subscriber side interface; i.e. PON", .offset = offsetof(bcmbal_flow_ind_data, access_int_id), .type = &type_descr_uint16_t }, { .name = "network_int_id", .descr = "The ID of the network side interface; i.e. NNI", .offset = offsetof(bcmbal_flow_ind_data, network_int_id), .type = &type_descr_uint16_t }, { .name = "sub_term_id", .descr = "The ID of the subsccriber terminal device", .offset = offsetof(bcmbal_flow_ind_data, sub_term_id), .type = &type_descr_uint32_t }, { .name = "svc_port_id", .descr = "The ID of the service port (for GPON/XGPON - GEM ID)", .offset = offsetof(bcmbal_flow_ind_data, svc_port_id), .type = &type_descr_uint16_t }, { .name = "agg_port_id", .descr = "The ID of the aggregate port (for GPON/XGPON - ALLOC ID)", .offset = offsetof(bcmbal_flow_ind_data, agg_port_id), .type = &type_descr_uint16_t }, { .name = "resolve_mac", .descr = "A flag indicating if the MAC address table should be used in DS GEM resolution", .offset = offsetof(bcmbal_flow_ind_data, resolve_mac), .type = &type_descr_bcmos_bool }, { .name = "base_tc_id", .descr = "The base index of the TC object(s) to be used for this flow", .offset = offsetof(bcmbal_flow_ind_data, base_tc_id), .type = &type_descr_uint16_t }, { .name = "classifier", .descr = "The classifier for this flow", .offset = offsetof(bcmbal_flow_ind_data, classifier), .type = &type_descr_bcmbal_classifier }, { .name = "action", .descr = "The action associated with the flow", .offset = offsetof(bcmbal_flow_ind_data, action), .type = &type_descr_bcmbal_action }, { .name = "sla", .descr = "SLA parameters for this flow", .offset = offsetof(bcmbal_flow_ind_data, sla), .type = &type_descr_bcmbal_sla }, { .name = "cookie", .descr = "Application cookie", .offset = offsetof(bcmbal_flow_ind_data, cookie), .type = &type_descr_uint32_t }, { .name = "priority", .descr = "Priority", .offset = offsetof(bcmbal_flow_ind_data, priority), .type = &type_descr_uint16_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_flow_ind_data = { .name = "bcmbal_flow_ind_data", .descr = "Flow Indication", .size = sizeof(bcmbal_flow_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_flow_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_flow_ind_data_fields } } };
+
+/* ==== Object: group ==== */
+
+/* Group: group - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_cfg_members_cmd = { .name = "members_cmd", .descr = "Membership operation commands", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_GROUP_CFG_ID_MEMBERS_CMD, .offset = offsetof(bcmbal_group_cfg_data, members_cmd), .type = &type_descr_bcmbal_group_member_cmd };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_cfg_members = { .name = "members", .descr = "The list of members associated with this group", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_GROUP_CFG_ID_MEMBERS, .offset = offsetof(bcmbal_group_cfg_data, members), .type = &type_descr_bcmbal_group_member_info_list_u16 };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_cfg_cookie = { .name = "cookie", .descr = "Application cookie", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_GROUP_CFG_ID_COOKIE, .offset = offsetof(bcmbal_group_cfg_data, cookie), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_cfg_flows = { .name = "flows", .descr = "List of flows associated with this group", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_GROUP_CFG_ID_FLOWS, .offset = offsetof(bcmbal_group_cfg_data, flows), .type = &type_descr_bcmbal_flow_id_list_u32 };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_cfg_owner = { .name = "owner", .descr = "Owner of the group", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_GROUP_CFG_ID_OWNER, .offset = offsetof(bcmbal_group_cfg_data, owner), .type = &type_descr_bcmbal_group_owner };
+static bcmbal_apicli_prop_descr * BCM_DESCR group_cfg_prop_array[] = { &prop_descr_group_cfg_members_cmd, &prop_descr_group_cfg_members, &prop_descr_group_cfg_cookie, &prop_descr_group_cfg_flows, &prop_descr_group_cfg_owner };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_group_cfg_data_fields[] = { { .name = "members_cmd", .descr = "Membership operation commands", .offset = offsetof(bcmbal_group_cfg_data, members_cmd), .type = &type_descr_bcmbal_group_member_cmd }, { .name = "members", .descr = "The list of members associated with this group", .offset = offsetof(bcmbal_group_cfg_data, members), .type = &type_descr_bcmbal_group_member_info_list_u16 }, { .name = "cookie", .descr = "Application cookie", .offset = offsetof(bcmbal_group_cfg_data, cookie), .type = &type_descr_uint64_t }, { .name = "flows", .descr = "List of flows associated with this group", .offset = offsetof(bcmbal_group_cfg_data, flows), .type = &type_descr_bcmbal_flow_id_list_u32 }, { .name = "owner", .descr = "Owner of the group", .offset = offsetof(bcmbal_group_cfg_data, owner), .type = &type_descr_bcmbal_group_owner } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_cfg_data = { .name = "bcmbal_group_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_group_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_group_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_group_cfg_data_fields } } };
+
+/* Group: group - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_group_key_group_id = { .name = "group_id", .descr = "The ID of the group object instance being referenced", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_GROUP_KEY_ID_GROUP_ID, .offset = offsetof(bcmbal_group_key, group_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR group_key_prop_array[] = { &prop_descr_group_key_group_id };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_group_key_fields[] = { { .name = "group_id", .descr = "The ID of the group object instance being referenced", .offset = offsetof(bcmbal_group_key, group_id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_group_key = { .name = "bcmbal_group_key", .descr = "key", .size = sizeof(bcmbal_group_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_group_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_group_key_fields } } };
+
+/* ==== Object: interface ==== */
+
+/* Group: interface - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_key_intf_id = { .name = "intf_id", .descr = "intf_id", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_KEY_ID_INTF_ID, .offset = offsetof(bcmbal_interface_key, intf_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_key_intf_type = { .name = "intf_type", .descr = "intf_type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_KEY_ID_INTF_TYPE, .offset = offsetof(bcmbal_interface_key, intf_type), .type = &type_descr_bcmbal_intf_type };
+static bcmbal_apicli_prop_descr * BCM_DESCR interface_key_prop_array[] = { &prop_descr_interface_key_intf_id, &prop_descr_interface_key_intf_type };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_interface_key_fields[] = { { .name = "intf_id", .descr = "intf_id", .offset = offsetof(bcmbal_interface_key, intf_id), .type = &type_descr_uint32_t }, { .name = "intf_type", .descr = "intf_type", .offset = offsetof(bcmbal_interface_key, intf_type), .type = &type_descr_bcmbal_intf_type } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_key = { .name = "bcmbal_interface_key", .descr = "key", .size = sizeof(bcmbal_interface_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_interface_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_interface_key_fields } } };
+
+/* Group: interface - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_admin_state = { .name = "admin_state", .descr = "Administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE, .offset = offsetof(bcmbal_interface_cfg_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_oper_status = { .name = "oper_status", .descr = "Operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_INTERFACE_CFG_ID_OPER_STATUS, .offset = offsetof(bcmbal_interface_cfg_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_min_data_agg_port_id = { .name = "min_data_agg_port_id", .descr = "The minimum agg_port_id that is allowed in the system", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID, .offset = offsetof(bcmbal_interface_cfg_data, min_data_agg_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_min_data_svc_port_id = { .name = "min_data_svc_port_id", .descr = "The minimum svc_port_id that is allowed in the system", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID, .offset = offsetof(bcmbal_interface_cfg_data, min_data_svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_transceiver_type = { .name = "transceiver_type", .descr = "The transceiver type used on an interface", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE, .offset = offsetof(bcmbal_interface_cfg_data, transceiver_type), .type = &type_descr_bcmbal_trx_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_ds_miss_mode = { .name = "ds_miss_mode", .descr = "Defines the action to take for unknown downstream packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE, .offset = offsetof(bcmbal_interface_cfg_data, ds_miss_mode), .type = &type_descr_bcmbal_ds_miss_mode };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_mtu = { .name = "mtu", .descr = "The MTU for an interface", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_MTU, .offset = offsetof(bcmbal_interface_cfg_data, mtu), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_flow_control = { .name = "flow_control", .descr = "Flow control enable or disable", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL, .offset = offsetof(bcmbal_interface_cfg_data, flow_control), .type = &type_descr_bcmbal_control };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_ds_tm = { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_DS_TM, .offset = offsetof(bcmbal_interface_cfg_data, ds_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_us_tm = { .name = "us_tm", .descr = "Upstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_CFG_ID_US_TM, .offset = offsetof(bcmbal_interface_cfg_data, us_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_cfg_sub_term_id_list = { .name = "sub_term_id_list", .descr = "A list of subscriber terminal ids configured on this interface", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST, .offset = offsetof(bcmbal_interface_cfg_data, sub_term_id_list), .type = &type_descr_bcmbal_sub_id_list_u16 };
+static bcmbal_apicli_prop_descr * BCM_DESCR interface_cfg_prop_array[] = { &prop_descr_interface_cfg_admin_state, &prop_descr_interface_cfg_oper_status, &prop_descr_interface_cfg_min_data_agg_port_id, &prop_descr_interface_cfg_min_data_svc_port_id, &prop_descr_interface_cfg_transceiver_type, &prop_descr_interface_cfg_ds_miss_mode, &prop_descr_interface_cfg_mtu, &prop_descr_interface_cfg_flow_control, &prop_descr_interface_cfg_ds_tm, &prop_descr_interface_cfg_us_tm, &prop_descr_interface_cfg_sub_term_id_list };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_interface_cfg_data_fields[] = { { .name = "admin_state", .descr = "Administrative state", .offset = offsetof(bcmbal_interface_cfg_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Operational status", .offset = offsetof(bcmbal_interface_cfg_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "min_data_agg_port_id", .descr = "The minimum agg_port_id that is allowed in the system", .offset = offsetof(bcmbal_interface_cfg_data, min_data_agg_port_id), .type = &type_descr_uint16_t }, { .name = "min_data_svc_port_id", .descr = "The minimum svc_port_id that is allowed in the system", .offset = offsetof(bcmbal_interface_cfg_data, min_data_svc_port_id), .type = &type_descr_uint16_t }, { .name = "transceiver_type", .descr = "The transceiver type used on an interface", .offset = offsetof(bcmbal_interface_cfg_data, transceiver_type), .type = &type_descr_bcmbal_trx_type }, { .name = "ds_miss_mode", .descr = "Defines the action to take for unknown downstream packets", .offset = offsetof(bcmbal_interface_cfg_data, ds_miss_mode), .type = &type_descr_bcmbal_ds_miss_mode }, { .name = "mtu", .descr = "The MTU for an interface", .offset = offsetof(bcmbal_interface_cfg_data, mtu), .type = &type_descr_uint16_t }, { .name = "flow_control", .descr = "Flow control enable or disable", .offset = offsetof(bcmbal_interface_cfg_data, flow_control), .type = &type_descr_bcmbal_control }, { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .offset = offsetof(bcmbal_interface_cfg_data, ds_tm), .type = &type_descr_uint32_t }, { .name = "us_tm", .descr = "Upstream scheduler and shaper", .offset = offsetof(bcmbal_interface_cfg_data, us_tm), .type = &type_descr_uint32_t }, { .name = "sub_term_id_list", .descr = "A list of subscriber terminal ids configured on this interface", .offset = offsetof(bcmbal_interface_cfg_data, sub_term_id_list), .type = &type_descr_bcmbal_sub_id_list_u16 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_cfg_data = { .name = "bcmbal_interface_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_interface_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_interface_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_interface_cfg_data_fields } } };
+
+/* Group: interface - stat */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_stat_rx_packets = { .name = "rx_packets", .descr = "Recieved packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_STAT_ID_RX_PACKETS, .offset = offsetof(bcmbal_interface_stat_data, rx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_stat_rx_bytes = { .name = "rx_bytes", .descr = "Received bytes", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_STAT_ID_RX_BYTES, .offset = offsetof(bcmbal_interface_stat_data, rx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_stat_tx_packets = { .name = "tx_packets", .descr = "Transmitted packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_STAT_ID_TX_PACKETS, .offset = offsetof(bcmbal_interface_stat_data, tx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_stat_tx_bytes = { .name = "tx_bytes", .descr = "Transmitted bytes", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_STAT_ID_TX_BYTES, .offset = offsetof(bcmbal_interface_stat_data, tx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR interface_stat_prop_array[] = { &prop_descr_interface_stat_rx_packets, &prop_descr_interface_stat_rx_bytes, &prop_descr_interface_stat_tx_packets, &prop_descr_interface_stat_tx_bytes };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_interface_stat_data_fields[] = { { .name = "rx_packets", .descr = "Recieved packets", .offset = offsetof(bcmbal_interface_stat_data, rx_packets), .type = &type_descr_uint64_t }, { .name = "rx_bytes", .descr = "Received bytes", .offset = offsetof(bcmbal_interface_stat_data, rx_bytes), .type = &type_descr_uint64_t }, { .name = "tx_packets", .descr = "Transmitted packets", .offset = offsetof(bcmbal_interface_stat_data, tx_packets), .type = &type_descr_uint64_t }, { .name = "tx_bytes", .descr = "Transmitted bytes", .offset = offsetof(bcmbal_interface_stat_data, tx_bytes), .type = &type_descr_uint64_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_stat_data = { .name = "bcmbal_interface_stat_data", .descr = "stat", .size = sizeof(bcmbal_interface_stat_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_interface_stat_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_interface_stat_data_fields } } };
+
+/* Group: interface - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_admin_state = { .name = "admin_state", .descr = "Current administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_ADMIN_STATE, .offset = offsetof(bcmbal_interface_ind_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_oper_status = { .name = "oper_status", .descr = "Current operational state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_OPER_STATUS, .offset = offsetof(bcmbal_interface_ind_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_min_data_agg_port_id = { .name = "min_data_agg_port_id", .descr = "The minimum agg_port_id that is allowed in the system", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID, .offset = offsetof(bcmbal_interface_ind_data, min_data_agg_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_min_data_svc_port_id = { .name = "min_data_svc_port_id", .descr = "The minimum svc_port_id that is allowed in the system", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID, .offset = offsetof(bcmbal_interface_ind_data, min_data_svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_transceiver_type = { .name = "transceiver_type", .descr = "The transceiver type used on an interface", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE, .offset = offsetof(bcmbal_interface_ind_data, transceiver_type), .type = &type_descr_bcmbal_trx_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_ds_miss_mode = { .name = "ds_miss_mode", .descr = "Defines the action to take for DS unknown packets", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE, .offset = offsetof(bcmbal_interface_ind_data, ds_miss_mode), .type = &type_descr_bcmbal_ds_miss_mode };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_mtu = { .name = "mtu", .descr = "The MTU for an interface", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_MTU, .offset = offsetof(bcmbal_interface_ind_data, mtu), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_flow_control = { .name = "flow_control", .descr = "Flow control enable or disable", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL, .offset = offsetof(bcmbal_interface_ind_data, flow_control), .type = &type_descr_bcmbal_control };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_ds_tm = { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_DS_TM, .offset = offsetof(bcmbal_interface_ind_data, ds_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_interface_ind_us_tm = { .name = "us_tm", .descr = "Upstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_INTERFACE_IND_ID_US_TM, .offset = offsetof(bcmbal_interface_ind_data, us_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR interface_ind_prop_array[] = { &prop_descr_interface_ind_admin_state, &prop_descr_interface_ind_oper_status, &prop_descr_interface_ind_min_data_agg_port_id, &prop_descr_interface_ind_min_data_svc_port_id, &prop_descr_interface_ind_transceiver_type, &prop_descr_interface_ind_ds_miss_mode, &prop_descr_interface_ind_mtu, &prop_descr_interface_ind_flow_control, &prop_descr_interface_ind_ds_tm, &prop_descr_interface_ind_us_tm };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_interface_ind_data_fields[] = { { .name = "admin_state", .descr = "Current administrative state", .offset = offsetof(bcmbal_interface_ind_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Current operational state", .offset = offsetof(bcmbal_interface_ind_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "min_data_agg_port_id", .descr = "The minimum agg_port_id that is allowed in the system", .offset = offsetof(bcmbal_interface_ind_data, min_data_agg_port_id), .type = &type_descr_uint16_t }, { .name = "min_data_svc_port_id", .descr = "The minimum svc_port_id that is allowed in the system", .offset = offsetof(bcmbal_interface_ind_data, min_data_svc_port_id), .type = &type_descr_uint16_t }, { .name = "transceiver_type", .descr = "The transceiver type used on an interface", .offset = offsetof(bcmbal_interface_ind_data, transceiver_type), .type = &type_descr_bcmbal_trx_type }, { .name = "ds_miss_mode", .descr = "Defines the action to take for DS unknown packets", .offset = offsetof(bcmbal_interface_ind_data, ds_miss_mode), .type = &type_descr_bcmbal_ds_miss_mode }, { .name = "mtu", .descr = "The MTU for an interface", .offset = offsetof(bcmbal_interface_ind_data, mtu), .type = &type_descr_uint16_t }, { .name = "flow_control", .descr = "Flow control enable or disable", .offset = offsetof(bcmbal_interface_ind_data, flow_control), .type = &type_descr_bcmbal_control }, { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .offset = offsetof(bcmbal_interface_ind_data, ds_tm), .type = &type_descr_uint32_t }, { .name = "us_tm", .descr = "Upstream scheduler and shaper", .offset = offsetof(bcmbal_interface_ind_data, us_tm), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_interface_ind_data = { .name = "bcmbal_interface_ind_data", .descr = "Interface Indication", .size = sizeof(bcmbal_interface_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_interface_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_interface_ind_data_fields } } };
+
+/* ==== Object: packet ==== */
+
+/* Group: packet - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_flow_id = { .name = "flow_id", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_FLOW_ID, .offset = offsetof(bcmbal_packet_cfg_data, flow_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_flow_type = { .name = "flow_type", .descr = "Flow Type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_FLOW_TYPE, .offset = offsetof(bcmbal_packet_cfg_data, flow_type), .type = &type_descr_bcmbal_flow_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_intf_id = { .name = "intf_id", .descr = "Interface ID", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_INTF_ID, .offset = offsetof(bcmbal_packet_cfg_data, intf_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_intf_type = { .name = "intf_type", .descr = "Interface Type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_INTF_TYPE, .offset = offsetof(bcmbal_packet_cfg_data, intf_type), .type = &type_descr_bcmbal_intf_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_svc_port = { .name = "svc_port", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_SVC_PORT, .offset = offsetof(bcmbal_packet_cfg_data, svc_port), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_flow_cookie = { .name = "flow_cookie", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_FLOW_COOKIE, .offset = offsetof(bcmbal_packet_cfg_data, flow_cookie), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_cfg_pkt = { .name = "pkt", .descr = "Packet Data", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_CFG_ID_PKT, .offset = offsetof(bcmbal_packet_cfg_data, pkt), .type = &type_descr_bcmbal_u8_list_u32 };
+static bcmbal_apicli_prop_descr * BCM_DESCR packet_cfg_prop_array[] = { &prop_descr_packet_cfg_flow_id, &prop_descr_packet_cfg_flow_type, &prop_descr_packet_cfg_intf_id, &prop_descr_packet_cfg_intf_type, &prop_descr_packet_cfg_svc_port, &prop_descr_packet_cfg_flow_cookie, &prop_descr_packet_cfg_pkt };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_packet_cfg_data_fields[] = { { .name = "flow_id", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_cfg_data, flow_id), .type = &type_descr_uint32_t }, { .name = "flow_type", .descr = "Flow Type", .offset = offsetof(bcmbal_packet_cfg_data, flow_type), .type = &type_descr_bcmbal_flow_type }, { .name = "intf_id", .descr = "Interface ID", .offset = offsetof(bcmbal_packet_cfg_data, intf_id), .type = &type_descr_uint32_t }, { .name = "intf_type", .descr = "Interface Type", .offset = offsetof(bcmbal_packet_cfg_data, intf_type), .type = &type_descr_bcmbal_intf_type }, { .name = "svc_port", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_cfg_data, svc_port), .type = &type_descr_uint16_t }, { .name = "flow_cookie", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_cfg_data, flow_cookie), .type = &type_descr_uint64_t }, { .name = "pkt", .descr = "Packet Data", .offset = offsetof(bcmbal_packet_cfg_data, pkt), .type = &type_descr_bcmbal_u8_list_u32 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_cfg_data = { .name = "bcmbal_packet_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_packet_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_packet_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_packet_cfg_data_fields } } };
+
+/* Group: packet - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_key_reserved = { .name = "reserved", .descr = "Reserved key field", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_KEY_ID_RESERVED, .offset = offsetof(bcmbal_packet_key, reserved), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_key_packet_send_dest = { .name = "packet_send_dest", .descr = "Packet destination", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST, .offset = offsetof(bcmbal_packet_key, packet_send_dest), .type = &type_descr_bcmbal_dest };
+static bcmbal_apicli_prop_descr * BCM_DESCR packet_key_prop_array[] = { &prop_descr_packet_key_reserved, &prop_descr_packet_key_packet_send_dest };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_packet_key_fields[] = { { .name = "reserved", .descr = "Reserved key field", .offset = offsetof(bcmbal_packet_key, reserved), .type = &type_descr_uint32_t }, { .name = "packet_send_dest", .descr = "Packet destination", .offset = offsetof(bcmbal_packet_key, packet_send_dest), .type = &type_descr_bcmbal_dest } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_key = { .name = "bcmbal_packet_key", .descr = "key", .size = sizeof(bcmbal_packet_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_packet_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_packet_key_fields } } };
+
+/* Group: packet - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_flow_id = { .name = "flow_id", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_FLOW_ID, .offset = offsetof(bcmbal_packet_ind_data, flow_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_flow_type = { .name = "flow_type", .descr = "Flow Type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_FLOW_TYPE, .offset = offsetof(bcmbal_packet_ind_data, flow_type), .type = &type_descr_bcmbal_flow_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_intf_id = { .name = "intf_id", .descr = "Interface ID", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_INTF_ID, .offset = offsetof(bcmbal_packet_ind_data, intf_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_intf_type = { .name = "intf_type", .descr = "Interface Type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_INTF_TYPE, .offset = offsetof(bcmbal_packet_ind_data, intf_type), .type = &type_descr_bcmbal_intf_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_svc_port = { .name = "svc_port", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_SVC_PORT, .offset = offsetof(bcmbal_packet_ind_data, svc_port), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_flow_cookie = { .name = "flow_cookie", .descr = "N/A for sending a packet", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_FLOW_COOKIE, .offset = offsetof(bcmbal_packet_ind_data, flow_cookie), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_packet_ind_pkt = { .name = "pkt", .descr = "Packet Data", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_PACKET_IND_ID_PKT, .offset = offsetof(bcmbal_packet_ind_data, pkt), .type = &type_descr_bcmbal_u8_list_u32 };
+static bcmbal_apicli_prop_descr * BCM_DESCR packet_ind_prop_array[] = { &prop_descr_packet_ind_flow_id, &prop_descr_packet_ind_flow_type, &prop_descr_packet_ind_intf_id, &prop_descr_packet_ind_intf_type, &prop_descr_packet_ind_svc_port, &prop_descr_packet_ind_flow_cookie, &prop_descr_packet_ind_pkt };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_packet_ind_data_fields[] = { { .name = "flow_id", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_ind_data, flow_id), .type = &type_descr_uint32_t }, { .name = "flow_type", .descr = "Flow Type", .offset = offsetof(bcmbal_packet_ind_data, flow_type), .type = &type_descr_bcmbal_flow_type }, { .name = "intf_id", .descr = "Interface ID", .offset = offsetof(bcmbal_packet_ind_data, intf_id), .type = &type_descr_uint32_t }, { .name = "intf_type", .descr = "Interface Type", .offset = offsetof(bcmbal_packet_ind_data, intf_type), .type = &type_descr_bcmbal_intf_type }, { .name = "svc_port", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_ind_data, svc_port), .type = &type_descr_uint16_t }, { .name = "flow_cookie", .descr = "N/A for sending a packet", .offset = offsetof(bcmbal_packet_ind_data, flow_cookie), .type = &type_descr_uint64_t }, { .name = "pkt", .descr = "Packet Data", .offset = offsetof(bcmbal_packet_ind_data, pkt), .type = &type_descr_bcmbal_u8_list_u32 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_packet_ind_data = { .name = "bcmbal_packet_ind_data", .descr = "Packet indication", .size = sizeof(bcmbal_packet_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_packet_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_packet_ind_data_fields } } };
+
+/* ==== Object: subscriber_terminal ==== */
+
+/* Group: subscriber_terminal - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_key_sub_term_id = { .name = "sub_term_id", .descr = "sub_term_id", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID, .offset = offsetof(bcmbal_subscriber_terminal_key, sub_term_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_key_intf_id = { .name = "intf_id", .descr = "intf_id", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID, .offset = offsetof(bcmbal_subscriber_terminal_key, intf_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR subscriber_terminal_key_prop_array[] = { &prop_descr_subscriber_terminal_key_sub_term_id, &prop_descr_subscriber_terminal_key_intf_id };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_key_fields[] = { { .name = "sub_term_id", .descr = "sub_term_id", .offset = offsetof(bcmbal_subscriber_terminal_key, sub_term_id), .type = &type_descr_uint32_t }, { .name = "intf_id", .descr = "intf_id", .offset = offsetof(bcmbal_subscriber_terminal_key, intf_id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_key = { .name = "bcmbal_subscriber_terminal_key", .descr = "key", .size = sizeof(bcmbal_subscriber_terminal_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_subscriber_terminal_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_subscriber_terminal_key_fields } } };
+
+/* Group: subscriber_terminal - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_admin_state = { .name = "admin_state", .descr = "Administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_oper_status = { .name = "oper_status", .descr = "Operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_serial_number = { .name = "serial_number", .descr = "The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, serial_number), .type = &type_descr_bcmbal_serial_number };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_password = { .name = "password", .descr = "The password of a GPON subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, password), .type = &type_descr_bcmbal_password };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_registration_id = { .name = "registration_id", .descr = "ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, registration_id), .type = &type_descr_bcmbal_registration_id };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_svc_port_id = { .name = "svc_port_id", .descr = "The management service port ID (for PON, the ONU ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_mac_address = { .name = "mac_address", .descr = "The Ethernet MAC address of an EPON subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, mac_address), .type = &type_descr_bcmos_mac_address };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_ds_tm = { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, ds_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_us_tm = { .name = "us_tm", .descr = "Upstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, us_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_svc_port_id_list = { .name = "svc_port_id_list", .descr = "A list of bearer traffic svc_port_ids associated with this subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, svc_port_id_list), .type = &type_descr_bcmbal_service_port_id_list_u8 };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_cfg_agg_port_id_list = { .name = "agg_port_id_list", .descr = "A list of aggr_port_ids associated with this subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST, .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, agg_port_id_list), .type = &type_descr_bcmbal_aggregation_port_id_list_u8 };
+static bcmbal_apicli_prop_descr * BCM_DESCR subscriber_terminal_cfg_prop_array[] = { &prop_descr_subscriber_terminal_cfg_admin_state, &prop_descr_subscriber_terminal_cfg_oper_status, &prop_descr_subscriber_terminal_cfg_serial_number, &prop_descr_subscriber_terminal_cfg_password, &prop_descr_subscriber_terminal_cfg_registration_id, &prop_descr_subscriber_terminal_cfg_svc_port_id, &prop_descr_subscriber_terminal_cfg_mac_address, &prop_descr_subscriber_terminal_cfg_ds_tm, &prop_descr_subscriber_terminal_cfg_us_tm, &prop_descr_subscriber_terminal_cfg_svc_port_id_list, &prop_descr_subscriber_terminal_cfg_agg_port_id_list };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_cfg_data_fields[] = { { .name = "admin_state", .descr = "Administrative state", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Operational status", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "serial_number", .descr = "The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, serial_number), .type = &type_descr_bcmbal_serial_number }, { .name = "password", .descr = "The password of a GPON subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, password), .type = &type_descr_bcmbal_password }, { .name = "registration_id", .descr = "ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, registration_id), .type = &type_descr_bcmbal_registration_id }, { .name = "svc_port_id", .descr = "The management service port ID (for PON, the ONU ID)", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, svc_port_id), .type = &type_descr_uint16_t }, { .name = "mac_address", .descr = "The Ethernet MAC address of an EPON subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, mac_address), .type = &type_descr_bcmos_mac_address }, { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, ds_tm), .type = &type_descr_uint32_t }, { .name = "us_tm", .descr = "Upstream scheduler and shaper", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, us_tm), .type = &type_descr_uint32_t }, { .name = "svc_port_id_list", .descr = "A list of bearer traffic svc_port_ids associated with this subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, svc_port_id_list), .type = &type_descr_bcmbal_service_port_id_list_u8 }, { .name = "agg_port_id_list", .descr = "A list of aggr_port_ids associated with this subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_cfg_data, agg_port_id_list), .type = &type_descr_bcmbal_aggregation_port_id_list_u8 } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_cfg_data = { .name = "bcmbal_subscriber_terminal_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_subscriber_terminal_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_subscriber_terminal_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_subscriber_terminal_cfg_data_fields } } };
+
+/* Group: subscriber_terminal - stat */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_stat_rx_packets = { .name = "rx_packets", .descr = "Received packets on specified object", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS, .offset = offsetof(bcmbal_subscriber_terminal_stat_data, rx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_stat_rx_bytes = { .name = "rx_bytes", .descr = "Received bytes on specified object", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES, .offset = offsetof(bcmbal_subscriber_terminal_stat_data, rx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_stat_tx_packets = { .name = "tx_packets", .descr = "Transmitted packets on specified object", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS, .offset = offsetof(bcmbal_subscriber_terminal_stat_data, tx_packets), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_stat_tx_bytes = { .name = "tx_bytes", .descr = "Transmittted bytes on specified object", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES, .offset = offsetof(bcmbal_subscriber_terminal_stat_data, tx_bytes), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR subscriber_terminal_stat_prop_array[] = { &prop_descr_subscriber_terminal_stat_rx_packets, &prop_descr_subscriber_terminal_stat_rx_bytes, &prop_descr_subscriber_terminal_stat_tx_packets, &prop_descr_subscriber_terminal_stat_tx_bytes };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_stat_data_fields[] = { { .name = "rx_packets", .descr = "Received packets on specified object", .offset = offsetof(bcmbal_subscriber_terminal_stat_data, rx_packets), .type = &type_descr_uint64_t }, { .name = "rx_bytes", .descr = "Received bytes on specified object", .offset = offsetof(bcmbal_subscriber_terminal_stat_data, rx_bytes), .type = &type_descr_uint64_t }, { .name = "tx_packets", .descr = "Transmitted packets on specified object", .offset = offsetof(bcmbal_subscriber_terminal_stat_data, tx_packets), .type = &type_descr_uint64_t }, { .name = "tx_bytes", .descr = "Transmittted bytes on specified object", .offset = offsetof(bcmbal_subscriber_terminal_stat_data, tx_bytes), .type = &type_descr_uint64_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_stat_data = { .name = "bcmbal_subscriber_terminal_stat_data", .descr = "stat", .size = sizeof(bcmbal_subscriber_terminal_stat_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_subscriber_terminal_stat_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_subscriber_terminal_stat_data_fields } } };
+
+/* Group: subscriber_terminal - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_admin_state = { .name = "admin_state", .descr = "Current administrative state", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, admin_state), .type = &type_descr_bcmbal_state };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_oper_status = { .name = "oper_status", .descr = "Current operational status", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, oper_status), .type = &type_descr_bcmbal_status };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_serial_number = { .name = "serial_number", .descr = "The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, serial_number), .type = &type_descr_bcmbal_serial_number };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_password = { .name = "password", .descr = "The password of a GPON subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, password), .type = &type_descr_bcmbal_password };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_registration_id = { .name = "registration_id", .descr = "ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, registration_id), .type = &type_descr_bcmbal_registration_id };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_svc_port_id = { .name = "svc_port_id", .descr = "The service port ID (for PON, the ONU ID)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, svc_port_id), .type = &type_descr_uint16_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_mac_address = { .name = "mac_address", .descr = "The Ethernet MAC address of an epon subscriber terminal", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, mac_address), .type = &type_descr_bcmos_mac_address };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_ds_tm = { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, ds_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_subscriber_terminal_ind_us_tm = { .name = "us_tm", .descr = "Upstream scheduler and shaper", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM, .offset = offsetof(bcmbal_subscriber_terminal_ind_data, us_tm), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR subscriber_terminal_ind_prop_array[] = { &prop_descr_subscriber_terminal_ind_admin_state, &prop_descr_subscriber_terminal_ind_oper_status, &prop_descr_subscriber_terminal_ind_serial_number, &prop_descr_subscriber_terminal_ind_password, &prop_descr_subscriber_terminal_ind_registration_id, &prop_descr_subscriber_terminal_ind_svc_port_id, &prop_descr_subscriber_terminal_ind_mac_address, &prop_descr_subscriber_terminal_ind_ds_tm, &prop_descr_subscriber_terminal_ind_us_tm };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_ind_data_fields[] = { { .name = "admin_state", .descr = "Current administrative state", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, admin_state), .type = &type_descr_bcmbal_state }, { .name = "oper_status", .descr = "Current operational status", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, oper_status), .type = &type_descr_bcmbal_status }, { .name = "serial_number", .descr = "The serial number of an ITU PON (GPON/XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, serial_number), .type = &type_descr_bcmbal_serial_number }, { .name = "password", .descr = "The password of a GPON subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, password), .type = &type_descr_bcmbal_password }, { .name = "registration_id", .descr = "ONU registration ID of an ITU PON (XG-PON1/XGS-PON/NG-PON2) subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, registration_id), .type = &type_descr_bcmbal_registration_id }, { .name = "svc_port_id", .descr = "The service port ID (for PON, the ONU ID)", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, svc_port_id), .type = &type_descr_uint16_t }, { .name = "mac_address", .descr = "The Ethernet MAC address of an epon subscriber terminal", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, mac_address), .type = &type_descr_bcmos_mac_address }, { .name = "ds_tm", .descr = "Downstream scheduler and shaper", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, ds_tm), .type = &type_descr_uint32_t }, { .name = "us_tm", .descr = "Upstream scheduler and shaper", .offset = offsetof(bcmbal_subscriber_terminal_ind_data, us_tm), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_subscriber_terminal_ind_data = { .name = "bcmbal_subscriber_terminal_ind_data", .descr = "Subscriber Terminal Indication", .size = sizeof(bcmbal_subscriber_terminal_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_subscriber_terminal_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_subscriber_terminal_ind_data_fields } } };
+
+/* ==== Object: tm_queue ==== */
+
+/* Group: tm_queue - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_key_sched_id = { .name = "sched_id", .descr = "Scheduler that owns the queue", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID, .offset = offsetof(bcmbal_tm_queue_key, sched_id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_key_sched_dir = { .name = "sched_dir", .descr = "sched dir", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR, .offset = offsetof(bcmbal_tm_queue_key, sched_dir), .type = &type_descr_bcmbal_tm_sched_dir };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_key_id = { .name = "id", .descr = "Queue id", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_KEY_ID_ID, .offset = offsetof(bcmbal_tm_queue_key, id), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_queue_key_prop_array[] = { &prop_descr_tm_queue_key_sched_id, &prop_descr_tm_queue_key_sched_dir, &prop_descr_tm_queue_key_id };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_queue_key_fields[] = { { .name = "sched_id", .descr = "Scheduler that owns the queue", .offset = offsetof(bcmbal_tm_queue_key, sched_id), .type = &type_descr_uint32_t }, { .name = "sched_dir", .descr = "sched dir", .offset = offsetof(bcmbal_tm_queue_key, sched_dir), .type = &type_descr_bcmbal_tm_sched_dir }, { .name = "id", .descr = "Queue id", .offset = offsetof(bcmbal_tm_queue_key, id), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_key = { .name = "bcmbal_tm_queue_key", .descr = "key", .size = sizeof(bcmbal_tm_queue_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_queue_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_queue_key_fields } } };
+
+/* Group: tm_queue - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_priority = { .name = "priority", .descr = "Scheduling priority", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_CFG_ID_PRIORITY, .offset = offsetof(bcmbal_tm_queue_cfg_data, priority), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_weight = { .name = "weight", .descr = "Scheduling weight", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_CFG_ID_WEIGHT, .offset = offsetof(bcmbal_tm_queue_cfg_data, weight), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_rate = { .name = "rate", .descr = "Rate shaping parameters", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_CFG_ID_RATE, .offset = offsetof(bcmbal_tm_queue_cfg_data, rate), .type = &type_descr_bcmbal_tm_shaping };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_bac = { .name = "bac", .descr = "Buffer admission control", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_CFG_ID_BAC, .offset = offsetof(bcmbal_tm_queue_cfg_data, bac), .type = &type_descr_bcmbal_tm_bac };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_creation_mode = { .name = "creation_mode", .descr = "Creation mode", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE, .offset = offsetof(bcmbal_tm_queue_cfg_data, creation_mode), .type = &type_descr_bcmbal_tm_creation_mode };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_cfg_ref_count = { .name = "ref_count", .descr = "reference count (flows)", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT, .offset = offsetof(bcmbal_tm_queue_cfg_data, ref_count), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_queue_cfg_prop_array[] = { &prop_descr_tm_queue_cfg_priority, &prop_descr_tm_queue_cfg_weight, &prop_descr_tm_queue_cfg_rate, &prop_descr_tm_queue_cfg_bac, &prop_descr_tm_queue_cfg_creation_mode, &prop_descr_tm_queue_cfg_ref_count };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_queue_cfg_data_fields[] = { { .name = "priority", .descr = "Scheduling priority", .offset = offsetof(bcmbal_tm_queue_cfg_data, priority), .type = &type_descr_uint8_t }, { .name = "weight", .descr = "Scheduling weight", .offset = offsetof(bcmbal_tm_queue_cfg_data, weight), .type = &type_descr_uint8_t }, { .name = "rate", .descr = "Rate shaping parameters", .offset = offsetof(bcmbal_tm_queue_cfg_data, rate), .type = &type_descr_bcmbal_tm_shaping }, { .name = "bac", .descr = "Buffer admission control", .offset = offsetof(bcmbal_tm_queue_cfg_data, bac), .type = &type_descr_bcmbal_tm_bac }, { .name = "creation_mode", .descr = "Creation mode", .offset = offsetof(bcmbal_tm_queue_cfg_data, creation_mode), .type = &type_descr_bcmbal_tm_creation_mode }, { .name = "ref_count", .descr = "reference count (flows)", .offset = offsetof(bcmbal_tm_queue_cfg_data, ref_count), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_cfg_data = { .name = "bcmbal_tm_queue_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_tm_queue_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_queue_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_queue_cfg_data_fields } } };
+
+/* Group: tm_queue - stat */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_stat_packets_ok = { .name = "packets_ok", .descr = "Packets transmitted succewssfully", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK, .offset = offsetof(bcmbal_tm_queue_stat_data, packets_ok), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_stat_bytes_ok = { .name = "bytes_ok", .descr = "Bytes transmitted successfully", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK, .offset = offsetof(bcmbal_tm_queue_stat_data, bytes_ok), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_stat_packets_discarded = { .name = "packets_discarded", .descr = "Packets discarded", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED, .offset = offsetof(bcmbal_tm_queue_stat_data, packets_discarded), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_stat_bytes_discarded = { .name = "bytes_discarded", .descr = "Bytes discarded", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED, .offset = offsetof(bcmbal_tm_queue_stat_data, bytes_discarded), .type = &type_descr_uint64_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_queue_stat_prop_array[] = { &prop_descr_tm_queue_stat_packets_ok, &prop_descr_tm_queue_stat_bytes_ok, &prop_descr_tm_queue_stat_packets_discarded, &prop_descr_tm_queue_stat_bytes_discarded };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_queue_stat_data_fields[] = { { .name = "packets_ok", .descr = "Packets transmitted succewssfully", .offset = offsetof(bcmbal_tm_queue_stat_data, packets_ok), .type = &type_descr_uint64_t }, { .name = "bytes_ok", .descr = "Bytes transmitted successfully", .offset = offsetof(bcmbal_tm_queue_stat_data, bytes_ok), .type = &type_descr_uint64_t }, { .name = "packets_discarded", .descr = "Packets discarded", .offset = offsetof(bcmbal_tm_queue_stat_data, packets_discarded), .type = &type_descr_uint64_t }, { .name = "bytes_discarded", .descr = "Bytes discarded", .offset = offsetof(bcmbal_tm_queue_stat_data, bytes_discarded), .type = &type_descr_uint64_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_stat_data = { .name = "bcmbal_tm_queue_stat_data", .descr = "stat", .size = sizeof(bcmbal_tm_queue_stat_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_queue_stat_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_queue_stat_data_fields } } };
+
+/* Group: tm_queue - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_queue_ind_ret = { .name = "ret", .descr = "ret", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_QUEUE_IND_ID_RET, .offset = offsetof(bcmbal_tm_queue_ind_data, ret), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_queue_ind_prop_array[] = { &prop_descr_tm_queue_ind_ret };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_queue_ind_data_fields[] = { { .name = "ret", .descr = "ret", .offset = offsetof(bcmbal_tm_queue_ind_data, ret), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_queue_ind_data = { .name = "bcmbal_tm_queue_ind_data", .descr = "Tm Queue Indication", .size = sizeof(bcmbal_tm_queue_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_queue_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_queue_ind_data_fields } } };
+
+/* ==== Object: tm_sched ==== */
+
+/* Group: tm_sched - key */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_key_dir = { .name = "dir", .descr = "Traffic direction", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_KEY_ID_DIR, .offset = offsetof(bcmbal_tm_sched_key, dir), .type = &type_descr_bcmbal_tm_sched_dir };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_key_id = { .name = "id", .descr = "ID", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_KEY_ID_ID, .offset = offsetof(bcmbal_tm_sched_key, id), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_sched_key_prop_array[] = { &prop_descr_tm_sched_key_dir, &prop_descr_tm_sched_key_id };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_key_fields[] = { { .name = "dir", .descr = "Traffic direction", .offset = offsetof(bcmbal_tm_sched_key, dir), .type = &type_descr_bcmbal_tm_sched_dir }, { .name = "id", .descr = "ID", .offset = offsetof(bcmbal_tm_sched_key, id), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_key = { .name = "bcmbal_tm_sched_key", .descr = "key", .size = sizeof(bcmbal_tm_sched_key), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_key_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_key_fields } } };
+
+/* Group: tm_sched - cfg */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_owner = { .name = "owner", .descr = "owner", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_OWNER, .offset = offsetof(bcmbal_tm_sched_cfg_data, owner), .type = &type_descr_bcmbal_tm_sched_owner };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_sched_type = { .name = "sched_type", .descr = "Scheduler type", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE, .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_type), .type = &type_descr_bcmbal_tm_sched_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_sched_parent = { .name = "sched_parent", .descr = "Scheduling parameters for parent scheduler", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT, .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_parent), .type = &type_descr_bcmbal_tm_sched_parent };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_sched_child_type = { .name = "sched_child_type", .descr = "Scheduling level for children tm ", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE, .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_child_type), .type = &type_descr_bcmbal_tm_sched_child_type };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_rate = { .name = "rate", .descr = "Rate shaping parameters", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_RATE, .offset = offsetof(bcmbal_tm_sched_cfg_data, rate), .type = &type_descr_bcmbal_tm_shaping };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_tcont_sla = { .name = "tcont_sla", .descr = "Additional SLA parameters for agg_port owner", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA, .offset = offsetof(bcmbal_tm_sched_cfg_data, tcont_sla), .type = &type_descr_bcmbal_tm_tcont_sla };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_creation_mode = { .name = "creation_mode", .descr = "Creation mode", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE, .offset = offsetof(bcmbal_tm_sched_cfg_data, creation_mode), .type = &type_descr_bcmbal_tm_creation_mode };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_queues = { .name = "queues", .descr = "Subsidiary queues", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_TM_SCHED_CFG_ID_QUEUES, .offset = offsetof(bcmbal_tm_sched_cfg_data, queues), .type = &type_descr_bcmbal_tm_queue_id_list_u8 };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_sub_scheds = { .name = "sub_scheds", .descr = "Subsidiary schedulers", .access = BCMBAL_APICLI_PROP_ACCESS_ID_R, .property = BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS, .offset = offsetof(bcmbal_tm_sched_cfg_data, sub_scheds), .type = &type_descr_bcmbal_tm_sched_id_list_u8 };
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_cfg_num_priorities = { .name = "num_priorities", .descr = "Max number of strict priority scheduling elements", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES, .offset = offsetof(bcmbal_tm_sched_cfg_data, num_priorities), .type = &type_descr_uint8_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_sched_cfg_prop_array[] = { &prop_descr_tm_sched_cfg_owner, &prop_descr_tm_sched_cfg_sched_type, &prop_descr_tm_sched_cfg_sched_parent, &prop_descr_tm_sched_cfg_sched_child_type, &prop_descr_tm_sched_cfg_rate, &prop_descr_tm_sched_cfg_tcont_sla, &prop_descr_tm_sched_cfg_creation_mode, &prop_descr_tm_sched_cfg_queues, &prop_descr_tm_sched_cfg_sub_scheds, &prop_descr_tm_sched_cfg_num_priorities };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_cfg_data_fields[] = { { .name = "owner", .descr = "owner", .offset = offsetof(bcmbal_tm_sched_cfg_data, owner), .type = &type_descr_bcmbal_tm_sched_owner }, { .name = "sched_type", .descr = "Scheduler type", .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_type), .type = &type_descr_bcmbal_tm_sched_type }, { .name = "sched_parent", .descr = "Scheduling parameters for parent scheduler", .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_parent), .type = &type_descr_bcmbal_tm_sched_parent }, { .name = "sched_child_type", .descr = "Scheduling level for children tm ", .offset = offsetof(bcmbal_tm_sched_cfg_data, sched_child_type), .type = &type_descr_bcmbal_tm_sched_child_type }, { .name = "rate", .descr = "Rate shaping parameters", .offset = offsetof(bcmbal_tm_sched_cfg_data, rate), .type = &type_descr_bcmbal_tm_shaping }, { .name = "tcont_sla", .descr = "Additional SLA parameters for agg_port owner", .offset = offsetof(bcmbal_tm_sched_cfg_data, tcont_sla), .type = &type_descr_bcmbal_tm_tcont_sla }, { .name = "creation_mode", .descr = "Creation mode", .offset = offsetof(bcmbal_tm_sched_cfg_data, creation_mode), .type = &type_descr_bcmbal_tm_creation_mode }, { .name = "queues", .descr = "Subsidiary queues", .offset = offsetof(bcmbal_tm_sched_cfg_data, queues), .type = &type_descr_bcmbal_tm_queue_id_list_u8 }, { .name = "sub_scheds", .descr = "Subsidiary schedulers", .offset = offsetof(bcmbal_tm_sched_cfg_data, sub_scheds), .type = &type_descr_bcmbal_tm_sched_id_list_u8 }, { .name = "num_priorities", .descr = "Max number of strict priority scheduling elements", .offset = offsetof(bcmbal_tm_sched_cfg_data, num_priorities), .type = &type_descr_uint8_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_cfg_data = { .name = "bcmbal_tm_sched_cfg_data", .descr = "cfg", .size = sizeof(bcmbal_tm_sched_cfg_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_cfg_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_cfg_data_fields } } };
+
+/* Group: tm_sched - ind */
+static bcmbal_apicli_prop_descr BCM_DESCR prop_descr_tm_sched_ind_ret = { .name = "ret", .descr = "ret", .access = BCMBAL_APICLI_PROP_ACCESS_ID_RW, .property = BCMBAL_TM_SCHED_IND_ID_RET, .offset = offsetof(bcmbal_tm_sched_ind_data, ret), .type = &type_descr_uint32_t };
+static bcmbal_apicli_prop_descr * BCM_DESCR tm_sched_ind_prop_array[] = { &prop_descr_tm_sched_ind_ret };
+static bcmbal_apicli_field_descr BCM_DESCR type_descr_bcmbal_tm_sched_ind_data_fields[] = { { .name = "ret", .descr = "ret", .offset = offsetof(bcmbal_tm_sched_ind_data, ret), .type = &type_descr_uint32_t } };
+static bcmbal_apicli_type_descr BCM_DESCR type_descr_bcmbal_tm_sched_ind_data = { .name = "bcmbal_tm_sched_ind_data", .descr = "Tm Sched Indication", .size = sizeof(bcmbal_tm_sched_ind_data), .base_type = BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, .x = { .s = { .num_fields = sizeof(type_descr_bcmbal_tm_sched_ind_data_fields) / sizeof(bcmbal_apicli_field_descr), .fields = type_descr_bcmbal_tm_sched_ind_data_fields } } };
+
+/* ==== API Helper Function Implementations ==== */
+bcmos_errno bcmbal_apicli_object_struct_size(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, uint32_t *key_size, uint32_t *key_offset, uint32_t *data_size, uint32_t *data_offset)
+{
+ if (((key_size == NULL) || (key_offset == NULL)) || ((data_size == NULL) || (data_offset == NULL)))
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ switch (obj)
+ {
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_access_terminal_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_access_terminal_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_access_terminal_key);
+ *key_offset = offsetof(bcmbal_access_terminal_cfg, key);
+ *data_size = sizeof(bcmbal_access_terminal_cfg_data);
+ *data_offset = offsetof(bcmbal_access_terminal_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_ACCESS_TERMINAL_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_access_terminal_key);
+ *key_offset = offsetof(bcmbal_access_terminal_ind, key);
+ *data_size = sizeof(bcmbal_access_terminal_ind_data);
+ *data_offset = offsetof(bcmbal_access_terminal_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_FLOW:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_flow_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_flow_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_flow_key);
+ *key_offset = offsetof(bcmbal_flow_cfg, key);
+ *data_size = sizeof(bcmbal_flow_cfg_data);
+ *data_offset = offsetof(bcmbal_flow_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_flow_key);
+ *key_offset = offsetof(bcmbal_flow_stat, key);
+ *data_size = sizeof(bcmbal_flow_stat_data);
+ *data_offset = offsetof(bcmbal_flow_stat, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_FLOW_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_flow_key);
+ *key_offset = offsetof(bcmbal_flow_ind, key);
+ *data_size = sizeof(bcmbal_flow_ind_data);
+ *data_offset = offsetof(bcmbal_flow_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_group_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_group_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_group_key);
+ *key_offset = offsetof(bcmbal_group_cfg, key);
+ *data_size = sizeof(bcmbal_group_cfg_data);
+ *data_offset = offsetof(bcmbal_group_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_interface_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_interface_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_interface_key);
+ *key_offset = offsetof(bcmbal_interface_cfg, key);
+ *data_size = sizeof(bcmbal_interface_cfg_data);
+ *data_offset = offsetof(bcmbal_interface_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_interface_key);
+ *key_offset = offsetof(bcmbal_interface_stat, key);
+ *data_size = sizeof(bcmbal_interface_stat_data);
+ *data_offset = offsetof(bcmbal_interface_stat, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_INTERFACE_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_interface_key);
+ *key_offset = offsetof(bcmbal_interface_ind, key);
+ *data_size = sizeof(bcmbal_interface_ind_data);
+ *data_offset = offsetof(bcmbal_interface_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_PACKET:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_packet_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_packet_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_packet_key);
+ *key_offset = offsetof(bcmbal_packet_cfg, key);
+ *data_size = sizeof(bcmbal_packet_cfg_data);
+ *data_offset = offsetof(bcmbal_packet_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_PACKET_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_packet_key);
+ *key_offset = offsetof(bcmbal_packet_ind, key);
+ *data_size = sizeof(bcmbal_packet_ind_data);
+ *data_offset = offsetof(bcmbal_packet_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_subscriber_terminal_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_subscriber_terminal_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_subscriber_terminal_key);
+ *key_offset = offsetof(bcmbal_subscriber_terminal_cfg, key);
+ *data_size = sizeof(bcmbal_subscriber_terminal_cfg_data);
+ *data_offset = offsetof(bcmbal_subscriber_terminal_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_subscriber_terminal_key);
+ *key_offset = offsetof(bcmbal_subscriber_terminal_stat, key);
+ *data_size = sizeof(bcmbal_subscriber_terminal_stat_data);
+ *data_offset = offsetof(bcmbal_subscriber_terminal_stat, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_subscriber_terminal_key);
+ *key_offset = offsetof(bcmbal_subscriber_terminal_ind, key);
+ *data_size = sizeof(bcmbal_subscriber_terminal_ind_data);
+ *data_offset = offsetof(bcmbal_subscriber_terminal_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_QUEUE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_tm_queue_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_tm_queue_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_tm_queue_key);
+ *key_offset = offsetof(bcmbal_tm_queue_cfg, key);
+ *data_size = sizeof(bcmbal_tm_queue_cfg_data);
+ *data_offset = offsetof(bcmbal_tm_queue_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_tm_queue_key);
+ *key_offset = offsetof(bcmbal_tm_queue_stat, key);
+ *data_size = sizeof(bcmbal_tm_queue_stat_data);
+ *data_offset = offsetof(bcmbal_tm_queue_stat, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_QUEUE_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_tm_queue_key);
+ *key_offset = offsetof(bcmbal_tm_queue_ind, key);
+ *data_size = sizeof(bcmbal_tm_queue_ind_data);
+ *data_offset = offsetof(bcmbal_tm_queue_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_tm_sched_key);
+ *key_offset = 0;
+ *data_size = sizeof(bcmbal_tm_sched_key);
+ *data_offset = 0;
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *key_size = sizeof(bcmbal_tm_sched_key);
+ *key_offset = offsetof(bcmbal_tm_sched_cfg, key);
+ *data_size = sizeof(bcmbal_tm_sched_cfg_data);
+ *data_offset = offsetof(bcmbal_tm_sched_cfg, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_SCHED_AUTO_ID_IND:
+ *key_size = sizeof(bcmbal_tm_sched_key);
+ *key_offset = offsetof(bcmbal_tm_sched_ind, key);
+ *data_size = sizeof(bcmbal_tm_sched_ind_data);
+ *data_offset = offsetof(bcmbal_tm_sched_ind, data);
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ return BCM_ERR_INTERNAL; /**< should never happen. */
+}
+
+bcmos_errno bcmbal_apicli_object_subgroup_name(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, const char **name, const char **descr)
+{
+ switch (obj)
+ {
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_ACCESS_TERMINAL_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Access Terminal Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_FLOW:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "stat";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "stat";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_FLOW_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Flow Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "stat";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "stat";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_INTERFACE_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Interface Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_PACKET:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_PACKET_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Packet indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "stat";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "stat";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Subscriber Terminal Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_QUEUE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "stat";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "stat";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_QUEUE_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Tm Queue Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "key";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "key";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ if (name != NULL)
+ {
+ *name = "cfg";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "cfg";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_SCHED_AUTO_ID_IND:
+ if (name != NULL)
+ {
+ *name = "ind";
+ }
+
+ if (descr != NULL)
+ {
+ *descr = "Tm Sched Indication";
+ }
+
+ return BCM_ERR_OK;
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ default:
+ return BCM_ERR_RANGE;
+ }
+
+ return BCM_ERR_INTERNAL; /**< should never happen. */
+}
+
+static bcmbal_apicli_prop_descr **obj_get_prop_array(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, uint32_t *size)
+{
+ switch (obj)
+ {
+ case BCMBAL_OBJ_ID_ACCESS_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(access_terminal_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return access_terminal_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(access_terminal_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return access_terminal_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_ACCESS_TERMINAL_AUTO_ID_IND:
+ *size = sizeof(access_terminal_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return access_terminal_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_FLOW:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(flow_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return flow_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(flow_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return flow_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(flow_stat_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return flow_stat_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_FLOW_AUTO_ID_IND:
+ *size = sizeof(flow_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return flow_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_GROUP:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(group_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return group_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(group_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return group_cfg_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_INTERFACE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(interface_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return interface_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(interface_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return interface_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(interface_stat_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return interface_stat_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_INTERFACE_AUTO_ID_IND:
+ *size = sizeof(interface_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return interface_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_PACKET:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(packet_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return packet_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(packet_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return packet_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_PACKET_AUTO_ID_IND:
+ *size = sizeof(packet_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return packet_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(subscriber_terminal_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return subscriber_terminal_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(subscriber_terminal_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return subscriber_terminal_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(subscriber_terminal_stat_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return subscriber_terminal_stat_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND:
+ *size = sizeof(subscriber_terminal_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return subscriber_terminal_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_TM_QUEUE:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(tm_queue_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_queue_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(tm_queue_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_queue_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_STAT:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(tm_queue_stat_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_queue_stat_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_QUEUE_AUTO_ID_IND:
+ *size = sizeof(tm_queue_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_queue_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ case BCMBAL_OBJ_ID_TM_SCHED:
+ switch (group)
+ {
+ case BCMBAL_MGT_GROUP_KEY:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(tm_sched_key_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_sched_key_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_CFG:
+ switch (subgroup)
+ {
+ case 0:
+ *size = sizeof(tm_sched_cfg_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_sched_cfg_prop_array;
+ default:
+ break;
+ }
+
+ case BCMBAL_MGT_GROUP_AUTO:
+ switch (subgroup)
+ {
+ case BCMBAL_TM_SCHED_AUTO_ID_IND:
+ *size = sizeof(tm_sched_ind_prop_array) / sizeof(bcmbal_apicli_prop_descr *);
+ return tm_sched_ind_prop_array;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+bcmos_errno bcmbal_apicli_object_name(bcmbal_obj_id obj, const char **name, const char **descr)
+{
+ if (obj >= BCMBAL_OBJ_ID__NUM_OF)
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ if (object_name[obj] == NULL)
+ {
+ return BCM_ERR_NOENT;
+ }
+
+ if (name != NULL)
+ {
+ *name = object_name[obj];
+ }
+
+ if (descr != NULL)
+ {
+ *descr = object_descr[obj];
+ }
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno bcmbal_apicli_object_property(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, uint16_t prop, const bcmbal_apicli_prop_descr **descr)
+{
+ bcmbal_apicli_prop_descr **prop_array = NULL;
+ uint32_t prop_array_size = 0;
+ if (descr == NULL)
+ {
+ return BCM_ERR_PARM;
+ }
+
+ prop_array = obj_get_prop_array(obj, group, subgroup, &prop_array_size);
+ if ((prop_array == NULL) || (prop >= prop_array_size))
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ if (prop_array[prop] == NULL)
+ {
+ return BCM_ERR_NOENT;
+ }
+
+ *descr = prop_array[prop];
+ return BCM_ERR_OK;
+}
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.h b/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.h
new file mode 100644
index 0000000..07e922a
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_helpers.h
@@ -0,0 +1,221 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+#ifndef BCMBAL_APICLI_HELPERS_H_
+#define BCMBAL_APICLI_HELPERS_H_
+
+#include <bcmcli.h>
+#include <bal_api.h>
+#include "bal_api_cli_types.h"
+
+/* Mac name length */
+#define BCMBAL_APICLI_MAX_PARM_NAME_LENGTH BCMCLI_MAX_SEARCH_SUBSTR_LENGTH
+
+/* Max help string length */
+#define BCMBAL_APICLI_MAX_PARM_HELP_LENGTH 128
+
+typedef enum bcmbal_apicli_field_descr_flags
+{
+ BCMBAL_APICLI_FIELD_DESCR_FLAGS_NONE = 0,
+ BCMBAL_APICLI_FIELD_DESCR_FLAGS_PRESENCE_MASK = (1 << 0) /* field is a 'presence mask' for a structure */
+} bcmbal_apicli_field_descr_flags;
+
+typedef struct bcmbal_apicli_type_descr bcmbal_apicli_type_descr;
+
+/* Structure field descriptor */
+typedef struct bcmbal_apicli_field_descr
+{
+ const char *name; /* Field name */
+ const char *descr; /* Field description */
+ const char *cli_name; /* Short CLI name. can be missing */
+ bcmbal_apicli_type_descr *type; /* Field type */
+ uint16_t offset; /* Offset from the beginning of the type structure */
+ bcmbal_apicli_field_descr_flags flags;
+} bcmbal_apicli_field_descr;
+
+/* Data type descriptor */
+struct bcmbal_apicli_type_descr
+{
+ const char *name; /* Type name */
+ const char *descr; /* Type description. can be missing */
+ const char *cli_name; /* Short CLI name. can be missing */
+ bcmbal_apicli_base_type_id base_type; /* Base type: snum, unum, string, ip, enum, etc. */
+ uint32_t min_val; /* Min value for range check */
+ uint32_t max_val; /* Max value for range check */
+ uint16_t size; /* Size */
+
+ /* The following union is qualified by the base_type and contains additional
+ * info for array, enum, struct, union */
+ union
+ {
+ bcmcli_enum_val *e; /* enum value array Contains num_elements+1 values. The last value has name=NULL */
+ struct
+ {
+ uint16_t num_fields; /* number of elements in the following structure */
+ bcmbal_apicli_field_descr *fields; /* Structure field array. Contains num_elements values */
+ } s;
+ struct
+ {
+ uint16_t num_common_fields; /* number of non-union fields at the start of the struct */
+ bcmbal_apicli_field_descr *common_fields; /* common field array. Contains num_elements values */
+ uint16_t classifier_idx; /* index of the classifier field within common_fields */
+ bcmbal_apicli_field_descr *union_fields; /* sub-struct fields under the union (name == NULL if no fields present)
+ (one per enum entry in the classifier type, plus one for default) */
+ } u;
+ struct
+ {
+ bcmbal_apicli_type_descr *elem_type; /* Array element type */
+ uint8_t len_size; /* Byte width of array length field (at start of struct) */
+ uint16_t max_size; /* Max array size */
+ } arr_dyn;
+ struct
+ {
+ bcmbal_apicli_type_descr *elem_type; /* Array element type */
+ uint16_t size; /* Fixed array size */
+ } arr_fixed;
+ } x;
+};
+
+/* Property descriptor.
+ * The 1st 5 fields are exactly the same as in bcmbal_apicli_field_descr
+ * ToDo: replace with bcmbal_apicli_field_descr substructure.
+ * Requires changes in code generator
+ */
+typedef struct
+{
+ const char *name; /* C name */
+ const char *descr; /* Property description */
+ const char *cli_name; /* CLI name */
+ bcmbal_apicli_type_descr *type; /* Type reference */
+ uint16_t offset; /* Offset in generated per-group structure */
+ uint16_t property; /* Property id in per-object management group */
+ bcmbal_apicli_prop_access_id access; /* Access */
+} bcmbal_apicli_prop_descr;
+
+/* All APIs return
+ * BCM_ERR_OK - ok
+ * BCM_ERR_NOENT - if id is in range, but doesn't correspond to any value (a hole)
+ * BCM_ERR_RANGE - id is out of range
+ */
+
+/* Get object name by id */
+bcmos_errno bcmbal_apicli_object_name(bcmbal_obj_id obj, const char **name, const char **descr);
+
+/* Get object structure size */
+bcmos_errno bcmbal_apicli_object_struct_size(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, uint32_t *key_size, uint32_t *key_offset, uint32_t *data_size, uint32_t *data_offset);
+
+/* Get object subgroup (e.g. specific indication) name and description */
+bcmos_errno bcmbal_apicli_object_subgroup_name(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, const char **name, const char **descr);
+
+/* Get property by object, mgt_group, subgroup (e.g. specific indication), property_id */
+bcmos_errno bcmbal_apicli_object_property(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, uint16_t prop, const bcmbal_apicli_prop_descr **descr);
+
+/* Get the number of subgroups present for a given group */
+static inline uint16_t bcmbal_apicli_get_subgroup_count(bcmbal_obj_id obj, bcmbal_mgt_group group)
+{
+ uint16_t count = 0;
+ uint32_t dummy;
+ while (bcmbal_apicli_object_struct_size(obj, group, count, &dummy, &dummy, &dummy, &dummy) != BCM_ERR_RANGE)
+ {
+ ++count;
+ }
+
+ return count;
+}
+
+/* Dump a single property */
+bcmos_errno bcmbal_apicli_dump_prop(bcmcli_session *session, const bcmbal_apicli_prop_descr *pd, void *prop_data);
+
+/* Dump a single property value in C initializer format */
+bcmos_errno bcmbal_apicli_dump_prop_initializer(bcmcli_session *session, const bcmbal_apicli_prop_descr *pd, void *prop_data);
+
+/* Dump message */
+bcmos_errno bcmbal_apicli_msg_dump(bcmcli_session *session, bcmbal_obj *msg);
+
+/* Message group name */
+const char *bcmbal_apicli_mgt_group_to_str(bcmbal_mgt_group group);
+
+/* Convert an enum value to the corresponding string */
+#define BCMOLT_ENUM_STRING_VAL(enum_name, value) bcmcli_enum_stringval(enum_name ## _string_table, (value))
+
+/* Enum string tables */
+extern bcmcli_enum_val bcmbal_access_terminal_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_access_terminal_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_access_terminal_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_action_id_string_table[];
+extern bcmcli_enum_val bcmbal_action_cmd_id_string_table[];
+extern bcmcli_enum_val bcmbal_classifier_id_string_table[];
+extern bcmcli_enum_val bcmbal_pkt_tag_type_string_table[];
+extern bcmcli_enum_val bcmbal_control_string_table[];
+extern bcmcli_enum_val bcmbal_dest_type_string_table[];
+extern bcmcli_enum_val bcmbal_ds_miss_mode_string_table[];
+extern bcmcli_enum_val bcmbal_extra_bw_eligibility_type_string_table[];
+extern bcmcli_enum_val bcmbal_flow_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_flow_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_flow_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_flow_stat_id_string_table[];
+extern bcmcli_enum_val bcmbal_flow_type_string_table[];
+extern bcmcli_enum_val bcmbal_group_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_group_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_group_member_cmd_string_table[];
+extern bcmcli_enum_val bcmbal_group_owner_string_table[];
+extern bcmcli_enum_val bcmbal_interface_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_interface_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_interface_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_interface_stat_id_string_table[];
+extern bcmcli_enum_val bcmbal_intf_type_string_table[];
+extern bcmcli_enum_val bcmbal_iwf_mode_string_table[];
+extern bcmcli_enum_val bcmbal_packet_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_packet_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_packet_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_sla_id_string_table[];
+extern bcmcli_enum_val bcmbal_state_string_table[];
+extern bcmcli_enum_val bcmbal_status_string_table[];
+extern bcmcli_enum_val bcmbal_subscriber_terminal_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_subscriber_terminal_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_subscriber_terminal_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_subscriber_terminal_stat_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_bac_type_string_table[];
+extern bcmcli_enum_val bcmbal_tm_creation_mode_string_table[];
+extern bcmcli_enum_val bcmbal_tm_queue_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_queue_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_queue_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_queue_stat_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_cfg_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_child_type_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_dir_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_ind_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_key_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_owner_type_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_owner_agg_port_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_parent_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_sched_type_string_table[];
+extern bcmcli_enum_val bcmbal_tm_shaping_id_string_table[];
+extern bcmcli_enum_val bcmbal_tm_tcont_sla_id_string_table[];
+extern bcmcli_enum_val bcmbal_trx_type_string_table[];
+#endif /* BCMBAL_APICLI_HELPERS_H_ */
diff --git a/bal_release/src/lib/libbalapicli/bal_api_cli_types.h b/bal_release/src/lib/libbalapicli/bal_api_cli_types.h
new file mode 100644
index 0000000..8e38a6c
--- /dev/null
+++ b/bal_release/src/lib/libbalapicli/bal_api_cli_types.h
@@ -0,0 +1,60 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#ifndef BCMBAL_APICLI_TYPES_H_
+#define BCMBAL_APICLI_TYPES_H_
+
+/* Property access */
+typedef enum
+{
+ BCMBAL_APICLI_PROP_ACCESS_ID_R = 0x1, /* Read access */
+ BCMBAL_APICLI_PROP_ACCESS_ID_W = 0x2, /* Write access */
+ BCMBAL_APICLI_PROP_ACCESS_ID_RW = 0x3, /* Read-write */
+} bcmbal_apicli_prop_access_id;
+
+/* Base data types */
+typedef enum
+{
+ BCMBAL_APICLI_BASE_TYPE_ID_SNUM, /* signed number */
+ BCMBAL_APICLI_BASE_TYPE_ID_UNUM, /* unsigned number */
+ BCMBAL_APICLI_BASE_TYPE_ID_UNUM_HEX, /* unsigned number printed in hex */
+ BCMBAL_APICLI_BASE_TYPE_ID_FLOAT, /* floating-point number */
+ BCMBAL_APICLI_BASE_TYPE_ID_BOOL, /* boolean (zero=no, nonzero=yes) */
+ BCMBAL_APICLI_BASE_TYPE_ID_STRING, /* string */
+ BCMBAL_APICLI_BASE_TYPE_ID_IPV4, /* IPv4 address */
+ BCMBAL_APICLI_BASE_TYPE_ID_MAC, /* MAC address */
+ BCMBAL_APICLI_BASE_TYPE_ID_ENUM, /* enum */
+ BCMBAL_APICLI_BASE_TYPE_ID_ENUM_MASK, /* bitmask enum */
+ BCMBAL_APICLI_BASE_TYPE_ID_STRUCT, /* struct */
+ BCMBAL_APICLI_BASE_TYPE_ID_UNION, /* union */
+ BCMBAL_APICLI_BASE_TYPE_ID_ARR_DYN, /* dynamically-sized array */
+ BCMBAL_APICLI_BASE_TYPE_ID_ARR_FIXED, /* fixed-size array */
+} bcmbal_apicli_base_type_id;
+
+#endif /* BCMBAL_APICLI_TYPES_H_ */
diff --git a/bal_release/src/lib/libcmdline/Makefile b/bal_release/src/lib/libcmdline/Makefile
new file mode 100644
index 0000000..5c5038d
--- /dev/null
+++ b/bal_release/src/lib/libcmdline/Makefile
@@ -0,0 +1,35 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = cmdline
+MOD_TYPE = lib
+
+srcs = cmdline.c
+
diff --git a/bal_release/src/lib/libcmdline/cmdline.c b/bal_release/src/lib/libcmdline/cmdline.c
new file mode 100644
index 0000000..d20b10a
--- /dev/null
+++ b/bal_release/src/lib/libcmdline/cmdline.c
@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+/*
+ * cmdline.c - Command line argument helper
+ */
+
+#include <cmdline.h>
+
+/* Print usage information */
+bcmos_errno cl_print_usage(const char *app, const char *arg,
+ const cl_argument supported_args[], int num_supported_args,
+ cl_argument_usage_flags flags)
+{
+ const char *owner = "";
+ int i;
+
+ if (arg)
+ bcmos_printf("*** Error in parameter %s\n", arg);
+ if (app)
+ {
+ const char *p, *fname;
+ p = strrchr(app, '/');
+ fname = p ? p + 1 : app;
+ bcmos_printf("Usage: %s arguments\n", fname);
+ }
+ for (i = 0; i < num_supported_args; i++)
+ {
+ const cl_argument *opt = &supported_args[i];
+ if ((flags & CL_ARGUMENT_USAGE_FLAG_OWNER) != 0 &&
+ opt->owner && strcmp(opt->owner, owner))
+ {
+ owner = opt->owner;
+ bcmos_printf("\n%s options:\n", owner);
+ }
+ if (opt->short_name)
+ bcmos_printf("%-3s%c", opt->short_name, opt->long_name ? ',' : ' ');
+ else
+ bcmos_printf(" ");
+ bcmos_printf("%-20s %20s %s\n",
+ opt->long_name ? opt->long_name : "",
+ opt->extra_arg ? opt->extra_arg : "",
+ opt->description ? opt->description : "");
+ }
+ return BCM_ERR_PARM;
+}
+
+/* Get parameter by name */
+const cl_argument *cl_parm_get(const char *name, const cl_argument supported_args[], int num_supported_args)
+{
+ const cl_argument *opt = NULL;
+ int i;
+
+ /* Make sure that all mandatory parameters are set */
+ for (i = 0; i < num_supported_args; i++)
+ {
+ opt = &supported_args[i];
+ if ((opt->short_name && !strcmp(opt->short_name, name)) ||
+ (opt->long_name && !strcmp(opt->long_name, name)))
+ break;
+ }
+ return (i < num_supported_args) ? opt : NULL;
+}
+
+/* Validate command line parameters */
+bcmos_errno cl_validate(int argc, char *argv[],
+ const cl_argument supported_args[], int num_supported_args)
+{
+ bcmos_bool parm_set[num_supported_args];
+ bcmos_errno rc = BCM_ERR_OK;
+ int i;
+
+ memset(parm_set, 0, sizeof(parm_set));
+ for (i = 1; i < argc; i++)
+ {
+ const cl_argument *opt = cl_parm_get(argv[i], supported_args, num_supported_args);
+ if (opt == NULL)
+ {
+ bcmos_printf("*** Invalid parameter: %s\n", argv[i]);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ if (opt->extra_arg)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ bcmos_printf("*** Argument is missing after %s\n", argv[i-1]);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ parm_set[opt - supported_args] = BCMOS_TRUE;
+ }
+
+ /* Make sure that all mandatory parameters are set */
+ for (i = 0; i < num_supported_args; i++)
+ {
+ const cl_argument *opt = &supported_args[i];
+ if ((opt->flags & CL_ARGUMENT_FLAG_MANDATORY) && !parm_set[i])
+ {
+ bcmos_printf("*** Mandatory parameter %s is missing\n", opt->long_name ? opt->long_name : opt->short_name);
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ return rc;
+}
diff --git a/bal_release/src/lib/libcmdline/cmdline.h b/bal_release/src/lib/libcmdline/cmdline.h
new file mode 100644
index 0000000..cad20b0
--- /dev/null
+++ b/bal_release/src/lib/libcmdline/cmdline.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+/*
+ * cmdline.h - Command line argument helper
+ */
+
+#ifndef _CMDLINE_H_
+#define _CMDLINE_H_
+
+#include <bcmos_system.h>
+
+/** Argument flags */
+typedef enum
+{
+ CL_ARGUMENT_FLAG_NONE = 0,
+ CL_ARGUMENT_FLAG_MANDATORY = 0x1,
+} cl_argument_flags;
+
+/** Command line argument */
+typedef struct cl_argument
+{
+ const char *long_name; /**< Command line option: long form */
+ const char *short_name; /**< Command line option: short form */
+ const char *extra_arg; /**< Extra arguments */
+ const char *description; /**< Description */
+ const char *owner; /**< Owner module */
+ cl_argument_flags flags; /**< Command line argument flags */
+} cl_argument;
+
+/** Print usage flags */
+typedef enum
+{
+ CL_ARGUMENT_USAGE_FLAG_NONE = 0,
+ CL_ARGUMENT_USAGE_FLAG_OWNER = 0x1, /**< Print argument owners */
+} cl_argument_usage_flags;
+
+/** Print usage
+ * \param[in] app Application name. Can be NULL
+ * \param[in] arg Argument that triggered command line parsing error. Can be NULL
+ * \param[in] supported_args Array of supported arguments
+ * \param[in] num_supported_args Number of elements in supported_args[] array
+ * \param[in] flags Usage flags
+ * \returns BCM_ERR_PARM
+ */
+bcmos_errno cl_print_usage(const char *app, const char *arg,
+ const cl_argument supported_args[], int num_supported_args,
+ cl_argument_usage_flags flags);
+
+/** Validate parameters
+ *
+ * - make sure that there are no unknown parameters
+ * - make sure that all mandatory parameters are present
+ *
+ * \param[in] argc Number of command line arguments
+ * \param[in] argv Command line arguments
+ * \param[in] supported_args Array of supported arguments
+ * \param[in] num_supported_args Number of elements in supported_args[] array
+ * \returns BCM_ERR_OK or BCM_ERR_PARM
+ */
+bcmos_errno cl_validate(int argc, char *argv[],
+ const cl_argument supported_args[], int num_supported_args);
+
+/** Get CL parameter by name
+ *
+ * \param[in] name Parameter name
+ * \param[in] supported_args Supported arguments array
+ * \param[in] num_supported_args Supported arguments array size
+ * \returns argument descriptor pointer or NULL if not found
+ */
+const cl_argument *cl_parm_get(const char *name, const cl_argument supported_args[],
+ int num_supported_args);
+
+#endif /* _CMDLINE_H_ */
diff --git a/bal_release/src/lib/libobjmsg/Makefile b/bal_release/src/lib/libobjmsg/Makefile
new file mode 100644
index 0000000..15ff2d9
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/Makefile
@@ -0,0 +1,37 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = balobjmsg
+MOD_TYPE = lib
+MOD_DEPS = common_include utils maple_sdk dev_log
+
+gen_bal_hdrs = bal_model_funcs.h bal_obj_msg_pack_unpack.h
+gen_bal_srcs = bal_model_funcs.c bal_obj_msg_pack_unpack.c
+srcs = bal_msg.c
diff --git a/bal_release/src/lib/libobjmsg/bal_model_funcs.c b/bal_release/src/lib/libobjmsg/bal_model_funcs.c
new file mode 100644
index 0000000..262999f
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/bal_model_funcs.c
@@ -0,0 +1,11384 @@
+#include <bcmos_system.h>
+#include "bal_model_funcs.h"
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_id_pack(bcmbal_access_terminal_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_id_unpack(bcmbal_access_terminal_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_id_pack(bcmbal_access_terminal_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_id_unpack(bcmbal_access_terminal_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_id_pack(bcmbal_access_terminal_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_id_unpack(bcmbal_access_terminal_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_id_pack(bcmbal_action_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_id_unpack(bcmbal_action_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_cmd_id_pack(bcmbal_action_cmd_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_cmd_id_unpack(bcmbal_action_cmd_id *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_id_pack(bcmbal_classifier_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_id_unpack(bcmbal_classifier_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_pkt_tag_type_pack(bcmbal_pkt_tag_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_pkt_tag_type_unpack(bcmbal_pkt_tag_type *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_control_pack(bcmbal_control this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_control_unpack(bcmbal_control *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_type_pack(bcmbal_dest_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_type_unpack(bcmbal_dest_type *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_ds_miss_mode_pack(bcmbal_ds_miss_mode this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_ds_miss_mode_unpack(bcmbal_ds_miss_mode *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_extra_bw_eligibility_type_pack(bcmbal_extra_bw_eligibility_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_extra_bw_eligibility_type_unpack(bcmbal_extra_bw_eligibility_type *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_id_pack(bcmbal_flow_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_id_unpack(bcmbal_flow_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_id_pack(bcmbal_flow_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_id_unpack(bcmbal_flow_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_id_pack(bcmbal_flow_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_id_unpack(bcmbal_flow_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_id_pack(bcmbal_flow_stat_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_id_unpack(bcmbal_flow_stat_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_type_pack(bcmbal_flow_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_type_unpack(bcmbal_flow_type *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_id_pack(bcmbal_group_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_id_unpack(bcmbal_group_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_id_pack(bcmbal_group_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_id_unpack(bcmbal_group_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_cmd_pack(bcmbal_group_member_cmd this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_cmd_unpack(bcmbal_group_member_cmd *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_owner_pack(bcmbal_group_owner this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_owner_unpack(bcmbal_group_owner *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_id_pack(bcmbal_interface_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_id_unpack(bcmbal_interface_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_id_pack(bcmbal_interface_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_id_unpack(bcmbal_interface_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_id_pack(bcmbal_interface_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_id_unpack(bcmbal_interface_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_id_pack(bcmbal_interface_stat_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_id_unpack(bcmbal_interface_stat_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_intf_type_pack(bcmbal_intf_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_intf_type_unpack(bcmbal_intf_type *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_iwf_mode_pack(bcmbal_iwf_mode this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_iwf_mode_unpack(bcmbal_iwf_mode *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_id_pack(bcmbal_packet_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_id_unpack(bcmbal_packet_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_id_pack(bcmbal_packet_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_id_unpack(bcmbal_packet_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_id_pack(bcmbal_packet_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_id_unpack(bcmbal_packet_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_id_pack(bcmbal_sla_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_id_unpack(bcmbal_sla_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_state_pack(bcmbal_state this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_state_unpack(bcmbal_state *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_status_pack(bcmbal_status this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_status_unpack(bcmbal_status *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_id_pack(bcmbal_subscriber_terminal_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_id_unpack(bcmbal_subscriber_terminal_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_id_pack(bcmbal_subscriber_terminal_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_id_unpack(bcmbal_subscriber_terminal_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_id_pack(bcmbal_subscriber_terminal_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_id_unpack(bcmbal_subscriber_terminal_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_id_pack(bcmbal_subscriber_terminal_stat_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_id_unpack(bcmbal_subscriber_terminal_stat_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_type_pack(bcmbal_tm_bac_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_type_unpack(bcmbal_tm_bac_type *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_creation_mode_pack(bcmbal_tm_creation_mode this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_creation_mode_unpack(bcmbal_tm_creation_mode *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_id_pack(bcmbal_tm_queue_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_id_unpack(bcmbal_tm_queue_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_id_pack(bcmbal_tm_queue_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_id_unpack(bcmbal_tm_queue_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_id_pack(bcmbal_tm_queue_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_id_unpack(bcmbal_tm_queue_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_id_pack(bcmbal_tm_queue_stat_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_id_unpack(bcmbal_tm_queue_stat_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_id_pack(bcmbal_tm_sched_cfg_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_id_unpack(bcmbal_tm_sched_cfg_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_child_type_pack(bcmbal_tm_sched_child_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_child_type_unpack(bcmbal_tm_sched_child_type *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_dir_pack(bcmbal_tm_sched_dir this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_dir_unpack(bcmbal_tm_sched_dir *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_id_pack(bcmbal_tm_sched_ind_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_id_unpack(bcmbal_tm_sched_ind_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_id_pack(bcmbal_tm_sched_key_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u16(buf, (uint16_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_id_unpack(bcmbal_tm_sched_key_id *this, bcmbal_buf *buf)
+{
+ uint16_t num_val;
+ if (!bcmbal_buf_read_u16(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_type_pack(bcmbal_tm_sched_owner_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_type_unpack(bcmbal_tm_sched_owner_type *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_agg_port_id_pack(bcmbal_tm_sched_owner_agg_port_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_agg_port_id_unpack(bcmbal_tm_sched_owner_agg_port_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_id_pack(bcmbal_tm_sched_parent_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_id_unpack(bcmbal_tm_sched_parent_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_type_pack(bcmbal_tm_sched_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u8(buf, (uint8_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_type_unpack(bcmbal_tm_sched_type *this, bcmbal_buf *buf)
+{
+ uint8_t num_val;
+ if (!bcmbal_buf_read_u8(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_id_pack(bcmbal_tm_shaping_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_id_unpack(bcmbal_tm_shaping_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_id_pack(bcmbal_tm_tcont_sla_id this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u64(buf, (uint64_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_id_unpack(bcmbal_tm_tcont_sla_id *this, bcmbal_buf *buf)
+{
+ uint64_t num_val;
+ if (!bcmbal_buf_read_u64(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_trx_type_pack(bcmbal_trx_type this, bcmbal_buf *buf)
+{
+ return bcmbal_buf_write_u32(buf, (uint32_t) this);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_trx_type_unpack(bcmbal_trx_type *this, bcmbal_buf *buf)
+{
+ uint32_t num_val;
+ if (!bcmbal_buf_read_u32(buf, &num_val))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *this = num_val;
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_action_set_default(bcmbal_action *this)
+{
+ this->presence_mask = (bcmbal_action_id) 0;
+ this->cmds_bitmask = (bcmbal_action_cmd_id) 0;
+ this->o_vid = 0;
+ this->o_pbits = 0;
+ this->o_tpid = 0;
+ this->i_vid = 0;
+ this->i_pbits = 0;
+ this->i_tpid = 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_pack(const bcmbal_action *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_action_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_action_cmd_id_pack(this->cmds_bitmask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->o_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->o_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->o_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->i_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->i_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->i_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_action_get_packed_length(const bcmbal_action *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ count += 2;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_unpack(bcmbal_action *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_action_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_action_cmd_id_unpack(&this->cmds_bitmask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->o_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->o_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->o_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->i_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->i_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->i_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_action_id presence_mask;
+ if (!bcmbal_action_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_action_bounds_check(const bcmbal_action *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFFFF80ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if ((this->cmds_bitmask & 0xFFFFE000UL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_aggregation_port_id_list_u8_set_default(bcmbal_aggregation_port_id_list_u8 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_aggregation_port_id_list_u8_pack(const bcmbal_aggregation_port_id_list_u8 *this, bcmbal_buf *buf)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_write_u8(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_aggregation_port_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_aggregation_port_id_list_u8_get_packed_length(const bcmbal_aggregation_port_id_list_u8 *this)
+{
+ return 1 + (2 * this->len);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_aggregation_port_id_list_u8_unpack(bcmbal_aggregation_port_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_read_u8(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_aggregation_port_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_aggregation_port_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_aggregation_port_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_aggregation_port_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint8_t len;
+ if (!bcmbal_buf_read_u8(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_aggregation_port_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 2))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_aggregation_port_id_list_u8_bounds_check(const bcmbal_aggregation_port_id_list_u8 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_classifier_set_default(bcmbal_classifier *this)
+{
+ this->presence_mask = (bcmbal_classifier_id) 0;
+ this->o_tpid = 0;
+ this->o_vid = 0;
+ this->i_tpid = 0;
+ this->i_vid = 0;
+ this->o_pbits = 0;
+ this->i_pbits = 0;
+ this->ether_type = 0;
+ bcmos_mac_address_init(&this->dst_mac);
+ bcmos_mac_address_init(&this->src_mac);
+ this->ip_proto = 0;
+ bcmos_ipv4_address_init(&this->dst_ip);
+ bcmos_ipv4_address_init(&this->src_ip);
+ this->src_port = 0;
+ this->dst_port = 0;
+ this->pkt_tag_type = (bcmbal_pkt_tag_type) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_pack(const bcmbal_classifier *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_classifier_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->o_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->o_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->i_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->i_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->o_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->i_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->ether_type))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0080) == 0x0080))
+ {
+ if (!bcmbal_buf_write_mac_address(buf, this->dst_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0100) == 0x0100))
+ {
+ if (!bcmbal_buf_write_mac_address(buf, this->src_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0200) == 0x0200))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->ip_proto))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0400) == 0x0400))
+ {
+ if (!bcmbal_buf_write_ipv4_address(buf, this->dst_ip))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0800) == 0x0800))
+ {
+ if (!bcmbal_buf_write_ipv4_address(buf, this->src_ip))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x1000) == 0x1000))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->src_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x2000) == 0x2000))
+ {
+ if (!bcmbal_buf_write_u16(buf, this->dst_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x4000) == 0x4000))
+ {
+ if (!bcmbal_pkt_tag_type_pack(this->pkt_tag_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_classifier_get_packed_length(const bcmbal_classifier *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0080) == 0x0080))
+ {
+ count += 6;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0100) == 0x0100))
+ {
+ count += 6;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0200) == 0x0200))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0400) == 0x0400))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0800) == 0x0800))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x1000) == 0x1000))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x2000) == 0x2000))
+ {
+ count += 2;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x4000) == 0x4000))
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_unpack(bcmbal_classifier *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_classifier_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->o_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->o_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->i_tpid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->i_vid))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->o_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->i_pbits))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->ether_type))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0080) == 0x0080))
+ {
+ if (!bcmbal_buf_read_mac_address(buf, &this->dst_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0100) == 0x0100))
+ {
+ if (!bcmbal_buf_read_mac_address(buf, &this->src_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0200) == 0x0200))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->ip_proto))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0400) == 0x0400))
+ {
+ if (!bcmbal_buf_read_ipv4_address(buf, &this->dst_ip))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0800) == 0x0800))
+ {
+ if (!bcmbal_buf_read_ipv4_address(buf, &this->src_ip))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x1000) == 0x1000))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->src_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x2000) == 0x2000))
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->dst_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x4000) == 0x4000))
+ {
+ if (!bcmbal_pkt_tag_type_unpack(&this->pkt_tag_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_classifier_id presence_mask;
+ if (!bcmbal_classifier_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0020) == 0x0020))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0040) == 0x0040))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0080) == 0x0080))
+ {
+ if (!bcmbal_buf_skip(packed, 6))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0100) == 0x0100))
+ {
+ if (!bcmbal_buf_skip(packed, 6))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0200) == 0x0200))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0400) == 0x0400))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0800) == 0x0800))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x1000) == 0x1000))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x2000) == 0x2000))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x4000) == 0x4000))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_classifier_bounds_check(const bcmbal_classifier *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFF8000ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x4000) == 0x4000))
+ {
+ if ((this->pkt_tag_type & 0xFFFFFFF8UL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_dest_set_default(bcmbal_dest *this)
+{
+ this->type = (bcmbal_dest_type) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_pack(const bcmbal_dest *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_dest_type_pack(this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.nni.int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.sub_term.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u16(buf, this->u.sub_term.sub_term_uni))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u16(buf, this->u.sub_term.int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ {
+ }
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_dest_get_packed_length(const bcmbal_dest *this)
+{
+ uint32_t count = 4;
+ switch (this->type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ {
+ count += 4;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ {
+ count += 8;
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ {
+ }
+ break;
+ default:
+ break;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_unpack(bcmbal_dest *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_dest_type_unpack(&this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.nni.int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.sub_term.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u16(buf, &this->u.sub_term.sub_term_uni))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u16(buf, &this->u.sub_term.int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ {
+ }
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_dest_type type;
+ if (!bcmbal_dest_type_unpack(&type, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ {
+ }
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_dest_bounds_check(const bcmbal_dest *this)
+{
+ switch (this->type)
+ {
+ case BCMBAL_DEST_TYPE_NNI:
+ {
+ }
+ break;
+ case BCMBAL_DEST_TYPE_SUB_TERM:
+ {
+ }
+ break;
+ case BCMBAL_DEST_TYPE_HOST:
+ {
+ }
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_flow_id_list_u32_set_default(bcmbal_flow_id_list_u32 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_id_list_u32_pack(const bcmbal_flow_id_list_u32 *this, bcmbal_buf *buf)
+{
+ uint32_t i0;
+ if (!bcmbal_buf_write_u32(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_flow_id_list_u32\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_flow_id_list_u32_get_packed_length(const bcmbal_flow_id_list_u32 *this)
+{
+ return 4 + (4 * this->len);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_id_list_u32_unpack(bcmbal_flow_id_list_u32 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint32_t i0;
+ if (!bcmbal_buf_read_u32(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_flow_id_list_u32\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_flow_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_flow_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_id_list_u32_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint32_t len;
+ if (!bcmbal_buf_read_u32(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_flow_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_id_list_u32_bounds_check(const bcmbal_flow_id_list_u32 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_ref_set_default(bcmbal_tm_queue_ref *this)
+{
+ this->sched_id = (bcmbal_tm_sched_id) 0;
+ this->queue_id = (bcmbal_tm_queue_id) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ref_pack(const bcmbal_tm_queue_ref *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->queue_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ref_unpack(bcmbal_tm_queue_ref *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->queue_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ref_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ (void)extra_mem;
+ return bcmbal_buf_skip(packed, 5);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ref_bounds_check(const bcmbal_tm_queue_ref *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_group_member_info_set_default(bcmbal_group_member_info *this)
+{
+ this->intf_id = (bcmbal_intf_id) 0;
+ this->svc_port_id = (bcmbal_service_port_id) 0;
+ this->action.presence_mask = (bcmbal_action_id) 0;
+ this->action.cmds_bitmask = (bcmbal_action_cmd_id) 0;
+ this->action.o_vid = 0;
+ this->action.o_pbits = 0;
+ this->action.o_tpid = 0;
+ this->action.i_vid = 0;
+ this->action.i_pbits = 0;
+ this->action.i_tpid = 0;
+ this->queue.sched_id = (bcmbal_tm_sched_id) 0;
+ this->queue.queue_id = (bcmbal_tm_queue_id) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_pack(const bcmbal_group_member_info *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_action_pack(&this->action, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_queue_ref_pack(&this->queue, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_group_member_info_get_packed_length(const bcmbal_group_member_info *this)
+{
+ return 11 + bcmbal_action_get_packed_length(&this->action);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_unpack(bcmbal_group_member_info *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_action_unpack(&this->action, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_queue_ref_unpack(&this->queue, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_action_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 5))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_bounds_check(const bcmbal_group_member_info *this)
+{
+ if (!bcmbal_action_bounds_check(&this->action))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_queue_ref_bounds_check(&this->queue))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_group_member_info_list_u16_set_default(bcmbal_group_member_info_list_u16 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_list_u16_pack(const bcmbal_group_member_info_list_u16 *this, bcmbal_buf *buf)
+{
+ uint16_t i0;
+ if (!bcmbal_buf_write_u16(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_group_member_info_list_u16\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_group_member_info_pack(&this->val[i0], buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_group_member_info_list_u16_get_packed_length(const bcmbal_group_member_info_list_u16 *this)
+{
+ uint32_t count = 2;
+ uint32_t i0;
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"len\" of struct \"bcmbal_group_member_info_list_u16\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return 0;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ count += bcmbal_group_member_info_get_packed_length(&this->val[i0]);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_list_u16_unpack(bcmbal_group_member_info_list_u16 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint16_t i0;
+ if (!bcmbal_buf_read_u16(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_group_member_info_list_u16\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_group_member_info *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_group_member_info));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_group_member_info_unpack(&this->val[i0], buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_list_u16_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint16_t len;
+ uint16_t i0;
+ if (!bcmbal_buf_read_u16(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_group_member_info) * len);
+ for (i0 = 0; i0 < len; i0++)
+ {
+ if (!bcmbal_group_member_info_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_member_info_list_u16_bounds_check(const bcmbal_group_member_info_list_u16 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_password_set_default(bcmbal_password *this)
+{
+ memset(this->arr, 0, sizeof(this->arr));
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_password_pack(const bcmbal_password *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write(buf, this->arr, 10))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_password_unpack(bcmbal_password *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read(buf, this->arr, 10))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_password_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ (void)extra_mem;
+ return bcmbal_buf_skip(packed, 10);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_password_bounds_check(const bcmbal_password *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_registration_id_set_default(bcmbal_registration_id *this)
+{
+ memset(this->arr, 0, sizeof(this->arr));
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_registration_id_pack(const bcmbal_registration_id *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write(buf, this->arr, 36))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_registration_id_unpack(bcmbal_registration_id *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read(buf, this->arr, 36))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_registration_id_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ (void)extra_mem;
+ return bcmbal_buf_skip(packed, 36);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_registration_id_bounds_check(const bcmbal_registration_id *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_serial_number_set_default(bcmbal_serial_number *this)
+{
+ memset(this->vendor_id, 0, sizeof(this->vendor_id));
+ memset(this->vendor_specific, 0, sizeof(this->vendor_specific));
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_serial_number_pack(const bcmbal_serial_number *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write(buf, this->vendor_id, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write(buf, this->vendor_specific, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_serial_number_unpack(bcmbal_serial_number *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read(buf, this->vendor_id, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read(buf, this->vendor_specific, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_serial_number_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ (void)extra_mem;
+ return bcmbal_buf_skip(packed, 8);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_serial_number_bounds_check(const bcmbal_serial_number *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_service_port_id_list_u8_set_default(bcmbal_service_port_id_list_u8 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_service_port_id_list_u8_pack(const bcmbal_service_port_id_list_u8 *this, bcmbal_buf *buf)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_write_u8(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_service_port_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_service_port_id_list_u8_get_packed_length(const bcmbal_service_port_id_list_u8 *this)
+{
+ return 1 + (2 * this->len);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_service_port_id_list_u8_unpack(bcmbal_service_port_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_read_u8(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_service_port_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_service_port_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_service_port_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_service_port_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint8_t len;
+ if (!bcmbal_buf_read_u8(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_service_port_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 2))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_service_port_id_list_u8_bounds_check(const bcmbal_service_port_id_list_u8 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_sla_set_default(bcmbal_sla *this)
+{
+ this->presence_mask = (bcmbal_sla_id) 0;
+ this->min_rate = 0;
+ this->max_rate = 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_pack(const bcmbal_sla *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_sla_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_write_u32(buf, this->min_rate))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u32(buf, this->max_rate))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_sla_get_packed_length(const bcmbal_sla *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_unpack(bcmbal_sla *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_sla_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->min_rate))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->max_rate))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_sla_id presence_mask;
+ if (!bcmbal_sla_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sla_bounds_check(const bcmbal_sla *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFFFFFCULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_sub_id_list_u16_set_default(bcmbal_sub_id_list_u16 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sub_id_list_u16_pack(const bcmbal_sub_id_list_u16 *this, bcmbal_buf *buf)
+{
+ uint16_t i0;
+ if (!bcmbal_buf_write_u16(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_sub_id_list_u16\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_sub_id_list_u16_get_packed_length(const bcmbal_sub_id_list_u16 *this)
+{
+ return 2 + (4 * this->len);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sub_id_list_u16_unpack(bcmbal_sub_id_list_u16 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint16_t i0;
+ if (!bcmbal_buf_read_u16(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_sub_id_list_u16\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_sub_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_sub_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sub_id_list_u16_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint16_t len;
+ if (!bcmbal_buf_read_u16(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_sub_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_sub_id_list_u16_bounds_check(const bcmbal_sub_id_list_u16 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_red_set_default(bcmbal_tm_red *this)
+{
+ this->min_threshold = (bcmbal_percent) 0;
+ this->max_threshold = (bcmbal_percent) 0;
+ this->max_probability = (bcmbal_percent) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_red_pack(const bcmbal_tm_red *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->min_threshold))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->max_threshold))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->max_probability))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_red_unpack(bcmbal_tm_red *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->min_threshold))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->max_threshold))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->max_probability))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_red_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ (void)extra_mem;
+ return bcmbal_buf_skip(packed, 3);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_red_bounds_check(const bcmbal_tm_red *this)
+{
+ if (this->min_threshold > (bcmbal_percent) 100)
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (this->max_threshold > (bcmbal_percent) 100)
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (this->max_probability > (bcmbal_percent) 100)
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_bac_set_default(bcmbal_tm_bac *this)
+{
+ this->type = (bcmbal_tm_bac_type) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_pack(const bcmbal_tm_bac *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_tm_bac_type_pack(this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ {
+ if (!bcmbal_buf_write_u32(buf, this->u.taildrop.max_size))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ {
+ if (!bcmbal_tm_red_pack(&this->u.red.red, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ {
+ if (!bcmbal_tm_red_pack(&this->u.wred.green, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_pack(&this->u.wred.yellow, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_pack(&this->u.wred.red, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WTAILDROP:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_bac_get_packed_length(const bcmbal_tm_bac *this)
+{
+ uint32_t count = 1;
+ switch (this->type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ {
+ count += 4;
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ {
+ count += 3;
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ {
+ count += 9;
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WTAILDROP:
+ default:
+ break;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_unpack(bcmbal_tm_bac *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_tm_bac_type_unpack(&this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->u.taildrop.max_size))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ {
+ if (!bcmbal_tm_red_unpack(&this->u.red.red, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ {
+ if (!bcmbal_tm_red_unpack(&this->u.wred.green, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_unpack(&this->u.wred.yellow, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_unpack(&this->u.wred.red, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WTAILDROP:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_tm_bac_type type;
+ if (!bcmbal_tm_bac_type_unpack(&type, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ {
+ if (!bcmbal_buf_skip(packed, 3))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ {
+ if (!bcmbal_buf_skip(packed, 3))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 3))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 3))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WTAILDROP:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_bac_bounds_check(const bcmbal_tm_bac *this)
+{
+ switch (this->type)
+ {
+ case BCMBAL_TM_BAC_TYPE_TAILDROP:
+ {
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_RED:
+ {
+ if (!bcmbal_tm_red_bounds_check(&this->u.red.red))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WRED:
+ {
+ if (!bcmbal_tm_red_bounds_check(&this->u.wred.green))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_bounds_check(&this->u.wred.yellow))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_tm_red_bounds_check(&this->u.wred.red))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_BAC_TYPE_WTAILDROP:
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_id_list_u8_set_default(bcmbal_tm_queue_id_list_u8 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_id_list_u8_pack(const bcmbal_tm_queue_id_list_u8 *this, bcmbal_buf *buf)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_write_u8(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_tm_queue_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_queue_id_list_u8_get_packed_length(const bcmbal_tm_queue_id_list_u8 *this)
+{
+ return 1 + this->len;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_id_list_u8_unpack(bcmbal_tm_queue_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_read_u8(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_tm_queue_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_tm_queue_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_tm_queue_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint8_t len;
+ if (!bcmbal_buf_read_u8(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_tm_queue_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 1))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_id_list_u8_bounds_check(const bcmbal_tm_queue_id_list_u8 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_id_list_u8_set_default(bcmbal_tm_sched_id_list_u8 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_id_list_u8_pack(const bcmbal_tm_sched_id_list_u8 *this, bcmbal_buf *buf)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_write_u8(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_tm_sched_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_id_list_u8_get_packed_length(const bcmbal_tm_sched_id_list_u8 *this)
+{
+ return 1 + (4 * this->len);
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_id_list_u8_unpack(bcmbal_tm_sched_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ uint8_t i0;
+ if (!bcmbal_buf_read_u8(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_tm_sched_id_list_u8\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (bcmbal_tm_sched_id *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(bcmbal_tm_sched_id));
+ }
+ }
+
+ for (i0 = 0; i0 < this->len; i0++)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->val[i0]))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint8_t len;
+ if (!bcmbal_buf_read_u8(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(bcmbal_tm_sched_id) * len);
+ if (!bcmbal_buf_skip(packed, len * 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_id_list_u8_bounds_check(const bcmbal_tm_sched_id_list_u8 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_owner_set_default(bcmbal_tm_sched_owner *this)
+{
+ this->type = (bcmbal_tm_sched_owner_type) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_pack(const bcmbal_tm_sched_owner *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_tm_sched_owner_type_pack(this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ if (!bcmbal_intf_type_pack(this->u.interface.intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.interface.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.sub_term.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.sub_term.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ if (!bcmbal_tm_sched_owner_agg_port_id_pack(this->u.agg_port.presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->u.agg_port.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.agg_port.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->u.agg_port.agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ if (!bcmbal_buf_write_u8(buf, this->u.uni.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->u.uni.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write_u8(buf, this->u.uni.idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ {
+ if (!bcmbal_buf_write_u32(buf, this->u.virtual.idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_owner_get_packed_length(const bcmbal_tm_sched_owner *this)
+{
+ uint32_t count = 1;
+ switch (this->type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ count += 8;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ count += 8;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ count += 15;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ count += 6;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ {
+ count += 4;
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED:
+ default:
+ break;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_unpack(bcmbal_tm_sched_owner *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_tm_sched_owner_type_unpack(&this->type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (this->type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ if (!bcmbal_intf_type_unpack(&this->u.interface.intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.interface.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.sub_term.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.sub_term.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ if (!bcmbal_tm_sched_owner_agg_port_id_unpack(&this->u.agg_port.presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->u.agg_port.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.agg_port.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->u.agg_port.presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->u.agg_port.agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->u.uni.intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->u.uni.sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_read_u8(buf, &this->u.uni.idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->u.virtual.idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_tm_sched_owner_type type;
+ if (!bcmbal_tm_sched_owner_type_unpack(&type, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ switch (type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ bcmbal_tm_sched_owner_agg_port_id presence_mask;
+ if (!bcmbal_tm_sched_owner_agg_port_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED:
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_owner_bounds_check(const bcmbal_tm_sched_owner *this)
+{
+ switch (this->type)
+ {
+ case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
+ {
+ switch (this->u.interface.intf_type)
+ {
+ case BCMBAL_INTF_TYPE_NNI:
+ break;
+ case BCMBAL_INTF_TYPE_PON:
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
+ {
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
+ {
+ if ((this->u.agg_port.presence_mask & 0xFFFFFFFFFFFFFFF8ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
+ {
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
+ {
+ }
+ break;
+ case BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED:
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_parent_set_default(bcmbal_tm_sched_parent *this)
+{
+ this->presence_mask = (bcmbal_tm_sched_parent_id) 0;
+ this->sched_id = (bcmbal_tm_sched_id) 0;
+ this->priority = (bcmbal_tm_priority) 0;
+ this->weight = (bcmbal_tm_weight) 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_pack(const bcmbal_tm_sched_parent *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_tm_sched_parent_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->weight))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_parent_get_packed_length(const bcmbal_tm_sched_parent *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_unpack(bcmbal_tm_sched_parent *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_tm_sched_parent_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->weight))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_tm_sched_parent_id presence_mask;
+ if (!bcmbal_tm_sched_parent_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_parent_bounds_check(const bcmbal_tm_sched_parent *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFFFFF8ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_shaping_set_default(bcmbal_tm_shaping *this)
+{
+ this->presence_mask = (bcmbal_tm_shaping_id) 0;
+ this->sbr = 0;
+ this->pbr = 0;
+ this->burst = 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_pack(const bcmbal_tm_shaping *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_tm_shaping_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_write_u32(buf, this->sbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u32(buf, this->pbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u32(buf, this->burst))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_shaping_get_packed_length(const bcmbal_tm_shaping *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 4;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_unpack(bcmbal_tm_shaping *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_tm_shaping_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->sbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->pbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->burst))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_tm_shaping_id presence_mask;
+ if (!bcmbal_tm_shaping_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_shaping_bounds_check(const bcmbal_tm_shaping *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFFFFF8ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_tcont_sla_set_default(bcmbal_tm_tcont_sla *this)
+{
+ this->presence_mask = (bcmbal_tm_tcont_sla_id) 0;
+ this->extra_bw_elig = BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NONE;
+ this->nrt_cbr = 0;
+ this->rt_cbr = 0;
+ this->rt_profile = 0;
+ this->nrt_profile = 0;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_pack(const bcmbal_tm_tcont_sla *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_tm_tcont_sla_id_pack(this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_extra_bw_eligibility_type_pack(this->extra_bw_elig, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->nrt_cbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->rt_cbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->rt_profile))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_write_u8(buf, this->nrt_profile))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_tcont_sla_get_packed_length(const bcmbal_tm_tcont_sla *this)
+{
+ uint32_t count = 8;
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ count += 1;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_unpack(bcmbal_tm_tcont_sla *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_tm_tcont_sla_id_unpack(&this->presence_mask, buf))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_extra_bw_eligibility_type_unpack(&this->extra_bw_elig, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->nrt_cbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->rt_cbr))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->rt_profile))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->nrt_profile))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ bcmbal_tm_tcont_sla_id presence_mask;
+ if (!bcmbal_tm_tcont_sla_id_unpack(&presence_mask, packed))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) presence_mask & 0x0001) == 0x0001))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0002) == 0x0002))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0004) == 0x0004))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0008) == 0x0008))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((((uint64_t) presence_mask & 0x0010) == 0x0010))
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_tcont_sla_bounds_check(const bcmbal_tm_tcont_sla *this)
+{
+ if ((this->presence_mask & 0xFFFFFFFFFFFFFFE0ULL) != 0)
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((((uint64_t) this->presence_mask & 0x0001) == 0x0001))
+ {
+ switch (this->extra_bw_elig)
+ {
+ case BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NONE:
+ break;
+ case BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NOT_ASSURED:
+ break;
+ case BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_BEST_EFFORT:
+ break;
+ default:
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_u8_list_u32_set_default(bcmbal_u8_list_u32 *this)
+{
+ this->len = 0;
+ this->val = NULL;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_u8_list_u32_pack(const bcmbal_u8_list_u32 *this, bcmbal_buf *buf)
+{
+ if (!bcmbal_buf_write_u32(buf, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_u8_list_u32\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+
+ if (!bcmbal_buf_write(buf, this->val, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_u8_list_u32_get_packed_length(const bcmbal_u8_list_u32 *this)
+{
+ return 4 + this->len;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_u8_list_u32_unpack(bcmbal_u8_list_u32 *this, bcmbal_buf *buf, void **extra_mem)
+{
+ if (!bcmbal_buf_read_u32(buf, &this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ if ((this->len > 0) && (this->val == NULL))
+ {
+ if (extra_mem == NULL)
+ {
+ bcmos_trace(BCMOS_TRACE_LEVEL_ERROR, "Error: list field \"val\" of struct \"bcmbal_u8_list_u32\" is uninitialized (NULL). You must allocate memory for this pointer before sending/receiving the message.\n");
+ return BCMOS_FALSE;
+ }
+ else
+ {
+ this->val = (uint8_t *) *extra_mem;
+ *extra_mem = ((uint8_t *) *extra_mem) + BCMOS_ROUND_TO_WORD(this->len * sizeof(uint8_t));
+ }
+ }
+
+ if (!bcmbal_buf_read(buf, this->val, this->len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_u8_list_u32_scan(bcmbal_buf *packed, uint32_t *extra_mem)
+{
+ uint32_t len;
+ if (!bcmbal_buf_read_u32(packed, &len))
+ {
+ return BCMOS_FALSE;
+ }
+
+ *extra_mem += BCMOS_ROUND_TO_WORD(sizeof(uint8_t) * len);
+ if (!bcmbal_buf_skip(packed, len * 1))
+ {
+ return BCMOS_FALSE;
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_u8_list_u32_bounds_check(const bcmbal_u8_list_u32 *this)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_access_terminal_key_set_default(bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ this->access_term_id = (bcmbal_access_id) 1;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_pack(const bcmbal_access_terminal_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->access_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_access_terminal_key_get_packed_length(const bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_unpack(bcmbal_access_terminal_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->access_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_key_bounds_check(const bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID)) != 0)
+ {
+ if (this->access_term_id < (bcmbal_access_id) 1)
+ {
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID;
+ return BCMOS_FALSE;
+ }
+
+ if (this->access_term_id > (bcmbal_access_id) 1)
+ {
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_KEY_ID_ACCESS_TERM_ID;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_access_terminal_cfg_data_set_default(bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ this->iwf_mode = BCMBAL_IWF_MODE_DIRECT_MAPPING;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_data_pack(const bcmbal_access_terminal_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_iwf_mode_pack(this->iwf_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_access_terminal_cfg_data_get_packed_length(const bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_data_unpack(bcmbal_access_terminal_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_iwf_mode_unpack(&this->iwf_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_cfg_data_bounds_check(const bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_CFG_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE)) != 0)
+ {
+ switch (this->iwf_mode)
+ {
+ case BCMBAL_IWF_MODE_DIRECT_MAPPING:
+ break;
+ case BCMBAL_IWF_MODE_PER_FLOW:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_access_terminal_ind_data_set_default(bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ this->iwf_mode = BCMBAL_IWF_MODE_DIRECT_MAPPING;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_data_pack(const bcmbal_access_terminal_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_iwf_mode_pack(this->iwf_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_access_terminal_ind_data_get_packed_length(const bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_data_unpack(bcmbal_access_terminal_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_iwf_mode_unpack(&this->iwf_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_access_terminal_ind_data_bounds_check(const bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_ind_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_IND_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_IND_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE)) != 0)
+ {
+ switch (this->iwf_mode)
+ {
+ case BCMBAL_IWF_MODE_DIRECT_MAPPING:
+ break;
+ case BCMBAL_IWF_MODE_PER_FLOW:
+ break;
+ default:
+ *failed_prop = BCMBAL_ACCESS_TERMINAL_IND_ID_IWF_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_flow_key_set_default(bcmbal_flow_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_ID)) != 0)
+ {
+ this->flow_id = (bcmbal_flow_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ this->flow_type = (bcmbal_flow_type) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_pack(const bcmbal_flow_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_pack(this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_flow_key_get_packed_length(const bcmbal_flow_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_unpack(bcmbal_flow_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_unpack(&this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_key_bounds_check(const bcmbal_flow_key *this, bcmbal_presence_mask fields_present, bcmbal_flow_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_KEY_ID_FLOW_TYPE)) != 0)
+ {
+ switch (this->flow_type)
+ {
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ break;
+ case BCMBAL_FLOW_TYPE_MULTICAST:
+ break;
+ default:
+ *failed_prop = BCMBAL_FLOW_KEY_ID_FLOW_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_flow_cfg_data_set_default(bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID)) != 0)
+ {
+ this->access_int_id = (bcmbal_intf_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID)) != 0)
+ {
+ this->network_int_id = (bcmbal_intf_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_ID)) != 0)
+ {
+ this->sub_term_id = (bcmbal_sub_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX)) != 0)
+ {
+ this->sub_term_uni_idx = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ this->svc_port_id = (bcmbal_service_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_AGG_PORT_ID)) != 0)
+ {
+ this->agg_port_id = (bcmbal_aggregation_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_RESOLVE_MAC)) != 0)
+ {
+ this->resolve_mac = BCMOS_FALSE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ this->classifier.presence_mask = (bcmbal_classifier_id) 0;
+ this->classifier.o_tpid = 0;
+ this->classifier.o_vid = 0;
+ this->classifier.i_tpid = 0;
+ this->classifier.i_vid = 0;
+ this->classifier.o_pbits = 0;
+ this->classifier.i_pbits = 0;
+ this->classifier.ether_type = 0;
+ bcmos_mac_address_init(&this->classifier.dst_mac);
+ bcmos_mac_address_init(&this->classifier.src_mac);
+ this->classifier.ip_proto = 0;
+ bcmos_ipv4_address_init(&this->classifier.dst_ip);
+ bcmos_ipv4_address_init(&this->classifier.src_ip);
+ this->classifier.src_port = 0;
+ this->classifier.dst_port = 0;
+ this->classifier.pkt_tag_type = (bcmbal_pkt_tag_type) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ this->action.presence_mask = (bcmbal_action_id) 0;
+ this->action.cmds_bitmask = (bcmbal_action_cmd_id) 0;
+ this->action.o_vid = 0;
+ this->action.o_pbits = 0;
+ this->action.o_tpid = 0;
+ this->action.i_vid = 0;
+ this->action.i_pbits = 0;
+ this->action.i_tpid = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ this->sla.presence_mask = (bcmbal_sla_id) 0;
+ this->sla.min_rate = 0;
+ this->sla.max_rate = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_COOKIE)) != 0)
+ {
+ this->cookie = (bcmbal_cookie) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ this->priority = 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_GROUP_ID)) != 0)
+ {
+ this->group_id = (bcmbal_group_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ this->queue.sched_id = (bcmbal_tm_sched_id) 0;
+ this->queue.queue_id = (bcmbal_tm_queue_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_data_pack(const bcmbal_flow_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->access_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->network_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, this->sub_term_uni_idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_write_bool(buf, this->resolve_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_pack(&this->classifier, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_pack(&this->action, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_pack(&this->sla, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, (uint64_t) this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->group_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ if (!bcmbal_tm_queue_ref_pack(&this->queue, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_flow_cfg_data_get_packed_length(const bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_AGG_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_RESOLVE_MAC)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ count += bcmbal_classifier_get_packed_length(&this->classifier);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ count += bcmbal_action_get_packed_length(&this->action);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ count += bcmbal_sla_get_packed_length(&this->sla);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_COOKIE)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_GROUP_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ count += 5;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_data_unpack(bcmbal_flow_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->access_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->network_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->sub_term_uni_idx))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_read_bool(buf, &this->resolve_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_unpack(&this->classifier, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_unpack(&this->action, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_unpack(&this->sla, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, (uint64_t *) &this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->group_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ if (!bcmbal_tm_queue_ref_unpack(&this->queue, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SUB_TERM_UNI_IDX)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 5))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_cfg_data_bounds_check(const bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_FLOW_CFG_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_FLOW_CFG_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_bounds_check(&this->classifier))
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_CLASSIFIER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_bounds_check(&this->action))
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_ACTION;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_bounds_check(&this->sla))
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_SLA;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_PRIORITY)) != 0)
+ {
+ if (this->priority < 1)
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_PRIORITY;
+ return BCMOS_FALSE;
+ }
+
+ if (this->priority > 255)
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_PRIORITY;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_CFG_ID_QUEUE)) != 0)
+ {
+ if (!bcmbal_tm_queue_ref_bounds_check(&this->queue))
+ {
+ *failed_prop = BCMBAL_FLOW_CFG_ID_QUEUE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_flow_stat_data_set_default(bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_PACKETS)) != 0)
+ {
+ this->rx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_BYTES)) != 0)
+ {
+ this->rx_bytes = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_PACKETS)) != 0)
+ {
+ this->tx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_BYTES)) != 0)
+ {
+ this->tx_bytes = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_data_pack(const bcmbal_flow_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_flow_stat_data_get_packed_length(const bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_data_unpack(bcmbal_flow_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_stat_data_bounds_check(const bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_stat_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_flow_ind_data_set_default(bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACCESS_INT_ID)) != 0)
+ {
+ this->access_int_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_NETWORK_INT_ID)) != 0)
+ {
+ this->network_int_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SUB_TERM_ID)) != 0)
+ {
+ this->sub_term_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ this->svc_port_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_AGG_PORT_ID)) != 0)
+ {
+ this->agg_port_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_RESOLVE_MAC)) != 0)
+ {
+ this->resolve_mac = BCMOS_FALSE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_BASE_TC_ID)) != 0)
+ {
+ this->base_tc_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ this->classifier.presence_mask = (bcmbal_classifier_id) 0;
+ this->classifier.o_tpid = 0;
+ this->classifier.o_vid = 0;
+ this->classifier.i_tpid = 0;
+ this->classifier.i_vid = 0;
+ this->classifier.o_pbits = 0;
+ this->classifier.i_pbits = 0;
+ this->classifier.ether_type = 0;
+ bcmos_mac_address_init(&this->classifier.dst_mac);
+ bcmos_mac_address_init(&this->classifier.src_mac);
+ this->classifier.ip_proto = 0;
+ bcmos_ipv4_address_init(&this->classifier.dst_ip);
+ bcmos_ipv4_address_init(&this->classifier.src_ip);
+ this->classifier.src_port = 0;
+ this->classifier.dst_port = 0;
+ this->classifier.pkt_tag_type = (bcmbal_pkt_tag_type) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ this->action.presence_mask = (bcmbal_action_id) 0;
+ this->action.cmds_bitmask = (bcmbal_action_cmd_id) 0;
+ this->action.o_vid = 0;
+ this->action.o_pbits = 0;
+ this->action.o_tpid = 0;
+ this->action.i_vid = 0;
+ this->action.i_pbits = 0;
+ this->action.i_tpid = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ this->sla.presence_mask = (bcmbal_sla_id) 0;
+ this->sla.min_rate = 0;
+ this->sla.max_rate = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_COOKIE)) != 0)
+ {
+ this->cookie = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ this->priority = 1;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_data_pack(const bcmbal_flow_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->access_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->network_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_write_bool(buf, this->resolve_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_BASE_TC_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->base_tc_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_pack(&this->classifier, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_pack(&this->action, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_pack(&this->sla, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_flow_ind_data_get_packed_length(const bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACCESS_INT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_NETWORK_INT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SUB_TERM_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_AGG_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_RESOLVE_MAC)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_BASE_TC_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ count += bcmbal_classifier_get_packed_length(&this->classifier);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ count += bcmbal_action_get_packed_length(&this->action);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ count += bcmbal_sla_get_packed_length(&this->sla);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_COOKIE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ count += 2;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_data_unpack(bcmbal_flow_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->access_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->network_int_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_read_bool(buf, &this->resolve_mac))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_BASE_TC_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->base_tc_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_unpack(&this->classifier, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_unpack(&this->action, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_unpack(&this->sla, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACCESS_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_NETWORK_INT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_RESOLVE_MAC)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_BASE_TC_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_flow_ind_data_bounds_check(const bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_ind_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_FLOW_IND_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_FLOW_IND_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_CLASSIFIER)) != 0)
+ {
+ if (!bcmbal_classifier_bounds_check(&this->classifier))
+ {
+ *failed_prop = BCMBAL_FLOW_IND_ID_CLASSIFIER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_ACTION)) != 0)
+ {
+ if (!bcmbal_action_bounds_check(&this->action))
+ {
+ *failed_prop = BCMBAL_FLOW_IND_ID_ACTION;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_SLA)) != 0)
+ {
+ if (!bcmbal_sla_bounds_check(&this->sla))
+ {
+ *failed_prop = BCMBAL_FLOW_IND_ID_SLA;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_FLOW_IND_ID_PRIORITY)) != 0)
+ {
+ if (this->priority < 1)
+ {
+ *failed_prop = BCMBAL_FLOW_IND_ID_PRIORITY;
+ return BCMOS_FALSE;
+ }
+
+ if (this->priority > 255)
+ {
+ *failed_prop = BCMBAL_FLOW_IND_ID_PRIORITY;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_group_key_set_default(bcmbal_group_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_KEY_ID_GROUP_ID)) != 0)
+ {
+ this->group_id = (bcmbal_group_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_pack(const bcmbal_group_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_KEY_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->group_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_group_key_get_packed_length(const bcmbal_group_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_GROUP_KEY_ID_GROUP_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_unpack(bcmbal_group_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_KEY_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->group_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_KEY_ID_GROUP_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_key_bounds_check(const bcmbal_group_key *this, bcmbal_presence_mask fields_present, bcmbal_group_key_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_group_cfg_data_set_default(bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ this->members_cmd = (bcmbal_group_member_cmd) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ this->members.len = 0;
+ this->members.val = NULL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_COOKIE)) != 0)
+ {
+ this->cookie = (bcmbal_cookie) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ this->flows.len = 0;
+ this->flows.val = NULL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ this->owner = BCMBAL_GROUP_OWNER_NONE;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_data_pack(const bcmbal_group_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ if (!bcmbal_group_member_cmd_pack(this->members_cmd, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ if (!bcmbal_group_member_info_list_u16_pack(&this->members, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, (uint64_t) this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ if (!bcmbal_flow_id_list_u32_pack(&this->flows, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_group_owner_pack(this->owner, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_group_cfg_data_get_packed_length(const bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ count += bcmbal_group_member_info_list_u16_get_packed_length(&this->members);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_COOKIE)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ count += bcmbal_flow_id_list_u32_get_packed_length(&this->flows);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_data_unpack(bcmbal_group_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ if (!bcmbal_group_member_cmd_unpack(&this->members_cmd, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ if (!bcmbal_group_member_info_list_u16_unpack(&this->members, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, (uint64_t *) &this->cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ if (!bcmbal_flow_id_list_u32_unpack(&this->flows, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_group_owner_unpack(&this->owner, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ if (!bcmbal_group_member_info_list_u16_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ if (!bcmbal_flow_id_list_u32_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_group_cfg_data_bounds_check(const bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_group_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS_CMD)) != 0)
+ {
+ switch (this->members_cmd)
+ {
+ case BCMBAL_GROUP_MEMBER_CMD_ADD_MEMBERS:
+ break;
+ case BCMBAL_GROUP_MEMBER_CMD_REM_MEMBERS:
+ break;
+ case BCMBAL_GROUP_MEMBER_CMD_SET_MEMBERS:
+ break;
+ default:
+ *failed_prop = BCMBAL_GROUP_CFG_ID_MEMBERS_CMD;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_MEMBERS)) != 0)
+ {
+ if (!bcmbal_group_member_info_list_u16_bounds_check(&this->members))
+ {
+ *failed_prop = BCMBAL_GROUP_CFG_ID_MEMBERS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS)) != 0)
+ {
+ if (!bcmbal_flow_id_list_u32_bounds_check(&this->flows))
+ {
+ *failed_prop = BCMBAL_GROUP_CFG_ID_FLOWS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_GROUP_CFG_ID_OWNER)) != 0)
+ {
+ switch (this->owner)
+ {
+ case BCMBAL_GROUP_OWNER_NONE:
+ break;
+ case BCMBAL_GROUP_OWNER_MULTICAST:
+ break;
+ case BCMBAL_GROUP_OWNER_UNICAST:
+ break;
+ default:
+ *failed_prop = BCMBAL_GROUP_CFG_ID_OWNER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_interface_key_set_default(bcmbal_interface_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_ID)) != 0)
+ {
+ this->intf_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ this->intf_type = BCMBAL_INTF_TYPE_NNI;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_pack(const bcmbal_interface_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_pack(this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_interface_key_get_packed_length(const bcmbal_interface_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_unpack(bcmbal_interface_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_unpack(&this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_key_bounds_check(const bcmbal_interface_key *this, bcmbal_presence_mask fields_present, bcmbal_interface_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_KEY_ID_INTF_TYPE)) != 0)
+ {
+ switch (this->intf_type)
+ {
+ case BCMBAL_INTF_TYPE_NNI:
+ break;
+ case BCMBAL_INTF_TYPE_PON:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_KEY_ID_INTF_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_interface_cfg_data_set_default(bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ this->min_data_agg_port_id = (bcmbal_aggregation_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ this->min_data_svc_port_id = (bcmbal_service_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ this->transceiver_type = BCMBAL_TRX_TYPE_GPON_SPS_43_48;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ this->ds_miss_mode = BCMBAL_DS_MISS_MODE_DISCARD;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MTU)) != 0)
+ {
+ this->mtu = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ this->flow_control = BCMBAL_CONTROL_DISABLE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_TM)) != 0)
+ {
+ this->ds_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_US_TM)) != 0)
+ {
+ this->us_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ this->sub_term_id_list.len = 0;
+ this->sub_term_id_list.val = NULL;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_data_pack(const bcmbal_interface_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->min_data_agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->min_data_svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_trx_type_pack(this->transceiver_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_ds_miss_mode_pack(this->ds_miss_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->mtu))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_control_pack(this->flow_control, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ if (!bcmbal_sub_id_list_u16_pack(&this->sub_term_id_list, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_interface_cfg_data_get_packed_length(const bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MTU)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_US_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ count += bcmbal_sub_id_list_u16_get_packed_length(&this->sub_term_id_list);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_data_unpack(bcmbal_interface_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->min_data_agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->min_data_svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_trx_type_unpack(&this->transceiver_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_ds_miss_mode_unpack(&this->ds_miss_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->mtu))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_control_unpack(&this->flow_control, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ if (!bcmbal_sub_id_list_u16_unpack(&this->sub_term_id_list, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ if (!bcmbal_sub_id_list_u16_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_cfg_data_bounds_check(const bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ switch (this->transceiver_type)
+ {
+ case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_TRANSCEIVER_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE)) != 0)
+ {
+ switch (this->ds_miss_mode)
+ {
+ case BCMBAL_DS_MISS_MODE_DISCARD:
+ break;
+ case BCMBAL_DS_MISS_MODE_BROADCAST:
+ break;
+ case BCMBAL_DS_MISS_MODE_VID:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_DS_MISS_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL)) != 0)
+ {
+ switch (this->flow_control)
+ {
+ case BCMBAL_CONTROL_DISABLE:
+ break;
+ case BCMBAL_CONTROL_ENABLE:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_FLOW_CONTROL;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST)) != 0)
+ {
+ if (!bcmbal_sub_id_list_u16_bounds_check(&this->sub_term_id_list))
+ {
+ *failed_prop = BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_interface_stat_data_set_default(bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_PACKETS)) != 0)
+ {
+ this->rx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_BYTES)) != 0)
+ {
+ this->rx_bytes = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_PACKETS)) != 0)
+ {
+ this->tx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_BYTES)) != 0)
+ {
+ this->tx_bytes = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_data_pack(const bcmbal_interface_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_interface_stat_data_get_packed_length(const bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_data_unpack(bcmbal_interface_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_stat_data_bounds_check(const bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_stat_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_interface_ind_data_set_default(bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ this->min_data_agg_port_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ this->min_data_svc_port_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ this->transceiver_type = BCMBAL_TRX_TYPE_GPON_SPS_43_48;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ this->ds_miss_mode = BCMBAL_DS_MISS_MODE_DISCARD;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MTU)) != 0)
+ {
+ this->mtu = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ this->flow_control = BCMBAL_CONTROL_DISABLE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_TM)) != 0)
+ {
+ this->ds_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_US_TM)) != 0)
+ {
+ this->us_tm = (bcmbal_tm_sched_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_data_pack(const bcmbal_interface_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->min_data_agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->min_data_svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_trx_type_pack(this->transceiver_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_ds_miss_mode_pack(this->ds_miss_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->mtu))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_control_pack(this->flow_control, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_interface_ind_data_get_packed_length(const bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MTU)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_US_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_data_unpack(bcmbal_interface_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->min_data_agg_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->min_data_svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_trx_type_unpack(&this->transceiver_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_ds_miss_mode_unpack(&this->ds_miss_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->mtu))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_control_unpack(&this->flow_control, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_AGG_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MIN_DATA_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_MTU)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_interface_ind_data_bounds_check(const bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_ind_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_IND_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_IND_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE)) != 0)
+ {
+ switch (this->transceiver_type)
+ {
+ case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
+ break;
+ case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC:
+ break;
+ case BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_IND_ID_TRANSCEIVER_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE)) != 0)
+ {
+ switch (this->ds_miss_mode)
+ {
+ case BCMBAL_DS_MISS_MODE_DISCARD:
+ break;
+ case BCMBAL_DS_MISS_MODE_BROADCAST:
+ break;
+ case BCMBAL_DS_MISS_MODE_VID:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_IND_ID_DS_MISS_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL)) != 0)
+ {
+ switch (this->flow_control)
+ {
+ case BCMBAL_CONTROL_DISABLE:
+ break;
+ case BCMBAL_CONTROL_ENABLE:
+ break;
+ default:
+ *failed_prop = BCMBAL_INTERFACE_IND_ID_FLOW_CONTROL;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_packet_key_set_default(bcmbal_packet_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_RESERVED)) != 0)
+ {
+ this->reserved = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ this->packet_send_dest.type = (bcmbal_dest_type) 0;
+ this->packet_send_dest.u.nni.int_id = (bcmbal_intf_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_pack(const bcmbal_packet_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_RESERVED)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->reserved))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ if (!bcmbal_dest_pack(&this->packet_send_dest, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_packet_key_get_packed_length(const bcmbal_packet_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_RESERVED)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ count += bcmbal_dest_get_packed_length(&this->packet_send_dest);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_unpack(bcmbal_packet_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_RESERVED)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->reserved))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ if (!bcmbal_dest_unpack(&this->packet_send_dest, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_RESERVED)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ if (!bcmbal_dest_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_key_bounds_check(const bcmbal_packet_key *this, bcmbal_presence_mask fields_present, bcmbal_packet_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST)) != 0)
+ {
+ if (!bcmbal_dest_bounds_check(&this->packet_send_dest))
+ {
+ *failed_prop = BCMBAL_PACKET_KEY_ID_PACKET_SEND_DEST;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_packet_cfg_data_set_default(bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_ID)) != 0)
+ {
+ this->flow_id = (bcmbal_flow_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ this->flow_type = (bcmbal_flow_type) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_ID)) != 0)
+ {
+ this->intf_id = (bcmbal_intf_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ this->intf_type = BCMBAL_INTF_TYPE_NNI;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_SVC_PORT)) != 0)
+ {
+ this->svc_port = (bcmbal_service_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_COOKIE)) != 0)
+ {
+ this->flow_cookie = (bcmbal_cookie) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ this->pkt.len = 0;
+ this->pkt.val = NULL;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_data_pack(const bcmbal_packet_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_pack(this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_pack(this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->svc_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, (uint64_t) this->flow_cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_pack(&this->pkt, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_packet_cfg_data_get_packed_length(const bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_SVC_PORT)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_COOKIE)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ count += bcmbal_u8_list_u32_get_packed_length(&this->pkt);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_data_unpack(bcmbal_packet_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_unpack(&this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_unpack(&this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->svc_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, (uint64_t *) &this->flow_cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_unpack(&this->pkt, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_cfg_data_bounds_check(const bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_packet_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_FLOW_TYPE)) != 0)
+ {
+ switch (this->flow_type)
+ {
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ break;
+ case BCMBAL_FLOW_TYPE_MULTICAST:
+ break;
+ default:
+ *failed_prop = BCMBAL_PACKET_CFG_ID_FLOW_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_INTF_TYPE)) != 0)
+ {
+ switch (this->intf_type)
+ {
+ case BCMBAL_INTF_TYPE_NNI:
+ break;
+ case BCMBAL_INTF_TYPE_PON:
+ break;
+ default:
+ *failed_prop = BCMBAL_PACKET_CFG_ID_INTF_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_CFG_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_bounds_check(&this->pkt))
+ {
+ *failed_prop = BCMBAL_PACKET_CFG_ID_PKT;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_packet_ind_data_set_default(bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_ID)) != 0)
+ {
+ this->flow_id = (bcmbal_flow_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ this->flow_type = (bcmbal_flow_type) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_ID)) != 0)
+ {
+ this->intf_id = (bcmbal_intf_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ this->intf_type = BCMBAL_INTF_TYPE_NNI;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_SVC_PORT)) != 0)
+ {
+ this->svc_port = (bcmbal_service_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_COOKIE)) != 0)
+ {
+ this->flow_cookie = (bcmbal_cookie) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ this->pkt.len = 0;
+ this->pkt.val = NULL;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_data_pack(const bcmbal_packet_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_pack(this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_pack(this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->svc_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, (uint64_t) this->flow_cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_pack(&this->pkt, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_packet_ind_data_get_packed_length(const bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_SVC_PORT)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_COOKIE)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ count += bcmbal_u8_list_u32_get_packed_length(&this->pkt);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_data_unpack(bcmbal_packet_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->flow_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_flow_type_unpack(&this->flow_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_intf_type_unpack(&this->intf_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->svc_port))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, (uint64_t *) &this->flow_cookie))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_unpack(&this->pkt, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_SVC_PORT)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_COOKIE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_packet_ind_data_bounds_check(const bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_packet_ind_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_FLOW_TYPE)) != 0)
+ {
+ switch (this->flow_type)
+ {
+ case BCMBAL_FLOW_TYPE_UPSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_DOWNSTREAM:
+ break;
+ case BCMBAL_FLOW_TYPE_BROADCAST:
+ break;
+ case BCMBAL_FLOW_TYPE_MULTICAST:
+ break;
+ default:
+ *failed_prop = BCMBAL_PACKET_IND_ID_FLOW_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_INTF_TYPE)) != 0)
+ {
+ switch (this->intf_type)
+ {
+ case BCMBAL_INTF_TYPE_NNI:
+ break;
+ case BCMBAL_INTF_TYPE_PON:
+ break;
+ default:
+ *failed_prop = BCMBAL_PACKET_IND_ID_INTF_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_PACKET_IND_ID_PKT)) != 0)
+ {
+ if (!bcmbal_u8_list_u32_bounds_check(&this->pkt))
+ {
+ *failed_prop = BCMBAL_PACKET_IND_ID_PKT;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_subscriber_terminal_key_set_default(bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID)) != 0)
+ {
+ this->sub_term_id = (bcmbal_sub_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID)) != 0)
+ {
+ this->intf_id = (bcmbal_intf_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_pack(const bcmbal_subscriber_terminal_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_subscriber_terminal_key_get_packed_length(const bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_unpack(bcmbal_subscriber_terminal_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->sub_term_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->intf_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_SUB_TERM_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_KEY_ID_INTF_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_key_bounds_check(const bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_key_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_subscriber_terminal_cfg_data_set_default(bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ memset(this->serial_number.vendor_id, 0, sizeof(this->serial_number.vendor_id));
+ memset(this->serial_number.vendor_specific, 0, sizeof(this->serial_number.vendor_specific));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ memset(this->password.arr, 0, sizeof(this->password.arr));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ memset(this->registration_id.arr, 0, sizeof(this->registration_id.arr));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ this->svc_port_id = (bcmbal_service_port_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS)) != 0)
+ {
+ bcmos_mac_address_init(&this->mac_address);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM)) != 0)
+ {
+ this->ds_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM)) != 0)
+ {
+ this->us_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ this->svc_port_id_list.len = 0;
+ this->svc_port_id_list.val = NULL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ this->agg_port_id_list.len = 0;
+ this->agg_port_id_list.val = NULL;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_pack(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_pack(&this->serial_number, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_pack(&this->password, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_pack(&this->registration_id, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, (uint16_t) this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_write_mac_address(buf, this->mac_address))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_service_port_id_list_u8_pack(&this->svc_port_id_list, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_aggregation_port_id_list_u8_pack(&this->agg_port_id_list, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_subscriber_terminal_cfg_data_get_packed_length(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ count += 10;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ count += 36;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS)) != 0)
+ {
+ count += 6;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ count += bcmbal_service_port_id_list_u8_get_packed_length(&this->svc_port_id_list);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ count += bcmbal_aggregation_port_id_list_u8_get_packed_length(&this->agg_port_id_list);
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_unpack(bcmbal_subscriber_terminal_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_unpack(&this->serial_number, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_unpack(&this->password, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_unpack(&this->registration_id, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, (uint16_t *) &this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_read_mac_address(buf, &this->mac_address))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_service_port_id_list_u8_unpack(&this->svc_port_id_list, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_aggregation_port_id_list_u8_unpack(&this->agg_port_id_list, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 10))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 36))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 6))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_service_port_id_list_u8_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_aggregation_port_id_list_u8_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_bounds_check(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_bounds_check(&this->serial_number))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SERIAL_NUMBER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_bounds_check(&this->password))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_PASSWORD;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_bounds_check(&this->registration_id))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_REGISTRATION_ID;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_service_port_id_list_u8_bounds_check(&this->svc_port_id_list))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST)) != 0)
+ {
+ if (!bcmbal_aggregation_port_id_list_u8_bounds_check(&this->agg_port_id_list))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_subscriber_terminal_stat_data_set_default(bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS)) != 0)
+ {
+ this->rx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES)) != 0)
+ {
+ this->rx_bytes = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS)) != 0)
+ {
+ this->tx_packets = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES)) != 0)
+ {
+ this->tx_bytes = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_data_pack(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_subscriber_terminal_stat_data_get_packed_length(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES)) != 0)
+ {
+ count += 8;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_data_unpack(bcmbal_subscriber_terminal_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->rx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_packets))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->tx_bytes))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_RX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_PACKETS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_STAT_ID_TX_BYTES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_stat_data_bounds_check(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_stat_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_subscriber_terminal_ind_data_set_default(bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ this->admin_state = (bcmbal_state) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ this->oper_status = (bcmbal_status) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ memset(this->serial_number.vendor_id, 0, sizeof(this->serial_number.vendor_id));
+ memset(this->serial_number.vendor_specific, 0, sizeof(this->serial_number.vendor_specific));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ memset(this->password.arr, 0, sizeof(this->password.arr));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ memset(this->registration_id.arr, 0, sizeof(this->registration_id.arr));
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ this->svc_port_id = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS)) != 0)
+ {
+ bcmos_mac_address_init(&this->mac_address);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM)) != 0)
+ {
+ this->ds_tm = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM)) != 0)
+ {
+ this->us_tm = (bcmbal_tm_sched_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_data_pack(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_pack(this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_pack(this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_pack(&this->serial_number, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_pack(&this->password, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_pack(&this->registration_id, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u16(buf, this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_write_mac_address(buf, this->mac_address))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_subscriber_terminal_ind_data_get_packed_length(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ count += 10;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ count += 36;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ count += 2;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS)) != 0)
+ {
+ count += 6;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_data_unpack(bcmbal_subscriber_terminal_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_state_unpack(&this->admin_state, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_status_unpack(&this->oper_status, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_unpack(&this->serial_number, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_unpack(&this->password, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_unpack(&this->registration_id, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u16(buf, &this->svc_port_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_read_mac_address(buf, &this->mac_address))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->ds_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->us_tm))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 10))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 36))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SVC_PORT_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 2))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_MAC_ADDRESS)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 6))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_DS_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_US_TM)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_subscriber_terminal_ind_data_bounds_check(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_ind_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE)) != 0)
+ {
+ switch (this->admin_state)
+ {
+ case BCMBAL_STATE_UP:
+ break;
+ case BCMBAL_STATE_DOWN:
+ break;
+ case BCMBAL_STATE_TESTING:
+ break;
+ default:
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_ADMIN_STATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS)) != 0)
+ {
+ switch (this->oper_status)
+ {
+ case BCMBAL_STATUS_UP:
+ break;
+ case BCMBAL_STATUS_DOWN:
+ break;
+ case BCMBAL_STATUS_TESTING:
+ break;
+ case BCMBAL_STATUS_NOT_PRESENT:
+ break;
+ case BCMBAL_STATUS_LOWER_LAYER_DOWN:
+ break;
+ case BCMBAL_STATUS_UNKNOWN:
+ break;
+ default:
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_OPER_STATUS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER)) != 0)
+ {
+ if (!bcmbal_serial_number_bounds_check(&this->serial_number))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_SERIAL_NUMBER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD)) != 0)
+ {
+ if (!bcmbal_password_bounds_check(&this->password))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_PASSWORD;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID)) != 0)
+ {
+ if (!bcmbal_registration_id_bounds_check(&this->registration_id))
+ {
+ *failed_prop = BCMBAL_SUBSCRIBER_TERMINAL_IND_ID_REGISTRATION_ID;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_key_set_default(bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID)) != 0)
+ {
+ this->sched_id = (bcmbal_tm_sched_id) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ this->sched_dir = (bcmbal_tm_sched_dir) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_ID)) != 0)
+ {
+ this->id = (bcmbal_tm_queue_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_pack(const bcmbal_tm_queue_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ if (!bcmbal_tm_sched_dir_pack(this->sched_dir, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_queue_key_get_packed_length(const bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_ID)) != 0)
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_unpack(bcmbal_tm_queue_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->sched_id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ if (!bcmbal_tm_sched_dir_unpack(&this->sched_dir, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_key_bounds_check(const bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR)) != 0)
+ {
+ switch (this->sched_dir)
+ {
+ case BCMBAL_TM_SCHED_DIR_US:
+ break;
+ case BCMBAL_TM_SCHED_DIR_DS:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_QUEUE_KEY_ID_SCHED_DIR;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_cfg_data_set_default(bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_PRIORITY)) != 0)
+ {
+ this->priority = (bcmbal_tm_priority) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_WEIGHT)) != 0)
+ {
+ this->weight = (bcmbal_tm_weight) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ this->rate.presence_mask = (bcmbal_tm_shaping_id) 0;
+ this->rate.sbr = 0;
+ this->rate.pbr = 0;
+ this->rate.burst = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ this->bac.type = BCMBAL_TM_BAC_TYPE_TAILDROP;
+ this->bac.u.taildrop.max_size = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ this->creation_mode = BCMBAL_TM_CREATION_MODE_MANUAL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT)) != 0)
+ {
+ this->ref_count = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_data_pack(const bcmbal_tm_queue_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_WEIGHT)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, (uint8_t) this->weight))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_pack(&this->rate, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ if (!bcmbal_tm_bac_pack(&this->bac, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_tm_creation_mode_pack(this->creation_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, this->ref_count))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_queue_cfg_data_get_packed_length(const bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_PRIORITY)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_WEIGHT)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ count += bcmbal_tm_shaping_get_packed_length(&this->rate);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ count += bcmbal_tm_bac_get_packed_length(&this->bac);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT)) != 0)
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_data_unpack(bcmbal_tm_queue_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->priority))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_WEIGHT)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, (uint8_t *) &this->weight))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_unpack(&this->rate, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ if (!bcmbal_tm_bac_unpack(&this->bac, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_tm_creation_mode_unpack(&this->creation_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->ref_count))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_PRIORITY)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_WEIGHT)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ if (!bcmbal_tm_bac_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_cfg_data_bounds_check(const bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_bounds_check(&this->rate))
+ {
+ *failed_prop = BCMBAL_TM_QUEUE_CFG_ID_RATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_BAC)) != 0)
+ {
+ if (!bcmbal_tm_bac_bounds_check(&this->bac))
+ {
+ *failed_prop = BCMBAL_TM_QUEUE_CFG_ID_BAC;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE)) != 0)
+ {
+ switch (this->creation_mode)
+ {
+ case BCMBAL_TM_CREATION_MODE_MANUAL:
+ break;
+ case BCMBAL_TM_CREATION_MODE_AUTO:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_stat_data_set_default(bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK)) != 0)
+ {
+ this->packets_ok = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK)) != 0)
+ {
+ this->bytes_ok = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED)) != 0)
+ {
+ this->packets_discarded = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED)) != 0)
+ {
+ this->bytes_discarded = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_data_pack(const bcmbal_tm_queue_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->packets_ok))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->bytes_ok))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->packets_discarded))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_write_u64(buf, this->bytes_discarded))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_queue_stat_data_get_packed_length(const bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED)) != 0)
+ {
+ count += 8;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED)) != 0)
+ {
+ count += 8;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_data_unpack(bcmbal_tm_queue_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->packets_ok))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->bytes_ok))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->packets_discarded))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_read_u64(buf, &this->bytes_discarded))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_OK)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_OK)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_PACKETS_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_STAT_ID_BYTES_DISCARDED)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 8))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_stat_data_bounds_check(const bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_stat_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_queue_ind_data_set_default(bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_IND_ID_RET)) != 0)
+ {
+ this->ret = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_data_pack(const bcmbal_tm_queue_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->ret))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_queue_ind_data_get_packed_length(const bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_IND_ID_RET)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_data_unpack(bcmbal_tm_queue_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->ret))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_QUEUE_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_queue_ind_data_bounds_check(const bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_ind_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_key_set_default(bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ this->dir = (bcmbal_tm_sched_dir) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_ID)) != 0)
+ {
+ this->id = (bcmbal_tm_sched_id) 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_pack(const bcmbal_tm_sched_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ if (!bcmbal_tm_sched_dir_pack(this->dir, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, (uint32_t) this->id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_key_get_packed_length(const bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_ID)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_unpack(bcmbal_tm_sched_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ if (!bcmbal_tm_sched_dir_unpack(&this->dir, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, (uint32_t *) &this->id))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_ID)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_key_bounds_check(const bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_key_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_KEY_ID_DIR)) != 0)
+ {
+ switch (this->dir)
+ {
+ case BCMBAL_TM_SCHED_DIR_US:
+ break;
+ case BCMBAL_TM_SCHED_DIR_DS:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_SCHED_KEY_ID_DIR;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_cfg_data_set_default(bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ this->owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_UNDEFINED;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ this->sched_type = BCMBAL_TM_SCHED_TYPE_NONE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ this->sched_parent.presence_mask = (bcmbal_tm_sched_parent_id) 0;
+ this->sched_parent.sched_id = (bcmbal_tm_sched_id) 0;
+ this->sched_parent.priority = (bcmbal_tm_priority) 0;
+ this->sched_parent.weight = (bcmbal_tm_weight) 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ this->sched_child_type = BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ this->rate.presence_mask = (bcmbal_tm_shaping_id) 0;
+ this->rate.sbr = 0;
+ this->rate.pbr = 0;
+ this->rate.burst = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ this->tcont_sla.presence_mask = (bcmbal_tm_tcont_sla_id) 0;
+ this->tcont_sla.extra_bw_elig = BCMBAL_EXTRA_BW_ELIGIBILITY_TYPE_NONE;
+ this->tcont_sla.nrt_cbr = 0;
+ this->tcont_sla.rt_cbr = 0;
+ this->tcont_sla.rt_profile = 0;
+ this->tcont_sla.nrt_profile = 0;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ this->creation_mode = BCMBAL_TM_CREATION_MODE_MANUAL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ this->queues.len = 0;
+ this->queues.val = NULL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ this->sub_scheds.len = 0;
+ this->sub_scheds.val = NULL;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES)) != 0)
+ {
+ this->num_priorities = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_data_pack(const bcmbal_tm_sched_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_tm_sched_owner_pack(&this->owner, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ if (!bcmbal_tm_sched_type_pack(this->sched_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ if (!bcmbal_tm_sched_parent_pack(&this->sched_parent, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ if (!bcmbal_tm_sched_child_type_pack(this->sched_child_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_pack(&this->rate, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ if (!bcmbal_tm_tcont_sla_pack(&this->tcont_sla, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_tm_creation_mode_pack(this->creation_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ if (!bcmbal_tm_queue_id_list_u8_pack(&this->queues, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ if (!bcmbal_tm_sched_id_list_u8_pack(&this->sub_scheds, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES)) != 0)
+ {
+ if (!bcmbal_buf_write_u8(buf, this->num_priorities))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_cfg_data_get_packed_length(const bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ count += bcmbal_tm_sched_owner_get_packed_length(&this->owner);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ count += bcmbal_tm_sched_parent_get_packed_length(&this->sched_parent);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ count += bcmbal_tm_shaping_get_packed_length(&this->rate);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ count += bcmbal_tm_tcont_sla_get_packed_length(&this->tcont_sla);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ count += 1;
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ count += bcmbal_tm_queue_id_list_u8_get_packed_length(&this->queues);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ count += bcmbal_tm_sched_id_list_u8_get_packed_length(&this->sub_scheds);
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES)) != 0)
+ {
+ count += 1;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_data_unpack(bcmbal_tm_sched_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_tm_sched_owner_unpack(&this->owner, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ if (!bcmbal_tm_sched_type_unpack(&this->sched_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ if (!bcmbal_tm_sched_parent_unpack(&this->sched_parent, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ if (!bcmbal_tm_sched_child_type_unpack(&this->sched_child_type, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_unpack(&this->rate, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ if (!bcmbal_tm_tcont_sla_unpack(&this->tcont_sla, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_tm_creation_mode_unpack(&this->creation_mode, buf))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ if (!bcmbal_tm_queue_id_list_u8_unpack(&this->queues, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ if (!bcmbal_tm_sched_id_list_u8_unpack(&this->sub_scheds, buf, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES)) != 0)
+ {
+ if (!bcmbal_buf_read_u8(buf, &this->num_priorities))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_tm_sched_owner_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ if (!bcmbal_tm_sched_parent_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ if (!bcmbal_tm_tcont_sla_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ if (!bcmbal_tm_queue_id_list_u8_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ if (!bcmbal_tm_sched_id_list_u8_scan(packed, extra_mem))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_NUM_PRIORITIES)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 1))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_cfg_data_bounds_check(const bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_cfg_id *failed_prop)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_OWNER)) != 0)
+ {
+ if (!bcmbal_tm_sched_owner_bounds_check(&this->owner))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_OWNER;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE)) != 0)
+ {
+ switch (this->sched_type)
+ {
+ case BCMBAL_TM_SCHED_TYPE_NONE:
+ break;
+ case BCMBAL_TM_SCHED_TYPE_WFQ:
+ break;
+ case BCMBAL_TM_SCHED_TYPE_SP:
+ break;
+ case BCMBAL_TM_SCHED_TYPE_SP_WFQ:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_SCHED_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT)) != 0)
+ {
+ if (!bcmbal_tm_sched_parent_bounds_check(&this->sched_parent))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_SCHED_PARENT;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE)) != 0)
+ {
+ switch (this->sched_child_type)
+ {
+ case BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE:
+ break;
+ case BCMBAL_TM_SCHED_CHILD_TYPE_SCHED:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_SCHED_CHILD_TYPE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_RATE)) != 0)
+ {
+ if (!bcmbal_tm_shaping_bounds_check(&this->rate))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_RATE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA)) != 0)
+ {
+ if (!bcmbal_tm_tcont_sla_bounds_check(&this->tcont_sla))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_TCONT_SLA;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE)) != 0)
+ {
+ switch (this->creation_mode)
+ {
+ case BCMBAL_TM_CREATION_MODE_MANUAL:
+ break;
+ case BCMBAL_TM_CREATION_MODE_AUTO:
+ break;
+ default:
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) != 0)
+ {
+ if (!bcmbal_tm_queue_id_list_u8_bounds_check(&this->queues))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_QUEUES;
+ return BCMOS_FALSE;
+ }
+ }
+
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS)) != 0)
+ {
+ if (!bcmbal_tm_sched_id_list_u8_bounds_check(&this->sub_scheds))
+ {
+ *failed_prop = BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS;
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+void bcmbal_tm_sched_ind_data_set_default(bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_IND_ID_RET)) != 0)
+ {
+ this->ret = 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_data_pack(const bcmbal_tm_sched_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_write_u32(buf, this->ret))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+uint32_t bcmbal_tm_sched_ind_data_get_packed_length(const bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present)
+{
+ uint32_t count = 0;
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_IND_ID_RET)) != 0)
+ {
+ count += 4;
+ }
+
+ return count;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_data_unpack(bcmbal_tm_sched_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_read_u32(buf, &this->ret))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present)
+{
+ if ((fields_present & (1ULL << BCMBAL_TM_SCHED_IND_ID_RET)) != 0)
+ {
+ if (!bcmbal_buf_skip(packed, 4))
+ {
+ return BCMOS_FALSE;
+ }
+ }
+
+ return BCMOS_TRUE;
+}
+
+/******************************************************************************/
+bcmos_bool bcmbal_tm_sched_ind_data_bounds_check(const bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_ind_id *failed_prop)
+{
+ return BCMOS_TRUE;
+}
+
+bcmos_bool bcmbal_obj_has_tag(bcmbal_obj_id obj, bcmbal_obj_tag tag)
+{
+ switch (obj)
+ {
+ default:
+ return BCMOS_FALSE;
+ }
+}
diff --git a/bal_release/src/lib/libobjmsg/bal_model_funcs.h b/bal_release/src/lib/libobjmsg/bal_model_funcs.h
new file mode 100644
index 0000000..a0f5dd0
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/bal_model_funcs.h
@@ -0,0 +1,3441 @@
+#ifndef BAL_MODEL_FUNCS
+#define BAL_MODEL_FUNCS
+
+#include "bcmos_system.h"
+#include "bcmos_errno.h"
+#include "bal_buf.h"
+#include "bal_model_ids.h"
+#include "bal_model_types.h"
+
+/** Packs a bcmbal_access_terminal_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_access_terminal_cfg_id_pack(bcmbal_access_terminal_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_access_terminal_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_access_terminal_cfg_id_unpack(bcmbal_access_terminal_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_access_terminal_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_access_terminal_ind_id_pack(bcmbal_access_terminal_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_access_terminal_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_access_terminal_ind_id_unpack(bcmbal_access_terminal_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_access_terminal_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_access_terminal_key_id_pack(bcmbal_access_terminal_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_access_terminal_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_access_terminal_key_id_unpack(bcmbal_access_terminal_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_action_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_action_id_pack(bcmbal_action_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_action_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_action_id_unpack(bcmbal_action_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_action_cmd_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_action_cmd_id_pack(bcmbal_action_cmd_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_action_cmd_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_action_cmd_id_unpack(bcmbal_action_cmd_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_classifier_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_classifier_id_pack(bcmbal_classifier_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_classifier_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_classifier_id_unpack(bcmbal_classifier_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_pkt_tag_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_pkt_tag_type_pack(bcmbal_pkt_tag_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_pkt_tag_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_pkt_tag_type_unpack(bcmbal_pkt_tag_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_control to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_control_pack(bcmbal_control this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_control from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_control_unpack(bcmbal_control *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_dest_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_dest_type_pack(bcmbal_dest_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_dest_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_dest_type_unpack(bcmbal_dest_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_ds_miss_mode to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_ds_miss_mode_pack(bcmbal_ds_miss_mode this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_ds_miss_mode from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_ds_miss_mode_unpack(bcmbal_ds_miss_mode *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_extra_bw_eligibility_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_extra_bw_eligibility_type_pack(bcmbal_extra_bw_eligibility_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_extra_bw_eligibility_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_extra_bw_eligibility_type_unpack(bcmbal_extra_bw_eligibility_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_flow_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_flow_cfg_id_pack(bcmbal_flow_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_flow_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_flow_cfg_id_unpack(bcmbal_flow_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_flow_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_flow_ind_id_pack(bcmbal_flow_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_flow_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_flow_ind_id_unpack(bcmbal_flow_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_flow_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_flow_key_id_pack(bcmbal_flow_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_flow_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_flow_key_id_unpack(bcmbal_flow_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_flow_stat_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_flow_stat_id_pack(bcmbal_flow_stat_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_flow_stat_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_flow_stat_id_unpack(bcmbal_flow_stat_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_flow_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_flow_type_pack(bcmbal_flow_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_flow_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_flow_type_unpack(bcmbal_flow_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_group_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_group_cfg_id_pack(bcmbal_group_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_group_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_group_cfg_id_unpack(bcmbal_group_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_group_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_group_key_id_pack(bcmbal_group_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_group_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_group_key_id_unpack(bcmbal_group_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_group_member_cmd to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_group_member_cmd_pack(bcmbal_group_member_cmd this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_group_member_cmd from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_group_member_cmd_unpack(bcmbal_group_member_cmd *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_group_owner to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_group_owner_pack(bcmbal_group_owner this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_group_owner from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_group_owner_unpack(bcmbal_group_owner *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_interface_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_interface_cfg_id_pack(bcmbal_interface_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_interface_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_interface_cfg_id_unpack(bcmbal_interface_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_interface_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_interface_ind_id_pack(bcmbal_interface_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_interface_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_interface_ind_id_unpack(bcmbal_interface_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_interface_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_interface_key_id_pack(bcmbal_interface_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_interface_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_interface_key_id_unpack(bcmbal_interface_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_interface_stat_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_interface_stat_id_pack(bcmbal_interface_stat_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_interface_stat_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_interface_stat_id_unpack(bcmbal_interface_stat_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_intf_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_intf_type_pack(bcmbal_intf_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_intf_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_intf_type_unpack(bcmbal_intf_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_iwf_mode to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_iwf_mode_pack(bcmbal_iwf_mode this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_iwf_mode from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_iwf_mode_unpack(bcmbal_iwf_mode *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_packet_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_packet_cfg_id_pack(bcmbal_packet_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_packet_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_packet_cfg_id_unpack(bcmbal_packet_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_packet_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_packet_ind_id_pack(bcmbal_packet_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_packet_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_packet_ind_id_unpack(bcmbal_packet_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_packet_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_packet_key_id_pack(bcmbal_packet_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_packet_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_packet_key_id_unpack(bcmbal_packet_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_sla_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_sla_id_pack(bcmbal_sla_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_sla_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_sla_id_unpack(bcmbal_sla_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_state to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_state_pack(bcmbal_state this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_state from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_state_unpack(bcmbal_state *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_status to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_status_pack(bcmbal_status this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_status from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_status_unpack(bcmbal_status *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_subscriber_terminal_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_id_pack(bcmbal_subscriber_terminal_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_subscriber_terminal_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_id_unpack(bcmbal_subscriber_terminal_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_subscriber_terminal_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_id_pack(bcmbal_subscriber_terminal_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_subscriber_terminal_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_id_unpack(bcmbal_subscriber_terminal_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_subscriber_terminal_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_id_pack(bcmbal_subscriber_terminal_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_subscriber_terminal_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_id_unpack(bcmbal_subscriber_terminal_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_subscriber_terminal_stat_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_id_pack(bcmbal_subscriber_terminal_stat_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_subscriber_terminal_stat_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_id_unpack(bcmbal_subscriber_terminal_stat_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_bac_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_bac_type_pack(bcmbal_tm_bac_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_bac_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_bac_type_unpack(bcmbal_tm_bac_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_creation_mode to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_creation_mode_pack(bcmbal_tm_creation_mode this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_creation_mode from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_creation_mode_unpack(bcmbal_tm_creation_mode *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_queue_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_queue_cfg_id_pack(bcmbal_tm_queue_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_queue_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_queue_cfg_id_unpack(bcmbal_tm_queue_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_queue_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_queue_ind_id_pack(bcmbal_tm_queue_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_queue_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_queue_ind_id_unpack(bcmbal_tm_queue_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_queue_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_queue_key_id_pack(bcmbal_tm_queue_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_queue_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_queue_key_id_unpack(bcmbal_tm_queue_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_queue_stat_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_queue_stat_id_pack(bcmbal_tm_queue_stat_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_queue_stat_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_queue_stat_id_unpack(bcmbal_tm_queue_stat_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_cfg_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_cfg_id_pack(bcmbal_tm_sched_cfg_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_cfg_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_cfg_id_unpack(bcmbal_tm_sched_cfg_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_child_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_child_type_pack(bcmbal_tm_sched_child_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_child_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_child_type_unpack(bcmbal_tm_sched_child_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_dir to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_dir_pack(bcmbal_tm_sched_dir this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_dir from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_dir_unpack(bcmbal_tm_sched_dir *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_ind_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_ind_id_pack(bcmbal_tm_sched_ind_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_ind_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_ind_id_unpack(bcmbal_tm_sched_ind_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_key_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_key_id_pack(bcmbal_tm_sched_key_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_key_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_key_id_unpack(bcmbal_tm_sched_key_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_owner_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_owner_type_pack(bcmbal_tm_sched_owner_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_owner_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_owner_type_unpack(bcmbal_tm_sched_owner_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_owner_agg_port_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_owner_agg_port_id_pack(bcmbal_tm_sched_owner_agg_port_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_owner_agg_port_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_owner_agg_port_id_unpack(bcmbal_tm_sched_owner_agg_port_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_parent_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_parent_id_pack(bcmbal_tm_sched_parent_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_parent_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_parent_id_unpack(bcmbal_tm_sched_parent_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_sched_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_sched_type_pack(bcmbal_tm_sched_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_sched_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_sched_type_unpack(bcmbal_tm_sched_type *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_shaping_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_shaping_id_pack(bcmbal_tm_shaping_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_shaping_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_shaping_id_unpack(bcmbal_tm_shaping_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_tm_tcont_sla_id to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_tm_tcont_sla_id_pack(bcmbal_tm_tcont_sla_id this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_tcont_sla_id from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_tm_tcont_sla_id_unpack(bcmbal_tm_tcont_sla_id *this, bcmbal_buf *buf);
+
+/** Packs a bcmbal_trx_type to bytes
+ *
+ * \param this The enumeration to pack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the pack was successful
+ */
+bcmos_bool bcmbal_trx_type_pack(bcmbal_trx_type this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_trx_type from bytes
+ *
+ * \param this Pointer to the enumeration to unpack
+ * \param buf Pointer to the buffer to write to
+ * \return Whether or not the unpack was successful
+ */
+bcmos_bool bcmbal_trx_type_unpack(bcmbal_trx_type *this, bcmbal_buf *buf);
+
+/** Initializes a bcmbal_action struct. This sets all fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_action_set_default(bcmbal_action *this);
+
+/** Packs a bcmbal_action to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_action_pack(const bcmbal_action *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_action would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_action_get_packed_length(const bcmbal_action *this);
+
+/** Unpacks a bcmbal_action from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_action_unpack(bcmbal_action *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_action struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_action_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_action is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_action_bounds_check(const bcmbal_action *this);
+
+/** Initializes a bcmbal_aggregation_port_id_list_u8 struct. This sets all
+ * fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_aggregation_port_id_list_u8_set_default(bcmbal_aggregation_port_id_list_u8 *this);
+
+/** Packs a bcmbal_aggregation_port_id_list_u8 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_aggregation_port_id_list_u8_pack(const bcmbal_aggregation_port_id_list_u8 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_aggregation_port_id_list_u8 would
+ * occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_aggregation_port_id_list_u8_get_packed_length(const bcmbal_aggregation_port_id_list_u8 *this);
+
+/** Unpacks a bcmbal_aggregation_port_id_list_u8 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_aggregation_port_id_list_u8_unpack(bcmbal_aggregation_port_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_aggregation_port_id_list_u8 struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_aggregation_port_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_aggregation_port_id_list_u8 is out of
+ * bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_aggregation_port_id_list_u8_bounds_check(const bcmbal_aggregation_port_id_list_u8 *this);
+
+/** Initializes a bcmbal_classifier struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_classifier_set_default(bcmbal_classifier *this);
+
+/** Packs a bcmbal_classifier to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_classifier_pack(const bcmbal_classifier *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_classifier would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_classifier_get_packed_length(const bcmbal_classifier *this);
+
+/** Unpacks a bcmbal_classifier from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_classifier_unpack(bcmbal_classifier *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_classifier struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_classifier_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_classifier is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_classifier_bounds_check(const bcmbal_classifier *this);
+
+/** Initializes a bcmbal_dest struct. This sets all fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_dest_set_default(bcmbal_dest *this);
+
+/** Packs a bcmbal_dest to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_dest_pack(const bcmbal_dest *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_dest would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_dest_get_packed_length(const bcmbal_dest *this);
+
+/** Unpacks a bcmbal_dest from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_dest_unpack(bcmbal_dest *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_dest struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_dest_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_dest is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_dest_bounds_check(const bcmbal_dest *this);
+
+/** Initializes a bcmbal_flow_id_list_u32 struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_flow_id_list_u32_set_default(bcmbal_flow_id_list_u32 *this);
+
+/** Packs a bcmbal_flow_id_list_u32 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_id_list_u32_pack(const bcmbal_flow_id_list_u32 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_flow_id_list_u32 would occupy on the
+ * wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_flow_id_list_u32_get_packed_length(const bcmbal_flow_id_list_u32 *this);
+
+/** Unpacks a bcmbal_flow_id_list_u32 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_id_list_u32_unpack(bcmbal_flow_id_list_u32 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_flow_id_list_u32 struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_flow_id_list_u32_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_flow_id_list_u32 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_id_list_u32_bounds_check(const bcmbal_flow_id_list_u32 *this);
+
+/** Initializes a bcmbal_tm_queue_ref struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_queue_ref_set_default(bcmbal_tm_queue_ref *this);
+
+/** Packs a bcmbal_tm_queue_ref to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ref_pack(const bcmbal_tm_queue_ref *this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_queue_ref from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ref_unpack(bcmbal_tm_queue_ref *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_queue_ref struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_ref_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_queue_ref is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ref_bounds_check(const bcmbal_tm_queue_ref *this);
+
+/** Initializes a bcmbal_group_member_info struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_group_member_info_set_default(bcmbal_group_member_info *this);
+
+/** Packs a bcmbal_group_member_info to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_pack(const bcmbal_group_member_info *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_group_member_info would occupy on the
+ * wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_group_member_info_get_packed_length(const bcmbal_group_member_info *this);
+
+/** Unpacks a bcmbal_group_member_info from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_unpack(bcmbal_group_member_info *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_group_member_info struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_group_member_info_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_group_member_info is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_bounds_check(const bcmbal_group_member_info *this);
+
+/** Initializes a bcmbal_group_member_info_list_u16 struct. This sets all
+ * fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_group_member_info_list_u16_set_default(bcmbal_group_member_info_list_u16 *this);
+
+/** Packs a bcmbal_group_member_info_list_u16 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_list_u16_pack(const bcmbal_group_member_info_list_u16 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_group_member_info_list_u16 would
+ * occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_group_member_info_list_u16_get_packed_length(const bcmbal_group_member_info_list_u16 *this);
+
+/** Unpacks a bcmbal_group_member_info_list_u16 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_list_u16_unpack(bcmbal_group_member_info_list_u16 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_group_member_info_list_u16 struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_group_member_info_list_u16_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_group_member_info_list_u16 is out of
+ * bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_member_info_list_u16_bounds_check(const bcmbal_group_member_info_list_u16 *this);
+
+/** Initializes a bcmbal_password struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_password_set_default(bcmbal_password *this);
+
+/** Packs a bcmbal_password to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_password_pack(const bcmbal_password *this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_password from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_password_unpack(bcmbal_password *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_password struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_password_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_password is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_password_bounds_check(const bcmbal_password *this);
+
+/** Initializes a bcmbal_registration_id struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_registration_id_set_default(bcmbal_registration_id *this);
+
+/** Packs a bcmbal_registration_id to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_registration_id_pack(const bcmbal_registration_id *this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_registration_id from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_registration_id_unpack(bcmbal_registration_id *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_registration_id struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_registration_id_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_registration_id is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_registration_id_bounds_check(const bcmbal_registration_id *this);
+
+/** Initializes a bcmbal_serial_number struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_serial_number_set_default(bcmbal_serial_number *this);
+
+/** Packs a bcmbal_serial_number to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_serial_number_pack(const bcmbal_serial_number *this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_serial_number from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_serial_number_unpack(bcmbal_serial_number *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_serial_number struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_serial_number_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_serial_number is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_serial_number_bounds_check(const bcmbal_serial_number *this);
+
+/** Initializes a bcmbal_service_port_id_list_u8 struct. This sets all fields
+ * to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_service_port_id_list_u8_set_default(bcmbal_service_port_id_list_u8 *this);
+
+/** Packs a bcmbal_service_port_id_list_u8 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_service_port_id_list_u8_pack(const bcmbal_service_port_id_list_u8 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_service_port_id_list_u8 would occupy
+ * on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_service_port_id_list_u8_get_packed_length(const bcmbal_service_port_id_list_u8 *this);
+
+/** Unpacks a bcmbal_service_port_id_list_u8 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_service_port_id_list_u8_unpack(bcmbal_service_port_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_service_port_id_list_u8 struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_service_port_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_service_port_id_list_u8 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_service_port_id_list_u8_bounds_check(const bcmbal_service_port_id_list_u8 *this);
+
+/** Initializes a bcmbal_sla struct. This sets all fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_sla_set_default(bcmbal_sla *this);
+
+/** Packs a bcmbal_sla to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_sla_pack(const bcmbal_sla *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_sla would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_sla_get_packed_length(const bcmbal_sla *this);
+
+/** Unpacks a bcmbal_sla from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_sla_unpack(bcmbal_sla *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_sla struct and collects memory requirements above
+ * and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_sla_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_sla is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_sla_bounds_check(const bcmbal_sla *this);
+
+/** Initializes a bcmbal_sub_id_list_u16 struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_sub_id_list_u16_set_default(bcmbal_sub_id_list_u16 *this);
+
+/** Packs a bcmbal_sub_id_list_u16 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_sub_id_list_u16_pack(const bcmbal_sub_id_list_u16 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_sub_id_list_u16 would occupy on the
+ * wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_sub_id_list_u16_get_packed_length(const bcmbal_sub_id_list_u16 *this);
+
+/** Unpacks a bcmbal_sub_id_list_u16 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_sub_id_list_u16_unpack(bcmbal_sub_id_list_u16 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_sub_id_list_u16 struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_sub_id_list_u16_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_sub_id_list_u16 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_sub_id_list_u16_bounds_check(const bcmbal_sub_id_list_u16 *this);
+
+/** Initializes a bcmbal_tm_red struct. This sets all fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_red_set_default(bcmbal_tm_red *this);
+
+/** Packs a bcmbal_tm_red to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_red_pack(const bcmbal_tm_red *this, bcmbal_buf *buf);
+
+/** Unpacks a bcmbal_tm_red from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_red_unpack(bcmbal_tm_red *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_red struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_red_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_red is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_red_bounds_check(const bcmbal_tm_red *this);
+
+/** Initializes a bcmbal_tm_bac struct. This sets all fields to default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_bac_set_default(bcmbal_tm_bac *this);
+
+/** Packs a bcmbal_tm_bac to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_bac_pack(const bcmbal_tm_bac *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_bac would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_bac_get_packed_length(const bcmbal_tm_bac *this);
+
+/** Unpacks a bcmbal_tm_bac from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_bac_unpack(bcmbal_tm_bac *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_bac struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_bac_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_bac is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_bac_bounds_check(const bcmbal_tm_bac *this);
+
+/** Initializes a bcmbal_tm_queue_id_list_u8 struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_queue_id_list_u8_set_default(bcmbal_tm_queue_id_list_u8 *this);
+
+/** Packs a bcmbal_tm_queue_id_list_u8 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_id_list_u8_pack(const bcmbal_tm_queue_id_list_u8 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_queue_id_list_u8 would occupy on
+ * the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_queue_id_list_u8_get_packed_length(const bcmbal_tm_queue_id_list_u8 *this);
+
+/** Unpacks a bcmbal_tm_queue_id_list_u8 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_id_list_u8_unpack(bcmbal_tm_queue_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_queue_id_list_u8 struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_queue_id_list_u8 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_id_list_u8_bounds_check(const bcmbal_tm_queue_id_list_u8 *this);
+
+/** Initializes a bcmbal_tm_sched_id_list_u8 struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_sched_id_list_u8_set_default(bcmbal_tm_sched_id_list_u8 *this);
+
+/** Packs a bcmbal_tm_sched_id_list_u8 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_id_list_u8_pack(const bcmbal_tm_sched_id_list_u8 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_id_list_u8 would occupy on
+ * the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_id_list_u8_get_packed_length(const bcmbal_tm_sched_id_list_u8 *this);
+
+/** Unpacks a bcmbal_tm_sched_id_list_u8 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_id_list_u8_unpack(bcmbal_tm_sched_id_list_u8 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_sched_id_list_u8 struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_id_list_u8_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_sched_id_list_u8 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_id_list_u8_bounds_check(const bcmbal_tm_sched_id_list_u8 *this);
+
+/** Initializes a bcmbal_tm_sched_owner struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_sched_owner_set_default(bcmbal_tm_sched_owner *this);
+
+/** Packs a bcmbal_tm_sched_owner to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_owner_pack(const bcmbal_tm_sched_owner *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_owner would occupy on the
+ * wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_owner_get_packed_length(const bcmbal_tm_sched_owner *this);
+
+/** Unpacks a bcmbal_tm_sched_owner from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_owner_unpack(bcmbal_tm_sched_owner *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_sched_owner struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_owner_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_sched_owner is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_owner_bounds_check(const bcmbal_tm_sched_owner *this);
+
+/** Initializes a bcmbal_tm_sched_parent struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_sched_parent_set_default(bcmbal_tm_sched_parent *this);
+
+/** Packs a bcmbal_tm_sched_parent to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_parent_pack(const bcmbal_tm_sched_parent *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_parent would occupy on the
+ * wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_parent_get_packed_length(const bcmbal_tm_sched_parent *this);
+
+/** Unpacks a bcmbal_tm_sched_parent from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_parent_unpack(bcmbal_tm_sched_parent *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_sched_parent struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_parent_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_sched_parent is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_parent_bounds_check(const bcmbal_tm_sched_parent *this);
+
+/** Initializes a bcmbal_tm_shaping struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_shaping_set_default(bcmbal_tm_shaping *this);
+
+/** Packs a bcmbal_tm_shaping to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_shaping_pack(const bcmbal_tm_shaping *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_shaping would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_shaping_get_packed_length(const bcmbal_tm_shaping *this);
+
+/** Unpacks a bcmbal_tm_shaping from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_shaping_unpack(bcmbal_tm_shaping *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_shaping struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_shaping_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_shaping is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_shaping_bounds_check(const bcmbal_tm_shaping *this);
+
+/** Initializes a bcmbal_tm_tcont_sla struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_tm_tcont_sla_set_default(bcmbal_tm_tcont_sla *this);
+
+/** Packs a bcmbal_tm_tcont_sla to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_tcont_sla_pack(const bcmbal_tm_tcont_sla *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_tm_tcont_sla would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_tcont_sla_get_packed_length(const bcmbal_tm_tcont_sla *this);
+
+/** Unpacks a bcmbal_tm_tcont_sla from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_tcont_sla_unpack(bcmbal_tm_tcont_sla *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_tm_tcont_sla struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_tcont_sla_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_tm_tcont_sla is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_tcont_sla_bounds_check(const bcmbal_tm_tcont_sla *this);
+
+/** Initializes a bcmbal_u8_list_u32 struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ */
+void bcmbal_u8_list_u32_set_default(bcmbal_u8_list_u32 *this);
+
+/** Packs a bcmbal_u8_list_u32 to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_u8_list_u32_pack(const bcmbal_u8_list_u32 *this, bcmbal_buf *buf);
+
+/** Gets the number of bytes that a bcmbal_u8_list_u32 would occupy on the wire
+ *
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_u8_list_u32_get_packed_length(const bcmbal_u8_list_u32 *this);
+
+/** Unpacks a bcmbal_u8_list_u32 from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_u8_list_u32_unpack(bcmbal_u8_list_u32 *this, bcmbal_buf *buf, void **extra_mem);
+
+/** Scans past a packed bcmbal_u8_list_u32 struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_u8_list_u32_scan(bcmbal_buf *packed, uint32_t *extra_mem);
+
+/** Checks if any field in the bcmbal_u8_list_u32 is out of bounds
+ *
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_u8_list_u32_bounds_check(const bcmbal_u8_list_u32 *this);
+
+/** Initializes a bcmbal_access_terminal_key struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_access_terminal_key_set_default(bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_access_terminal_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_key_pack(const bcmbal_access_terminal_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_access_terminal_key would occupy on
+ * the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_access_terminal_key_get_packed_length(const bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_access_terminal_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_key_unpack(bcmbal_access_terminal_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_access_terminal_key struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_access_terminal_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_access_terminal_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_key_bounds_check(const bcmbal_access_terminal_key *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_key_id *failed_prop);
+
+/** Initializes a bcmbal_access_terminal_cfg_data struct. This sets all fields
+ * to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_access_terminal_cfg_data_set_default(bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_access_terminal_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_cfg_data_pack(const bcmbal_access_terminal_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_access_terminal_cfg_data would occupy
+ * on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_access_terminal_cfg_data_get_packed_length(const bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_access_terminal_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_cfg_data_unpack(bcmbal_access_terminal_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_access_terminal_cfg_data struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_access_terminal_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_access_terminal_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_cfg_data_bounds_check(const bcmbal_access_terminal_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_access_terminal_ind_data struct. This sets all fields
+ * to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_access_terminal_ind_data_set_default(bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_access_terminal_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_ind_data_pack(const bcmbal_access_terminal_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_access_terminal_ind_data would occupy
+ * on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_access_terminal_ind_data_get_packed_length(const bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_access_terminal_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_ind_data_unpack(bcmbal_access_terminal_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_access_terminal_ind_data struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_access_terminal_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_access_terminal_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_access_terminal_ind_data_bounds_check(const bcmbal_access_terminal_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_access_terminal_ind_id *failed_prop);
+
+/** Initializes a bcmbal_flow_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_flow_key_set_default(bcmbal_flow_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_flow_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_key_pack(const bcmbal_flow_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_flow_key would occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_flow_key_get_packed_length(const bcmbal_flow_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_flow_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_key_unpack(bcmbal_flow_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_flow_key struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_flow_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_flow_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_key_bounds_check(const bcmbal_flow_key *this, bcmbal_presence_mask fields_present, bcmbal_flow_key_id *failed_prop);
+
+/** Initializes a bcmbal_flow_cfg_data struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_flow_cfg_data_set_default(bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_flow_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_cfg_data_pack(const bcmbal_flow_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_flow_cfg_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_flow_cfg_data_get_packed_length(const bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_flow_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_cfg_data_unpack(bcmbal_flow_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_flow_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_flow_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_flow_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_cfg_data_bounds_check(const bcmbal_flow_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_flow_stat_data struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_flow_stat_data_set_default(bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_flow_stat_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_stat_data_pack(const bcmbal_flow_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_flow_stat_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_flow_stat_data_get_packed_length(const bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_flow_stat_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_stat_data_unpack(bcmbal_flow_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_flow_stat_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_flow_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_flow_stat_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_stat_data_bounds_check(const bcmbal_flow_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_stat_id *failed_prop);
+
+/** Initializes a bcmbal_flow_ind_data struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_flow_ind_data_set_default(bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_flow_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_ind_data_pack(const bcmbal_flow_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_flow_ind_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_flow_ind_data_get_packed_length(const bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_flow_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_ind_data_unpack(bcmbal_flow_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_flow_ind_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_flow_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_flow_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_flow_ind_data_bounds_check(const bcmbal_flow_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_flow_ind_id *failed_prop);
+
+/** Initializes a bcmbal_group_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_group_key_set_default(bcmbal_group_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_group_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_key_pack(const bcmbal_group_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_group_key would occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_group_key_get_packed_length(const bcmbal_group_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_group_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_key_unpack(bcmbal_group_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_group_key struct and collects memory requirements
+ * above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_group_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_group_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_key_bounds_check(const bcmbal_group_key *this, bcmbal_presence_mask fields_present, bcmbal_group_key_id *failed_prop);
+
+/** Initializes a bcmbal_group_cfg_data struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_group_cfg_data_set_default(bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_group_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_cfg_data_pack(const bcmbal_group_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_group_cfg_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_group_cfg_data_get_packed_length(const bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_group_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_cfg_data_unpack(bcmbal_group_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_group_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_group_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_group_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_group_cfg_data_bounds_check(const bcmbal_group_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_group_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_interface_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_interface_key_set_default(bcmbal_interface_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_interface_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_key_pack(const bcmbal_interface_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_interface_key would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_interface_key_get_packed_length(const bcmbal_interface_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_interface_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_key_unpack(bcmbal_interface_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_interface_key struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_interface_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_interface_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_key_bounds_check(const bcmbal_interface_key *this, bcmbal_presence_mask fields_present, bcmbal_interface_key_id *failed_prop);
+
+/** Initializes a bcmbal_interface_cfg_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_interface_cfg_data_set_default(bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_interface_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_cfg_data_pack(const bcmbal_interface_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_interface_cfg_data would occupy on
+ * the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_interface_cfg_data_get_packed_length(const bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_interface_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_cfg_data_unpack(bcmbal_interface_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_interface_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_interface_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_interface_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_cfg_data_bounds_check(const bcmbal_interface_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_interface_stat_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_interface_stat_data_set_default(bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_interface_stat_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_stat_data_pack(const bcmbal_interface_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_interface_stat_data would occupy on
+ * the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_interface_stat_data_get_packed_length(const bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_interface_stat_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_stat_data_unpack(bcmbal_interface_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_interface_stat_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_interface_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_interface_stat_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_stat_data_bounds_check(const bcmbal_interface_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_stat_id *failed_prop);
+
+/** Initializes a bcmbal_interface_ind_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_interface_ind_data_set_default(bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_interface_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_ind_data_pack(const bcmbal_interface_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_interface_ind_data would occupy on
+ * the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_interface_ind_data_get_packed_length(const bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_interface_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_ind_data_unpack(bcmbal_interface_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_interface_ind_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_interface_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_interface_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_interface_ind_data_bounds_check(const bcmbal_interface_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_interface_ind_id *failed_prop);
+
+/** Initializes a bcmbal_packet_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_packet_key_set_default(bcmbal_packet_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_packet_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_key_pack(const bcmbal_packet_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_packet_key would occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_packet_key_get_packed_length(const bcmbal_packet_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_packet_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_key_unpack(bcmbal_packet_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_packet_key struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_packet_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_packet_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_key_bounds_check(const bcmbal_packet_key *this, bcmbal_presence_mask fields_present, bcmbal_packet_key_id *failed_prop);
+
+/** Initializes a bcmbal_packet_cfg_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_packet_cfg_data_set_default(bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_packet_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_cfg_data_pack(const bcmbal_packet_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_packet_cfg_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_packet_cfg_data_get_packed_length(const bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_packet_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_cfg_data_unpack(bcmbal_packet_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_packet_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_packet_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_packet_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_cfg_data_bounds_check(const bcmbal_packet_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_packet_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_packet_ind_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_packet_ind_data_set_default(bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_packet_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_ind_data_pack(const bcmbal_packet_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_packet_ind_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_packet_ind_data_get_packed_length(const bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_packet_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_ind_data_unpack(bcmbal_packet_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_packet_ind_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_packet_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_packet_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_packet_ind_data_bounds_check(const bcmbal_packet_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_packet_ind_id *failed_prop);
+
+/** Initializes a bcmbal_subscriber_terminal_key struct. This sets all fields
+ * to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_subscriber_terminal_key_set_default(bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_subscriber_terminal_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_pack(const bcmbal_subscriber_terminal_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_subscriber_terminal_key would occupy
+ * on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_subscriber_terminal_key_get_packed_length(const bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_subscriber_terminal_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_unpack(bcmbal_subscriber_terminal_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_subscriber_terminal_key struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_subscriber_terminal_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_key_bounds_check(const bcmbal_subscriber_terminal_key *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_key_id *failed_prop);
+
+/** Initializes a bcmbal_subscriber_terminal_cfg_data struct. This sets all
+ * fields to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_subscriber_terminal_cfg_data_set_default(bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_subscriber_terminal_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_pack(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_subscriber_terminal_cfg_data would
+ * occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_subscriber_terminal_cfg_data_get_packed_length(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_subscriber_terminal_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_unpack(bcmbal_subscriber_terminal_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_subscriber_terminal_cfg_data struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_subscriber_terminal_cfg_data is out of
+ * bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_cfg_data_bounds_check(const bcmbal_subscriber_terminal_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_subscriber_terminal_stat_data struct. This sets all
+ * fields to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_subscriber_terminal_stat_data_set_default(bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_subscriber_terminal_stat_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_data_pack(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_subscriber_terminal_stat_data would
+ * occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_subscriber_terminal_stat_data_get_packed_length(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_subscriber_terminal_stat_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_data_unpack(bcmbal_subscriber_terminal_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_subscriber_terminal_stat_data struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_subscriber_terminal_stat_data is out of
+ * bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_stat_data_bounds_check(const bcmbal_subscriber_terminal_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_stat_id *failed_prop);
+
+/** Initializes a bcmbal_subscriber_terminal_ind_data struct. This sets all
+ * fields to default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_subscriber_terminal_ind_data_set_default(bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_subscriber_terminal_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_data_pack(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_subscriber_terminal_ind_data would
+ * occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_subscriber_terminal_ind_data_get_packed_length(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_subscriber_terminal_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_data_unpack(bcmbal_subscriber_terminal_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_subscriber_terminal_ind_data struct and collects
+ * memory requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_subscriber_terminal_ind_data is out of
+ * bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_subscriber_terminal_ind_data_bounds_check(const bcmbal_subscriber_terminal_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_subscriber_terminal_ind_id *failed_prop);
+
+/** Initializes a bcmbal_tm_queue_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_queue_key_set_default(bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_queue_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_key_pack(const bcmbal_tm_queue_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_queue_key would occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_queue_key_get_packed_length(const bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_queue_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_key_unpack(bcmbal_tm_queue_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_queue_key struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_queue_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_key_bounds_check(const bcmbal_tm_queue_key *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_key_id *failed_prop);
+
+/** Initializes a bcmbal_tm_queue_cfg_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_queue_cfg_data_set_default(bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_queue_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_cfg_data_pack(const bcmbal_tm_queue_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_queue_cfg_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_queue_cfg_data_get_packed_length(const bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_queue_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_cfg_data_unpack(bcmbal_tm_queue_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_queue_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_queue_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_cfg_data_bounds_check(const bcmbal_tm_queue_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_tm_queue_stat_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_queue_stat_data_set_default(bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_queue_stat_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_stat_data_pack(const bcmbal_tm_queue_stat_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_queue_stat_data would occupy on
+ * the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_queue_stat_data_get_packed_length(const bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_queue_stat_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_stat_data_unpack(bcmbal_tm_queue_stat_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_queue_stat_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_stat_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_queue_stat_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_stat_data_bounds_check(const bcmbal_tm_queue_stat_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_stat_id *failed_prop);
+
+/** Initializes a bcmbal_tm_queue_ind_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_queue_ind_data_set_default(bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_queue_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ind_data_pack(const bcmbal_tm_queue_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_queue_ind_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_queue_ind_data_get_packed_length(const bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_queue_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ind_data_unpack(bcmbal_tm_queue_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_queue_ind_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_queue_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_queue_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_queue_ind_data_bounds_check(const bcmbal_tm_queue_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_queue_ind_id *failed_prop);
+
+/** Initializes a bcmbal_tm_sched_key struct. This sets all fields to default
+ * values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_sched_key_set_default(bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_sched_key to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_key_pack(const bcmbal_tm_sched_key *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_key would occupy on the wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_key_get_packed_length(const bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_sched_key from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_key_unpack(bcmbal_tm_sched_key *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_sched_key struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_key_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_sched_key is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_key_bounds_check(const bcmbal_tm_sched_key *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_key_id *failed_prop);
+
+/** Initializes a bcmbal_tm_sched_cfg_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_sched_cfg_data_set_default(bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_sched_cfg_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_cfg_data_pack(const bcmbal_tm_sched_cfg_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_cfg_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_cfg_data_get_packed_length(const bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_sched_cfg_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_cfg_data_unpack(bcmbal_tm_sched_cfg_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_sched_cfg_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_cfg_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_sched_cfg_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_cfg_data_bounds_check(const bcmbal_tm_sched_cfg_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_cfg_id *failed_prop);
+
+/** Initializes a bcmbal_tm_sched_ind_data struct. This sets all fields to
+ * default values.
+ *
+ * \param this Pointer to the structure
+ * \param fields_present Bitmask of which fields are present in the structure.
+ */
+void bcmbal_tm_sched_ind_data_set_default(bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Packs a bcmbal_tm_sched_ind_data to bytes
+ *
+ * \param this Pointer to the object to pack
+ * \param buf Pointer to the buffer to write to
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the pack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_ind_data_pack(const bcmbal_tm_sched_ind_data *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+
+/** Gets the number of bytes that a bcmbal_tm_sched_ind_data would occupy on the
+ * wire
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return The structure size in bytes
+ */
+uint32_t bcmbal_tm_sched_ind_data_get_packed_length(const bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present);
+
+/** Unpacks a bcmbal_tm_sched_ind_data from bytes
+ *
+ * \param this Pointer to the object to unpack
+ * \param buf Pointer to the buffer to read from
+ * \param extra_mem Pointer to the first location in memory to use to store
+ * pointer fields that are NULL. Setting this to NULL will cause an error when
+ * a NULL pointer is encountered.
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE if the unpack was successful, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_ind_data_unpack(bcmbal_tm_sched_ind_data *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+
+/** Scans past a packed bcmbal_tm_sched_ind_data struct and collects memory
+ * requirements above and beyond sizeof()
+ *
+ * \param packed A stream pointing to the packed byte stream
+ * \param extra_mem Number of additional storage bytes required
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \return TRUE on success, FALSE on failure
+ */
+bcmos_bool bcmbal_tm_sched_ind_data_scan(bcmbal_buf *packed, uint32_t *extra_mem, bcmbal_presence_mask fields_present);
+
+/** Checks if any field in the bcmbal_tm_sched_ind_data is out of bounds
+ *
+ * \param fields_present Bitmask of which fields are present in the structure.
+ * \param failed_prop Reference to the property that was out of range (only set
+ * on failure)
+ * \return TRUE if all fields are in the correct range, FALSE otherwise
+ */
+bcmos_bool bcmbal_tm_sched_ind_data_bounds_check(const bcmbal_tm_sched_ind_data *this, bcmbal_presence_mask fields_present, bcmbal_tm_sched_ind_id *failed_prop);
+#endif /* BAL_MODEL_FUNCS */
diff --git a/bal_release/src/lib/libobjmsg/bal_msg.c b/bal_release/src/lib/libobjmsg/bal_msg.c
new file mode 100644
index 0000000..285be80
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/bal_msg.c
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_msg.c
+ * @brief BAL message helper functions
+ * @addtogroup ctrlr
+ */
+#include <bal_msg.h>
+#include <bal_obj_msg_pack_unpack.h>
+
+/*
+ * Clone BAL message
+ * Returns payload_ptr of the clone
+ */
+void *bcmbal_msg_clone(void *bal_obj)
+{
+ bal_comm_msg_hdr *msg_hdr = bcmbal_bal_hdr_get(bal_obj);
+ bal_comm_msg_hdr *clone_hdr = NULL;
+ bcmos_errno err = bcmbal_obj_msg_clone(&clone_hdr, msg_hdr);
+ return ((int)err >= 0) ? bcmbal_payload_ptr_get(clone_hdr) : NULL;
+}
+
+/*
+ * Send a BAL message given the payload pointer
+ */
+bcmos_errno bcmbal_msg_send(bcmos_msg_queue *queue, void *msg_payload, bcmos_msg_send_flags flags)
+{
+ bcmos_msg *packed_msg = NULL;
+ bcmos_errno err;
+
+ /* pack and send */
+ err = bcmbal_obj_msg_pack(bcmbal_bal_hdr_get(msg_payload), &packed_msg);
+ if (err != BCM_ERR_OK)
+ return err;
+
+ err = bcmos_msg_send(queue, packed_msg, flags);
+
+ if ((flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR) == 0)
+ {
+ /* Release the original message */
+ bcmbal_msg_free(msg_payload);
+ }
+ else if (err != BCM_ERR_OK)
+ {
+ /* bcmos_msg_send() failed, but packed_msg wasn't released because of the flag. */
+ bcmos_msg_free(packed_msg);
+ }
+
+ return err;
+}
+
+/*
+ * Call callback in the context of the target module and pass it the BAL message pointer
+ */
+bcmos_errno bcmbal_msg_call(void *msg_payload,
+ bcmos_module_id module, F_bcmos_msg_handler cb, bcmos_msg_send_flags flags)
+{
+ bcmos_msg *m = bcmbal_bcmos_hdr_get(msg_payload);
+ m->handler = cb;
+ return bcmos_msg_send_to_module(module, m, flags);
+}
+
+bcmos_errno bcmbal_msg_recv(bcmos_msg_queue *queue, uint32_t timeout, void **msg_payload)
+{
+ bcmos_errno ret;
+ bcmos_msg *msg;
+ bal_comm_msg_hdr *unpacked_msg = (*msg_payload) ? bcmbal_bal_hdr_get(*msg_payload) : NULL;
+
+ do {
+ ret = bcmos_msg_recv(queue, timeout, &msg);
+ if(BCM_ERR_OK != ret)
+ {
+ bcmos_printf("%s: error during bcmos_msg_recv (error:%s)\n",
+ __FUNCTION__,
+ bcmos_strerror(ret));
+ break;
+ }
+
+ /* Got a message. Now unpack it */
+ ret = bcmbal_obj_msg_unpack(msg, &unpacked_msg);
+ bcmos_msg_free(msg); /* release packed message. It is no longer needed */
+ if (BCM_ERR_OK != ret)
+ {
+ bcmos_printf("%s: bcmbal_obj_msg_unpack (error:%s)\n",
+ __FUNCTION__, bcmos_strerror(ret));
+ break;
+ }
+
+ /* If message was allocated in unpack - assign it */
+ if (! *msg_payload)
+ *msg_payload = bcmbal_payload_ptr_get(unpacked_msg);
+
+ } while (0);
+
+ return ret;
+}
+
+int32_t bcmbal_bal_msg_hdr_get_packed_length(void)
+{
+ return 21; /* See bcmbal_bal_msg_hdr_pack() */
+}
+
+static int32_t bcmbal_bal_msg_hdr_get_ex_id_offset(void)
+{
+ return 16; /* See bcmbal_bal_msg_hdr_pack() */
+}
+
+/** Pack a BAL message header to a byte stream */
+bcmos_errno bcmbal_bal_msg_hdr_pack(const bal_comm_msg_hdr *msg, bcmbal_buf *buf)
+{
+ bcmos_bool ret;
+
+ /* bcmos_msg header pack... (8 bytes post-pack) */
+ ret = bcmbal_buf_write_u32(buf, buf->len);
+
+ ret = ret && bcmbal_buf_write_u16(buf, (uint16_t)msg->m.type);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->m.instance);
+ ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->m.sender);
+
+ /* ...and then the rest of the header (15 bytes post-pack) */
+ ret = ret && bcmbal_buf_write_u8(buf, msg->version_major);
+ ret = ret && bcmbal_buf_write_u8(buf, msg->version_minor);
+ ret = ret && bcmbal_buf_write_u32(buf, msg->msg_id); /* the msg_id cannot be compressed */
+ ret = ret && bcmbal_buf_write_u16(buf, (uint16_t)msg->msg_type);
+ ret = ret && bcmbal_buf_write_u32(buf, msg->ex_id);
+ ret = ret && bcmbal_buf_write_u8(buf, msg->sender);
+
+ return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
+}
+
+/** Unpack a BAL message header from a byte stream */
+bcmos_errno bcmbal_bal_msg_hdr_unpack(bal_comm_msg_hdr *msg, bcmbal_buf *buf)
+{
+ uint16_t m_type;
+ uint8_t m_instance;
+ uint8_t m_sender;
+ uint32_t m_size;
+
+ uint8_t version_major;
+ uint8_t version_minor;
+ uint32_t msg_id;
+ uint16_t msg_type;
+ uint32_t ex_id;
+ uint8_t sender;
+
+ bcmos_bool ret;
+
+ ret = bcmbal_buf_read_u32(buf, &m_size);
+ ret = ret && bcmbal_buf_read_u16(buf, &m_type);
+ ret = ret && bcmbal_buf_read_u8(buf, &m_instance);
+ ret = ret && bcmbal_buf_read_u8(buf, &m_sender);
+
+ ret = ret && bcmbal_buf_read_u8(buf, &version_major);
+ ret = ret && bcmbal_buf_read_u8(buf, &version_minor);
+ ret = ret && bcmbal_buf_read_u32(buf, &msg_id);
+ ret = ret && bcmbal_buf_read_u16(buf, &msg_type);
+ ret = ret && bcmbal_buf_read_u32(buf, &ex_id);
+ ret = ret && bcmbal_buf_read_u8(buf, &sender);
+
+ if (ret)
+ {
+ msg->m.type = (bcmos_msg_id)m_type;
+ msg->m.instance = (bcmos_msg_instance)m_instance;
+ msg->m.sender = (bcmos_module_id)m_sender;
+ msg->m.size = m_size;
+
+ msg->version_major = version_major;
+ msg->version_minor = version_minor;
+ msg->msg_id = msg_id;
+ msg->msg_type = msg_type;
+ msg->ex_id = ex_id;
+ msg->sender = sender;
+ }
+
+ return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
+}
+
+/** Peek exchange_id in the received message without unpacking */
+bcmos_errno bcmbal_bal_msg_peek_ex_id(bcmos_msg *msg, uint32_t *ex_id)
+{
+ bcmbal_buf buf;
+ if (msg->size < bcmbal_bal_msg_hdr_get_packed_length())
+ return BCM_ERR_INTERNAL;
+ bcmbal_buf_init(&buf, msg->size, msg->data);
+ bcmolt_buf_set_pos(&buf, bcmbal_bal_msg_hdr_get_ex_id_offset());
+ bcmbal_buf_read_u32(&buf, ex_id);
+ return BCM_ERR_OK;
+}
+
+
+
diff --git a/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.c b/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.c
new file mode 100644
index 0000000..519af97
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.c
@@ -0,0 +1,558 @@
+#include <bcmos_system.h>
+#include <bal_msg.h>
+#include "bal_obj_msg_pack_unpack.h"
+
+typedef uint32_t (*bcmbal_func_packed_len) (void *this, bcmbal_presence_mask fields_present);
+typedef bcmos_bool (*bcmbal_func_pack) (void *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
+typedef bcmos_bool (*bcmbal_func_unpack) (void *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
+typedef bcmos_bool (*bcmbal_func_mem_scan) (bcmbal_buf * buf, uint32_t * extra_mem, bcmbal_presence_mask fields_present);
+
+/******************************************************************************/
+typedef struct bcmbal_group_info
+{
+ bcmbal_obj_id obj_type;
+ bcmbal_mgt_group group;
+ uint16_t subgroup;
+ uint32_t size;
+ uint32_t container_size; /* sizeof() the key/data container struct (0 for key groups) */
+ uint32_t data_offset; /* offsetof() data field within container struct (0 for key groups) */
+ bcmbal_func_packed_len get_packed_length;
+ bcmbal_func_pack pack;
+ bcmbal_func_unpack unpack;
+ bcmbal_func_mem_scan mem_scan;
+} bcmbal_group_info;
+
+/******************************************************************************/
+typedef struct bcmbal_group_ids
+{
+ uint32_t subgroup_count;
+ bcmbal_obj_group_id *subgroup_ids;
+} bcmbal_group_ids;
+
+/******************************************************************************/
+typedef struct bcmbal_instance_info
+{
+ int8_t offset;
+ int8_t size;
+} bcmbal_instance_info;
+
+/******************************************************************************/
+static bcmbal_group_info group_info_access_terminal_key = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_access_terminal_key), 0, 0, (bcmbal_func_packed_len) bcmbal_access_terminal_key_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_key_pack, (bcmbal_func_unpack) bcmbal_access_terminal_key_unpack, bcmbal_access_terminal_key_scan };
+static bcmbal_group_info group_info_access_terminal_cfg = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_access_terminal_cfg_data), sizeof(bcmbal_access_terminal_cfg), offsetof(bcmbal_access_terminal_cfg, data), (bcmbal_func_packed_len) bcmbal_access_terminal_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_cfg_data_pack, (bcmbal_func_unpack) bcmbal_access_terminal_cfg_data_unpack, bcmbal_access_terminal_cfg_data_scan };
+static bcmbal_group_info group_info_access_terminal_ind = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_access_terminal_ind_data), sizeof(bcmbal_access_terminal_ind), offsetof(bcmbal_access_terminal_ind, data), (bcmbal_func_packed_len) bcmbal_access_terminal_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_ind_data_pack, (bcmbal_func_unpack) bcmbal_access_terminal_ind_data_unpack, bcmbal_access_terminal_ind_data_scan };
+static bcmbal_group_info group_info_flow_key = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_flow_key), 0, 0, (bcmbal_func_packed_len) bcmbal_flow_key_get_packed_length, (bcmbal_func_pack) bcmbal_flow_key_pack, (bcmbal_func_unpack) bcmbal_flow_key_unpack, bcmbal_flow_key_scan };
+static bcmbal_group_info group_info_flow_cfg = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_flow_cfg_data), sizeof(bcmbal_flow_cfg), offsetof(bcmbal_flow_cfg, data), (bcmbal_func_packed_len) bcmbal_flow_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_cfg_data_pack, (bcmbal_func_unpack) bcmbal_flow_cfg_data_unpack, bcmbal_flow_cfg_data_scan };
+static bcmbal_group_info group_info_flow_stat = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_flow_stat_data), sizeof(bcmbal_flow_stat), offsetof(bcmbal_flow_stat, data), (bcmbal_func_packed_len) bcmbal_flow_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_stat_data_pack, (bcmbal_func_unpack) bcmbal_flow_stat_data_unpack, bcmbal_flow_stat_data_scan };
+static bcmbal_group_info group_info_flow_ind = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_flow_ind_data), sizeof(bcmbal_flow_ind), offsetof(bcmbal_flow_ind, data), (bcmbal_func_packed_len) bcmbal_flow_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_ind_data_pack, (bcmbal_func_unpack) bcmbal_flow_ind_data_unpack, bcmbal_flow_ind_data_scan };
+static bcmbal_group_info group_info_group_key = { BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_group_key), 0, 0, (bcmbal_func_packed_len) bcmbal_group_key_get_packed_length, (bcmbal_func_pack) bcmbal_group_key_pack, (bcmbal_func_unpack) bcmbal_group_key_unpack, bcmbal_group_key_scan };
+static bcmbal_group_info group_info_group_cfg = { BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_group_cfg_data), sizeof(bcmbal_group_cfg), offsetof(bcmbal_group_cfg, data), (bcmbal_func_packed_len) bcmbal_group_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_group_cfg_data_pack, (bcmbal_func_unpack) bcmbal_group_cfg_data_unpack, bcmbal_group_cfg_data_scan };
+static bcmbal_group_info group_info_interface_key = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_interface_key), 0, 0, (bcmbal_func_packed_len) bcmbal_interface_key_get_packed_length, (bcmbal_func_pack) bcmbal_interface_key_pack, (bcmbal_func_unpack) bcmbal_interface_key_unpack, bcmbal_interface_key_scan };
+static bcmbal_group_info group_info_interface_cfg = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_interface_cfg_data), sizeof(bcmbal_interface_cfg), offsetof(bcmbal_interface_cfg, data), (bcmbal_func_packed_len) bcmbal_interface_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_cfg_data_pack, (bcmbal_func_unpack) bcmbal_interface_cfg_data_unpack, bcmbal_interface_cfg_data_scan };
+static bcmbal_group_info group_info_interface_stat = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_interface_stat_data), sizeof(bcmbal_interface_stat), offsetof(bcmbal_interface_stat, data), (bcmbal_func_packed_len) bcmbal_interface_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_stat_data_pack, (bcmbal_func_unpack) bcmbal_interface_stat_data_unpack, bcmbal_interface_stat_data_scan };
+static bcmbal_group_info group_info_interface_ind = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_interface_ind_data), sizeof(bcmbal_interface_ind), offsetof(bcmbal_interface_ind, data), (bcmbal_func_packed_len) bcmbal_interface_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_ind_data_pack, (bcmbal_func_unpack) bcmbal_interface_ind_data_unpack, bcmbal_interface_ind_data_scan };
+static bcmbal_group_info group_info_packet_key = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_packet_key), 0, 0, (bcmbal_func_packed_len) bcmbal_packet_key_get_packed_length, (bcmbal_func_pack) bcmbal_packet_key_pack, (bcmbal_func_unpack) bcmbal_packet_key_unpack, bcmbal_packet_key_scan };
+static bcmbal_group_info group_info_packet_cfg = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_packet_cfg_data), sizeof(bcmbal_packet_cfg), offsetof(bcmbal_packet_cfg, data), (bcmbal_func_packed_len) bcmbal_packet_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_packet_cfg_data_pack, (bcmbal_func_unpack) bcmbal_packet_cfg_data_unpack, bcmbal_packet_cfg_data_scan };
+static bcmbal_group_info group_info_packet_ind = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_packet_ind_data), sizeof(bcmbal_packet_ind), offsetof(bcmbal_packet_ind, data), (bcmbal_func_packed_len) bcmbal_packet_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_packet_ind_data_pack, (bcmbal_func_unpack) bcmbal_packet_ind_data_unpack, bcmbal_packet_ind_data_scan };
+static bcmbal_group_info group_info_subscriber_terminal_key = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_subscriber_terminal_key), 0, 0, (bcmbal_func_packed_len) bcmbal_subscriber_terminal_key_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_key_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_key_unpack, bcmbal_subscriber_terminal_key_scan };
+static bcmbal_group_info group_info_subscriber_terminal_cfg = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_subscriber_terminal_cfg_data), sizeof(bcmbal_subscriber_terminal_cfg), offsetof(bcmbal_subscriber_terminal_cfg, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_cfg_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_cfg_data_unpack, bcmbal_subscriber_terminal_cfg_data_scan };
+static bcmbal_group_info group_info_subscriber_terminal_stat = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_subscriber_terminal_stat_data), sizeof(bcmbal_subscriber_terminal_stat), offsetof(bcmbal_subscriber_terminal_stat, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_stat_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_stat_data_unpack, bcmbal_subscriber_terminal_stat_data_scan };
+static bcmbal_group_info group_info_subscriber_terminal_ind = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_subscriber_terminal_ind_data), sizeof(bcmbal_subscriber_terminal_ind), offsetof(bcmbal_subscriber_terminal_ind, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_ind_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_ind_data_unpack, bcmbal_subscriber_terminal_ind_data_scan };
+static bcmbal_group_info group_info_tm_queue_key = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_tm_queue_key), 0, 0, (bcmbal_func_packed_len) bcmbal_tm_queue_key_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_key_pack, (bcmbal_func_unpack) bcmbal_tm_queue_key_unpack, bcmbal_tm_queue_key_scan };
+static bcmbal_group_info group_info_tm_queue_cfg = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_tm_queue_cfg_data), sizeof(bcmbal_tm_queue_cfg), offsetof(bcmbal_tm_queue_cfg, data), (bcmbal_func_packed_len) bcmbal_tm_queue_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_cfg_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_cfg_data_unpack, bcmbal_tm_queue_cfg_data_scan };
+static bcmbal_group_info group_info_tm_queue_stat = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_tm_queue_stat_data), sizeof(bcmbal_tm_queue_stat), offsetof(bcmbal_tm_queue_stat, data), (bcmbal_func_packed_len) bcmbal_tm_queue_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_stat_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_stat_data_unpack, bcmbal_tm_queue_stat_data_scan };
+static bcmbal_group_info group_info_tm_queue_ind = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_tm_queue_ind_data), sizeof(bcmbal_tm_queue_ind), offsetof(bcmbal_tm_queue_ind, data), (bcmbal_func_packed_len) bcmbal_tm_queue_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_ind_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_ind_data_unpack, bcmbal_tm_queue_ind_data_scan };
+static bcmbal_group_info group_info_tm_sched_key = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_tm_sched_key), 0, 0, (bcmbal_func_packed_len) bcmbal_tm_sched_key_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_key_pack, (bcmbal_func_unpack) bcmbal_tm_sched_key_unpack, bcmbal_tm_sched_key_scan };
+static bcmbal_group_info group_info_tm_sched_cfg = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_tm_sched_cfg_data), sizeof(bcmbal_tm_sched_cfg), offsetof(bcmbal_tm_sched_cfg, data), (bcmbal_func_packed_len) bcmbal_tm_sched_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_cfg_data_pack, (bcmbal_func_unpack) bcmbal_tm_sched_cfg_data_unpack, bcmbal_tm_sched_cfg_data_scan };
+static bcmbal_group_info group_info_tm_sched_ind = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_tm_sched_ind_data), sizeof(bcmbal_tm_sched_ind), offsetof(bcmbal_tm_sched_ind, data), (bcmbal_func_packed_len) bcmbal_tm_sched_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_ind_data_pack, (bcmbal_func_unpack) bcmbal_tm_sched_ind_data_unpack, bcmbal_tm_sched_ind_data_scan };
+static bcmbal_group_info *group_info[] = { &group_info_access_terminal_key, &group_info_access_terminal_cfg, &group_info_access_terminal_ind, &group_info_flow_key, &group_info_flow_cfg, &group_info_flow_stat, &group_info_flow_ind, &group_info_group_key, &group_info_group_cfg, &group_info_interface_key, &group_info_interface_cfg, &group_info_interface_stat, &group_info_interface_ind, &group_info_packet_key, &group_info_packet_cfg, &group_info_packet_ind, &group_info_subscriber_terminal_key, &group_info_subscriber_terminal_cfg, &group_info_subscriber_terminal_stat, &group_info_subscriber_terminal_ind, &group_info_tm_queue_key, &group_info_tm_queue_cfg, &group_info_tm_queue_stat, &group_info_tm_queue_ind, &group_info_tm_sched_key, &group_info_tm_sched_cfg, &group_info_tm_sched_ind };
+static bcmbal_obj_group_id group_ids_access_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_KEY };
+static bcmbal_obj_group_id group_ids_access_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_CFG };
+static bcmbal_obj_group_id group_ids_access_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_IND };
+static bcmbal_obj_group_id group_ids_flow_key[] = { BCMBAL_OBJ_GROUP_ID_FLOW_KEY };
+static bcmbal_obj_group_id group_ids_flow_cfg[] = { BCMBAL_OBJ_GROUP_ID_FLOW_CFG };
+static bcmbal_obj_group_id group_ids_flow_stat[] = { BCMBAL_OBJ_GROUP_ID_FLOW_STAT };
+static bcmbal_obj_group_id group_ids_flow_auto[] = { BCMBAL_OBJ_GROUP_ID_FLOW_IND };
+static bcmbal_obj_group_id group_ids_group_key[] = { BCMBAL_OBJ_GROUP_ID_GROUP_KEY };
+static bcmbal_obj_group_id group_ids_group_cfg[] = { BCMBAL_OBJ_GROUP_ID_GROUP_CFG };
+static bcmbal_obj_group_id group_ids_interface_key[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_KEY };
+static bcmbal_obj_group_id group_ids_interface_cfg[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_CFG };
+static bcmbal_obj_group_id group_ids_interface_stat[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_STAT };
+static bcmbal_obj_group_id group_ids_interface_auto[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_IND };
+static bcmbal_obj_group_id group_ids_packet_key[] = { BCMBAL_OBJ_GROUP_ID_PACKET_KEY };
+static bcmbal_obj_group_id group_ids_packet_cfg[] = { BCMBAL_OBJ_GROUP_ID_PACKET_CFG };
+static bcmbal_obj_group_id group_ids_packet_auto[] = { BCMBAL_OBJ_GROUP_ID_PACKET_IND };
+static bcmbal_obj_group_id group_ids_subscriber_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_KEY };
+static bcmbal_obj_group_id group_ids_subscriber_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_CFG };
+static bcmbal_obj_group_id group_ids_subscriber_terminal_stat[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_STAT };
+static bcmbal_obj_group_id group_ids_subscriber_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_IND };
+static bcmbal_obj_group_id group_ids_tm_queue_key[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_KEY };
+static bcmbal_obj_group_id group_ids_tm_queue_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_CFG };
+static bcmbal_obj_group_id group_ids_tm_queue_stat[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_STAT };
+static bcmbal_obj_group_id group_ids_tm_queue_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_IND };
+static bcmbal_obj_group_id group_ids_tm_sched_key[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_KEY };
+static bcmbal_obj_group_id group_ids_tm_sched_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_CFG };
+static bcmbal_obj_group_id group_ids_tm_sched_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_IND };
+static bcmbal_group_ids group_ids_obj_access_terminal[] = { { 1, group_ids_access_terminal_key }, { 1, group_ids_access_terminal_cfg }, { 0, NULL }, { 1, group_ids_access_terminal_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_flow[] = { { 1, group_ids_flow_key }, { 1, group_ids_flow_cfg }, { 1, group_ids_flow_stat }, { 1, group_ids_flow_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_group[] = { { 1, group_ids_group_key }, { 1, group_ids_group_cfg }, { 0, NULL }, { 0, NULL }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_interface[] = { { 1, group_ids_interface_key }, { 1, group_ids_interface_cfg }, { 1, group_ids_interface_stat }, { 1, group_ids_interface_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_packet[] = { { 1, group_ids_packet_key }, { 1, group_ids_packet_cfg }, { 0, NULL }, { 1, group_ids_packet_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_subscriber_terminal[] = { { 1, group_ids_subscriber_terminal_key }, { 1, group_ids_subscriber_terminal_cfg }, { 1, group_ids_subscriber_terminal_stat }, { 1, group_ids_subscriber_terminal_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_tm_queue[] = { { 1, group_ids_tm_queue_key }, { 1, group_ids_tm_queue_cfg }, { 1, group_ids_tm_queue_stat }, { 1, group_ids_tm_queue_auto }, { 0, NULL } };
+static bcmbal_group_ids group_ids_obj_tm_sched[] = { { 1, group_ids_tm_sched_key }, { 1, group_ids_tm_sched_cfg }, { 0, NULL }, { 1, group_ids_tm_sched_auto }, { 0, NULL } };
+static bcmbal_group_ids *group_ids[] = { group_ids_obj_access_terminal, group_ids_obj_flow, group_ids_obj_group, group_ids_obj_interface, group_ids_obj_packet, group_ids_obj_subscriber_terminal, group_ids_obj_tm_queue, group_ids_obj_tm_sched };
+static bcmbal_presence_mask readonly_prop_mask[] = { (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE), 1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS, (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS) | (1ULL << BCMBAL_GROUP_CFG_ID_OWNER), (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST), 0, (((1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST), (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE) | (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT), ((1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE) | (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) | (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS) };
+static bcmbal_instance_info instance_info[] = { { offsetof(bcmbal_access_terminal_key, access_term_id), sizeof(bcmbal_access_id) }, { offsetof(bcmbal_flow_key, flow_id), sizeof(bcmbal_flow_id) }, { offsetof(bcmbal_group_key, group_id), sizeof(bcmbal_group_id) }, { offsetof(bcmbal_interface_key, intf_id), sizeof(uint32_t) }, { offsetof(bcmbal_packet_key, reserved), sizeof(uint32_t) }, { offsetof(bcmbal_subscriber_terminal_key, sub_term_id), sizeof(bcmbal_sub_id) }, { offsetof(bcmbal_tm_queue_key, id), sizeof(bcmbal_tm_queue_id) }, { offsetof(bcmbal_tm_sched_key, id), sizeof(bcmbal_tm_sched_id) } };
+
+/** Converts a specific object type, group and subgroup into a generic group ID.
+ *
+ * \param obj The object type that corresponds to the group ID.
+ * \param group The group type that corresponds to the group ID.
+ * \param subgroup The subgroup index that corresponds to the group ID.
+ * \param group_id The generic group ID.
+ * \return An error code or BCM_ERR_OK for success.
+ */
+static bcmos_errno _bcmbal_obj_group_id_combine(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, bcmbal_obj_group_id *group_id)
+{
+ if ((obj >= BCMBAL_OBJ_ID__NUM_OF) || (group >= BCMBAL_MGT_GROUP__NUM_OF) || (group_ids[obj] == NULL) || (subgroup >= group_ids[obj][group].subgroup_count))
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ *group_id = group_ids[obj][group].subgroup_ids[subgroup];
+ return BCM_ERR_OK;
+}
+
+/******************************************************************************/
+static bcmos_bool _bcmbal_get_group_info(const bcmbal_obj *msg, bcmbal_group_info **group, bcmbal_group_info **key)
+{
+ bcmbal_obj_group_id group_id;
+ bcmbal_obj_group_id key_id;
+ bcmos_errno err;
+
+ err = _bcmbal_obj_group_id_combine(msg->obj_type, msg->group, msg->subgroup, &group_id);
+ if (err != BCM_ERR_OK)
+ {
+ return BCMOS_FALSE;
+ }
+
+ err = _bcmbal_obj_group_id_combine(msg->obj_type, BCMBAL_MGT_GROUP_KEY, 0, &key_id);
+ if (err != BCM_ERR_OK)
+ {
+ return BCMOS_FALSE;
+ }
+
+ *group = group_info[group_id];
+ *key = group_info[key_id];
+ return BCMOS_TRUE;
+}
+
+/** Gets the number of bytes a message would occupy when packed.
+ *
+ * \param msg The message to scan.
+ * \return The size in bytes if > 0, or an error as defined in bcmos_errno.
+ */
+static int32_t _bcmbal_obj_msg_packed_length_get(bcmbal_obj *msg)
+{
+ uint8_t *key_ptr;
+ bcmbal_group_info *group;
+ bcmbal_group_info *key;
+ int32_t ret;
+
+ /* First, get the total length of the packed BAL msg header and the packed BAL object header */
+ ret = bcmbal_bal_msg_hdr_get_packed_length() + bcmbal_obj_msg_hdr_get_packed_length();
+
+ if (!_bcmbal_get_group_info(msg, &group, &key))
+ {
+ return (int32_t) BCM_ERR_MSG_ERROR;
+ }
+
+ key_ptr = (uint8_t *) (msg + 1);
+
+ /* Add the length of the packed key */
+ ret += key->get_packed_length(key_ptr, BCMBAL_PRESENCE_MASK_ALL);
+
+ /* Add the length of the packed object itself (for those attributes that have been specified, if any) */
+ if (bcmbal_obj_msg_should_pack_data(msg) && (group->get_packed_length != NULL))
+ {
+ uint8_t *data_ptr = (uint8_t *) ((long)msg + group->data_offset);
+ ret += group->get_packed_length(data_ptr, msg->presence_mask);
+ }
+
+ return ret;
+}
+
+/** Packs a message to a byte stream.
+ *
+ * \param msg The message to pack.
+ * \param buf The stream to pack into.
+ * \return An error code or BCM_ERR_OK for success.
+ */
+static bcmos_errno _bcmbal_obj_msg_pack(bal_comm_msg_hdr *msg, bcmbal_buf *buf)
+{
+ uint8_t *key_ptr;
+ bcmos_errno err;
+ bcmbal_group_info *group;
+ bcmbal_group_info *key;
+ bcmbal_obj *bal_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(msg);
+
+ if (!_bcmbal_get_group_info(bal_obj, &group, &key))
+ {
+ return BCM_ERR_MSG_ERROR;
+ }
+
+ err = bcmbal_bal_msg_hdr_pack(msg, buf);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ err = bcmbal_obj_msg_hdr_pack(bal_obj, buf);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ key_ptr = (uint8_t *) (bal_obj + 1);
+ if (!key->pack(key_ptr, buf, BCMBAL_PRESENCE_MASK_ALL))
+ {
+ return BCM_ERR_OVERFLOW;
+ }
+
+ if (bcmbal_obj_msg_should_pack_data(bal_obj) && (group->pack != NULL))
+ {
+ uint8_t *data_ptr = (uint8_t *) ((long)bal_obj + group->data_offset);
+ if (!group->pack(data_ptr, buf, bal_obj->presence_mask))
+ {
+ return BCM_ERR_OVERFLOW;
+ }
+ }
+
+ return err;
+}
+
+/* scan the input buffer to determine how much memory will be required to unpack variable-sized lists */
+static bcmos_errno bcmbal_obj_msg_list_mem_scan(bcmbal_buf *buf, const bcmbal_obj *hdr, const bcmbal_group_info *group, const bcmbal_group_info *key, uint32_t *size)
+{
+ uint32_t pos_before_scan = bcmbal_buf_get_used(buf);
+
+ if (!key->mem_scan(buf, size, BCMBAL_PRESENCE_MASK_ALL))
+ {
+ return BCM_ERR_OVERFLOW;
+ }
+
+ if (bcmbal_obj_msg_should_pack_data(hdr) && (group->mem_scan != NULL) && !group->mem_scan(buf, size, hdr->presence_mask))
+ {
+ return BCM_ERR_OVERFLOW;
+ }
+
+ if (!bcmbal_buf_rewind(buf, bcmbal_buf_get_used(buf) - pos_before_scan))
+ {
+ return BCM_ERR_OVERFLOW;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/** Unpacks a message from a byte stream.
+ *
+ * This unpacks the message from the packed form into the struct following the "unpacked" pointer. There are several
+ * special cases:
+ *
+ * if *unpacked == NULL:
+ * *unpacked will be allocated dynamically via bcmos_calloc, in a contiguous block of memory with the struct
+ * itself followed by the memory required for all variable-sized lists.
+ *
+ * if (*unpacked)->list_buf != NULL:
+ * When a variable-length list is encountered in the input stream, and the array field we're unpacking into is NULL,
+ * memory will be allocated starting from (*unpacked)->list_buf. If multiple such lists exist, they will share this
+ * buffer. If the (*unpacked)->list_buf_size is not large enough, this will return BCM_ERR_INSUFFICIENT_LIST_MEM.
+ *
+ * \param buf The stream to unpack from.
+ * \param unpacked A pointer to the resulting unpacked BAL message starting at the bal header.
+ * \return The number of bytes unpacked if > 0, or an error as defined in bcmos_errno.
+ */
+static int32_t _bcmbal_obj_msg_unpack(bcmbal_buf *buf, bal_comm_msg_hdr **unpacked)
+{
+ bcmbal_obj bal_obj_hdr;
+ bal_comm_msg_hdr *bal_msg_hdr = &bal_obj_hdr.comm_hdr;
+ bcmos_errno err;
+ bcmbal_group_info *group;
+ bcmbal_group_info *key;
+ bcmos_bool did_malloc = BCMOS_FALSE;
+ uint8_t *key_ptr;
+ void *list_mem = NULL;
+ void **list_mem_ptr = NULL;
+ uint32_t size = 0;
+ bcmbal_obj *unpacked_bal_obj;
+
+ /* Preserve header fields that are not packed */
+ if (*unpacked != NULL)
+ memcpy(&bal_obj_hdr, bcmbal_payload_ptr_get(*unpacked), sizeof(bal_obj_hdr));
+ else
+ memset(&bal_obj_hdr, 0, sizeof(bal_obj_hdr));
+
+ err = bcmbal_bal_msg_hdr_unpack(bal_msg_hdr, buf);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ err = bcmbal_obj_msg_hdr_unpack(&bal_obj_hdr, buf);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ if (!_bcmbal_get_group_info(&bal_obj_hdr, &group, &key))
+ {
+ return BCM_ERR_MSG_ERROR;
+ }
+
+ /* If the caller did not allocate a space to unpack into, then alloc one */
+ if (*unpacked == NULL)
+ {
+ size = group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
+
+ err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ /* allocate a bal msg header, and a BAL object with data length of "size" */
+ unpacked_bal_obj = bcmbal_msg_calloc(size);
+ if (unpacked_bal_obj == NULL)
+ {
+ return BCM_ERR_NOMEM;
+ }
+
+ *unpacked = bcmbal_bal_hdr_get(unpacked_bal_obj);
+
+ list_mem = (uint8_t *)unpacked_bal_obj + group->container_size;
+ list_mem_ptr = &list_mem;
+ did_malloc = BCMOS_TRUE;
+ }
+ else
+ {
+ unpacked_bal_obj = bcmbal_payload_ptr_get(*unpacked);
+
+ if (unpacked_bal_obj->list_buf != NULL)
+ {
+ err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
+ if (err != BCM_ERR_OK)
+ {
+ return err;
+ }
+
+ if (size > unpacked_bal_obj->list_buf_size)
+ {
+ return BCM_ERR_INSUFFICIENT_LIST_MEM;
+ }
+
+ list_mem = unpacked_bal_obj->list_buf;
+ list_mem_ptr = &list_mem;
+ }
+
+ size += group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
+ }
+
+ /* copy the bal message header into the unpack buffer */
+ bal_msg_hdr->m.size = size - sizeof(bcmos_msg);
+
+ /* copy the bal object header into the unpack buffer */
+ *unpacked_bal_obj = bal_obj_hdr;
+
+ key_ptr = (uint8_t *) (unpacked_bal_obj + 1);
+ if (!key->unpack(key_ptr, buf, list_mem_ptr, BCMBAL_PRESENCE_MASK_ALL))
+ {
+ if (did_malloc)
+ {
+ bcmbal_msg_free(unpacked_bal_obj);
+ *unpacked = NULL;
+ }
+
+ return BCM_ERR_OVERFLOW;
+ }
+
+ if (bcmbal_obj_msg_should_pack_data(&bal_obj_hdr))
+ {
+ uint8_t *data_ptr = (uint8_t *)unpacked_bal_obj + group->data_offset;
+ if ((group->unpack != NULL) && !group->unpack(data_ptr, buf, list_mem_ptr, unpacked_bal_obj->presence_mask))
+ {
+ if (did_malloc)
+ {
+ bcmbal_msg_free(unpacked_bal_obj);
+ *unpacked = NULL;
+ }
+
+ return BCM_ERR_OVERFLOW;
+ }
+ }
+
+ return size;
+}
+
+bcmos_errno bcmbal_obj_msg_pack(bal_comm_msg_hdr *unpacked_bal_msg, /* unpacked msg */ bcmos_msg **packed_msg) /* packed message */
+{
+ bcmbal_buf buf;
+ bcmos_errno ret;
+ bcmbal_obj *unpacked_obj;
+ int32_t packed_payload_len;
+ uint8_t *packed_payload;
+ bcmos_msg *os_msg;
+
+ *packed_msg = NULL; /* Initialization */
+
+ /* Recover a pointer to the UNPACKED bal object */
+ unpacked_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(unpacked_bal_msg);
+
+ /* Calculate packed length */
+ packed_payload_len = _bcmbal_obj_msg_packed_length_get(unpacked_obj);
+ if (packed_payload_len < 0) return (bcmos_errno) packed_payload_len;
+
+ os_msg = (bcmos_msg *)bcmos_alloc(packed_payload_len + sizeof(bcmos_msg));
+
+ if (NULL == os_msg) return BCM_ERR_NORES;
+
+ memset(os_msg, 0, sizeof(bcmos_msg));
+ packed_payload = (uint8_t *) (os_msg + 1);
+ bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
+ if (BCM_ERR_OK != (ret = _bcmbal_obj_msg_pack(unpacked_bal_msg, &buf)))
+ {
+ bcmos_free(os_msg);
+ return ret;
+ }
+
+ os_msg->data = packed_payload;
+ os_msg->size = packed_payload_len;
+ os_msg->type = unpacked_bal_msg->m.type;
+ os_msg->instance = unpacked_bal_msg->m.instance;
+ os_msg->sender = unpacked_bal_msg->m.sender;
+ *packed_msg = os_msg;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno bcmbal_obj_msg_unpack(bcmos_msg *packed_msg, /* packed message */ bal_comm_msg_hdr **unpacked_bal_msg) /* the unpacked bal msg */
+{
+ bcmbal_buf buf;
+ int32_t unpacked_len;
+ bal_comm_msg_hdr *bal_msg_hdr = *unpacked_bal_msg;
+ uint8_t *packed_payload = packed_msg->data;
+ uint32_t packed_payload_len = packed_msg->size;
+
+ bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
+
+ unpacked_len = _bcmbal_obj_msg_unpack(&buf, &bal_msg_hdr);
+
+ if (unpacked_len < 0)
+ {
+ return (bcmos_errno) unpacked_len;
+ }
+
+ if (((bcmbal_obj *) (bcmbal_payload_ptr_get(bal_msg_hdr)))->version != BCMBAL_OBJ_VERSION)
+ {
+ bcmos_printf("Illegal BAL object version detected. Found: %d, Should be:%d\n", ((bcmbal_obj *) (bcmbal_payload_ptr_get(bal_msg_hdr)))->version, BCMBAL_OBJ_VERSION);
+
+ return BCM_ERR_PARSE;
+ }
+
+ *unpacked_bal_msg = bal_msg_hdr;
+
+ /* NOTE: Do NOT Free the passed in original received message! */
+ return BCM_ERR_OK;
+}
+
+bcmos_errno _bcmbal_obj_group_id_split(bcmbal_obj_group_id group_id, bcmbal_obj_id *obj, bcmbal_mgt_group *group, uint16_t *subgroup)
+{
+ if ((group_id >= BCMBAL_OBJ_GROUP_ID__NUM_OF) || (group_info[group_id] == NULL))
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ *obj = group_info[group_id]->obj_type;
+ *group = group_info[group_id]->group;
+ *subgroup = group_info[group_id]->subgroup;
+ return BCM_ERR_OK;
+}
+
+/******************************************************************************/
+uint8_t bcmbal_obj_msg_instance(const bcmbal_obj *msg)
+{
+ const void *val_ptr;
+
+ if (msg->obj_type >= BCMBAL_OBJ_ID__NUM_OF)
+ {
+ return 0;
+ }
+
+ if (instance_info[msg->obj_type].offset < 0)
+ {
+ return 0;
+ }
+
+ val_ptr = ((const uint8_t *)(msg + 1)) + instance_info[msg->obj_type].offset;
+
+ /** This is probably not the smartest way to do this... TODO: revisit */
+ switch (instance_info[msg->obj_type].size)
+ {
+ case 1:
+ return *((const uint8_t *)val_ptr);
+ case 2:
+ return (uint8_t) (*((const uint16_t *)val_ptr));
+ case 4:
+ return (uint8_t) (*((const uint32_t *)val_ptr));
+ case 8:
+ return (uint8_t) (*((const uint64_t *)val_ptr));
+ default:
+ return 0;
+ }
+}
+
+/******************************************************************************/
+bcmos_errno bcmbal_obj_msg_clone(bal_comm_msg_hdr **dest, bal_comm_msg_hdr *src)
+{
+ bcmos_errno err;
+ int32_t packed_obj_msg_len;
+ uint8_t *mem;
+ bcmbal_buf buf;
+
+ packed_obj_msg_len = _bcmbal_obj_msg_packed_length_get(bcmbal_payload_ptr_get(src));
+ if (packed_obj_msg_len < 0)
+ {
+ return (bcmos_errno) packed_obj_msg_len;
+ }
+
+ /* Allocate a BAL msg (this includes the BAL msg hdr PLUS the BAL object) */
+ mem = bcmos_calloc((uint32_t) packed_obj_msg_len);
+ if (mem == NULL)
+ {
+ return BCM_ERR_NOMEM;
+ }
+
+ bcmbal_buf_init(&buf, (uint32_t) packed_obj_msg_len, mem);
+ err = _bcmbal_obj_msg_pack(src, &buf);
+ if (err != BCM_ERR_OK)
+ {
+ bcmos_free(mem);
+ return err;
+ }
+
+ buf.curr = buf.start;
+ err = _bcmbal_obj_msg_unpack(&buf, dest);
+ bcmos_free(mem);
+ return err;
+}
+
+/******************************************************************************/
+bcmos_errno bcmbal_get_prop_readonly_mask(bcmbal_obj_id obj, bcmbal_presence_mask *mask)
+{
+ if (obj >= BCMBAL_OBJ_ID__NUM_OF)
+ {
+ return BCM_ERR_RANGE;
+ }
+
+ *mask = readonly_prop_mask[obj];
+ return BCM_ERR_OK;
+}
diff --git a/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.h b/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.h
new file mode 100644
index 0000000..1837a99
--- /dev/null
+++ b/bal_release/src/lib/libobjmsg/bal_obj_msg_pack_unpack.h
@@ -0,0 +1,51 @@
+#ifndef BAL_OBJ_MSG_PACK_UNPACK_H_
+#define BAL_OBJ_MSG_PACK_UNPACK_H_
+
+#include "bcmos_system.h"
+#include "bcmos_errno.h"
+#include "bal_model_types.h"
+#include "bal_model_funcs.h"
+
+
+bcmos_errno bcmbal_obj_msg_pack(bal_comm_msg_hdr *unpacked_bal_msg,/* unpacked msg */
+ bcmos_msg **packed_msg); /* packed message */
+
+bcmos_errno bcmbal_obj_msg_unpack(bcmos_msg *packed_msg, /* packed message */
+ bal_comm_msg_hdr **unpacked_bal_msg); /* the unpacked bal msg */
+
+/** Returns the instance number of a given message, as determined by the object key.
+ *
+ * \param msg The message to check.
+ * \return The instance number of the message.
+ */
+uint8_t bcmbal_obj_msg_instance(const bcmbal_obj *msg);
+
+/** Gets a mask of all readonly properties for an object's cfg group.
+ *
+ * \param obj The objecct to check.
+ * \param mask A mask of bits set to 1 per read-only property.
+ * \return An error code or BCM_ERR_OK for success.
+ */
+bcmos_errno bcmbal_get_prop_readonly_mask(bcmbal_obj_id obj, bcmbal_presence_mask *mask);
+
+/** Clones a message by packing it to a buffer then unpacking it into the destination message.
+ * This uses _bcmbal_obj_msg_unpack, so if *dest is NULL, memory will by allocated dynamically using bcmos_calloc.
+ *
+ * \param dest A pointer to the location in memory that will hold the cloned message.
+ * \param src The message that should be copied.
+ * \return An error code or BCM_ERR_OK for success.
+ */
+bcmos_errno bcmbal_obj_msg_clone(bal_comm_msg_hdr **dest, bal_comm_msg_hdr *src);
+
+/** Converts a generic group ID into a specific object type, group and subgroup.
+ *
+ * \param group_id The generic group ID.
+ * \param obj The object type that corresponds to the group ID.
+ * \param group The group type that corresponds to the group ID.
+ * \param subgroup The subgroup index that corresponds to the group ID.
+ * \return An error code or BCM_ERR_OK for success.
+ */
+bcmos_errno _bcmbal_obj_group_id_split(bcmbal_obj_group_id group_id, bcmbal_obj_id *obj, bcmbal_mgt_group *group, uint16_t *subgroup);
+
+
+#endif /* BAL_OBJ_MSG_PACK_UNPACK_H_ */
diff --git a/bal_release/src/lib/librscmgr/Makefile b/bal_release/src/lib/librscmgr/Makefile
new file mode 100644
index 0000000..d94cd45
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/Makefile
@@ -0,0 +1,37 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = rscmgr
+MOD_TYPE = lib
+MOD_DEPS = dev_log cli os_cli bal_api
+srcs = rsc_mgr.c rsc_mgr_common.c rsc_mgr_cli.c
+
+# XXX To break a circular dependency, we should avoid adding bal_core to MOD_DEPS
+EXTRA_CFLAGS += -I$(SRC_DIR)/../../core/main
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr.c b/bal_release/src/lib/librscmgr/rsc_mgr.c
new file mode 100644
index 0000000..bd8afec
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr.c
@@ -0,0 +1,922 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bcmolt_host_api.h>
+#include <bcm_dev_log.h>
+#include <bal_objs.h>
+#include <bal_api.h>
+#include <bal_cli.h>
+#include <bcmolt_math.h>
+#include <bcm_topo.h>
+#include "rsc_mgr_common.h"
+#include "rsc_mgr.h"
+
+#define GPON_NUM_OF_ALLOC_IDS 1024
+#define XGPON_NUM_OF_ALLOC_IDS 2048
+
+#define GPON_NUM_OF_GEM_PORT_IDS_PER_PON 4096
+#define XGPON_NUM_OF_GEM_PORT_IDS_PER_PON 8192
+
+#define RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, first_data_alloc_id) \
+ ((first_data_alloc_id) + (bcmolt_pon_alloc_id)(RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids - 1))
+#define RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, alloc_id, first_data_alloc_id) ( \
+ ((alloc_id) >= (first_data_alloc_id) && (alloc_id) <= RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, first_data_alloc_id)))
+#define RSC_MGR_ALLOC_ID_IS_VALID(pon_id, alloc_id, first_data_alloc_id) ( \
+ ((alloc_id) <= RSC_MGR_ALLOC_ID_LAST_DEFAULT(pon_id)) || \
+ RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, alloc_id, first_data_alloc_id))
+
+#define RSC_MGR_GEM_PORT_ID_LAST_DEFAULT(pon_id) ((bcmolt_pon_gem_port_id)(bcm_topo_pon_get_max_num_of_onus(pon_id) - 1))
+#define RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, first_data_port_id) \
+ ((first_data_port_id) + (bcmolt_pon_gem_port_id)(RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports - bcm_topo_pon_get_max_num_of_onus(pon_id) - 1))
+#define RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, gem_port_id, first_data_port_id) ( \
+ ((gem_port_id) >= (first_data_port_id) && (gem_port_id) <= RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, first_data_port_id)))
+#define RSC_MGR_GEM_PORT_ID_IS_VALID(pon_id, gem_port_id, first_data_port_id) ( \
+ ((gem_port_id) <= RSC_MGR_GEM_PORT_ID_LAST_DEFAULT(pon_id)) || \
+ RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, gem_port_id, first_data_port_id))
+
+#define RSC_MGR_FOR_EACH_ALLOC_INDEX(pon_id, alloc_index) \
+ for (alloc_index = (bcmolt_pon_alloc_index)0; alloc_index < (bcmolt_pon_alloc_index)RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids; alloc_index++)
+
+#define RSC_MGR_FOR_EACH_GEM_INDEX(pon_id, gem_port_index) \
+ for (gem_port_index = 0; (bcmolt_pon_gem_port_index)gem_port_index < (bcmolt_pon_gem_port_index)RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports; gem_port_index++)
+
+#define RSC_MGR_FOR_EACH_TM_SCHED_AUTO_INDEX(tm_sched_auto_index) \
+ for (tm_sched_auto_index = 0; (bcmbal_tm_sched_id_index)tm_sched_auto_index < (bcmbal_tm_sched_id_index)tm_context.num_of_tm_sched_auto_key_ids; tm_sched_auto_index++)
+
+/* Because GEM port 0 .. 127 are used for OMCI, we can start allocating from 128. But due to a bug in Maple A0, 128 .. 159 must not be used. So we start from 256. */
+#define MIN_BASE_GEM_PORT_ID_GPON 256
+
+#define NUM_OF_TM_SCHED_AUTO_KEY_IDS 2048
+#define MIN_BASE_TM_SCHED_AUTO_ID 2048
+
+
+rsc_mgr_context_t rsc_mgr_context;
+rsc_mgr_tm_context tm_context;
+
+
+static bcmos_errno rsc_mgr_alloc_validate_common(bcmbal_intf_id access_int_id);
+static bcmos_errno rsc_mgr_obj_get(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_obj **obj, dev_log_id log_id);
+static bcmos_errno rsc_mgr_obj_store_user_data(rsc_mgr_obj *obj, void *user_data);
+static bcmos_errno rsc_mgr_obj_remove_user_data(rsc_mgr_obj *obj, void *user_data);
+
+
+static bcmos_bool rsc_mgr_is_valid_data_alloc_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return (bcm_topo_pon_is_valid(pon_id) && RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, id, min_data_obj_id));
+}
+
+static rsc_mgr_obj_id rsc_mgr_get_last_data_alloc_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return (rsc_mgr_obj_id)(bcmolt_pon_alloc_id)RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, min_data_obj_id);
+}
+
+static bcmos_bool rsc_mgr_is_valid_data_gem_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return (bcm_topo_pon_is_valid(pon_id) && RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, id, min_data_obj_id));
+}
+
+static rsc_mgr_obj_id rsc_mgr_get_last_data_gem_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return (rsc_mgr_obj_id)(bcmolt_pon_gem_port_id)RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, min_data_obj_id);
+}
+static bcmos_bool rsc_mgr_is_valid_data_tm_sched_auto_id(rsc_mgr_obj_id id)
+{
+ return (id >= MIN_BASE_TM_SCHED_AUTO_ID && id < MIN_BASE_TM_SCHED_AUTO_ID + NUM_OF_TM_SCHED_AUTO_KEY_IDS);
+}
+
+static bcmos_bool rsc_mgr_is_valid_data_tm_sched_auto_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return rsc_mgr_is_valid_data_tm_sched_auto_id(id);
+}
+
+static rsc_mgr_obj_id rsc_mgr_get_last_data_tm_sched_auto_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id)
+{
+ return (rsc_mgr_obj_id)(min_data_obj_id + NUM_OF_TM_SCHED_AUTO_KEY_IDS - 1);
+}
+
+
+static bcmos_errno rsc_mgr_obj_alloc(bcmbal_intf_id access_int_id, rsc_mgr_obj_id *obj_id, uint32_t range_size, rsc_mgr_obj_type type, rsc_mgr_obj_rsc *obj_rsc, void *user_data, dev_log_id log_id)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+
+ if (range_size < RSC_MGR_MIN_RANGE_SIZE || range_size > RSC_MGR_MAX_RANGE_SIZE)
+ {
+ BCM_LOG(ERROR, log_id, "Range size must be in the range %u .. %u\n", RSC_MGR_MIN_RANGE_SIZE, RSC_MGR_MAX_RANGE_SIZE);
+ return BCM_ERR_PARM;
+ }
+
+ if (*obj_id)
+ {
+ rc = rsc_mgr_obj_get(access_int_id, *obj_id, obj_rsc, &obj, log_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ if (obj->range_size != range_size)
+ {
+ BCM_LOG(ERROR, log_id, "When reusing a range of %ss, range size (%d) must be exactly the same as the range from creation (%u)\n",
+ obj_rsc->obj_name, range_size, obj->range_size);
+ return BCM_ERR_PARM;
+ }
+
+ if (obj->type != type)
+ {
+ BCM_LOG(ERROR, log_id, "When reusing %ss, type (%d) must be exactly the same as the type from creation (%u)\n",
+ obj_rsc->obj_name, type, obj->type);
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ rsc_mgr_obj *base_obj;
+ rsc_mgr_obj *last_obj;
+ rsc_mgr_obj *obj_iter;
+
+ /* Find the first free range that fits ("first-fit" algorithm). */
+ TAILQ_FOREACH(obj_iter, &obj_rsc->free_objs, list)
+ {
+ if (range_size <= obj_iter->range_size)
+ break;
+ }
+ if (!obj_iter)
+ {
+ BCM_LOG(ERROR, log_id, "No free %ss\n", obj_rsc->obj_name);
+ return BCM_ERR_NORES;
+ }
+ *obj_id = obj_iter->id;
+
+ if (range_size < obj_iter->range_size)
+ {
+ /* Insert a smaller range (decrease by 'range_size') to the list of free objects. It will replace the old free range. */
+ base_obj = &obj_iter[range_size];
+ last_obj = &obj_iter[obj_iter->range_size - 1];
+ TAILQ_INSERT_HEAD(&obj_rsc->free_objs, base_obj, list);
+ base_obj->range_size = obj_iter->range_size - range_size;
+ last_obj->base_obj = base_obj;
+ }
+
+ /* Move 'range_size' objects from the list of free objects to the list of allocated objects. */
+ base_obj = obj_iter;
+ last_obj = &obj_iter[range_size - 1];
+ TAILQ_REMOVE(&obj_rsc->free_objs, base_obj, list);
+ TAILQ_INSERT_HEAD(&obj_rsc->allocated_objs, base_obj, list);
+ base_obj->range_size = range_size;
+ base_obj->type = type;
+ last_obj->base_obj = base_obj;
+
+ obj = obj_iter;
+ /* since new object, initialize the user data list */
+ TAILQ_INIT(&obj->user_data_list);
+
+ }
+ obj->ref_count++;
+
+ /** store user data (flow entry pointer) in a linked list inside the object */
+ rsc_mgr_obj_store_user_data(obj, user_data);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_obj_free(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, void *user_data, dev_log_id log_id)
+{
+ rsc_mgr_obj *obj;
+ rsc_mgr_obj *last_obj;
+ bcmos_errno rc;
+
+ rc = rsc_mgr_obj_get(access_int_id, obj_id, obj_rsc, &obj, log_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ obj->ref_count--;
+ /** remove user data (flow entry pointer) from the linked list inside the object */
+ rsc_mgr_obj_remove_user_data(obj, user_data);
+
+ if (!obj->ref_count)
+ {
+ rsc_mgr_obj *next_obj = NULL;
+ rsc_mgr_obj *prev_obj = NULL;
+
+ /* Validate that going to the next object won't overflow the array. */
+ if (obj < &obj_rsc->objs[obj_rsc->num_of_objs - 1] && &obj[obj->range_size] <= &obj_rsc->objs[obj_rsc->num_of_objs - 1])
+ {
+ /* Check if the next ID is in the free list (according to its reference count).
+ * If true -> we can merge obj's range with the next range. */
+ if (!obj[obj->range_size].ref_count)
+ next_obj = &obj[obj->range_size];
+ }
+
+ /* Validate that going to the base of the previous range won't underflow the array. */
+ if (obj > obj_rsc->objs)
+ {
+ /* Check if the base ID of the previous range is in the free list (according to the base ID's reference count).
+ * If true -> we can merge obj's range with the previous range. */
+ if (obj[-1].base_obj && !obj[-1].base_obj->ref_count)
+ prev_obj = obj[-1].base_obj;
+ }
+
+ /* First remove the object from the allocated linked list. */
+ TAILQ_REMOVE(&obj_rsc->allocated_objs, obj, list);
+ last_obj = &obj[obj->range_size - 1];
+ obj->type = RSC_MGR_OBJ_TYPE_INVALID; /* Clear type. */
+ if (next_obj && !prev_obj)
+ {
+ /* Merge only with next range. */
+ TAILQ_INSERT_BEFORE(next_obj, obj, list);
+ TAILQ_REMOVE(&obj_rsc->free_objs, next_obj, list);
+ obj->range_size += next_obj->range_size;
+ last_obj->base_obj = NULL;
+ next_obj->range_size = 0;
+ last_obj = &obj[obj->range_size - 1];
+ last_obj->base_obj = obj;
+ }
+ else if (!next_obj && prev_obj)
+ {
+ /* Merge only with previous range. */
+ prev_obj->range_size += obj->range_size;
+ obj->range_size = 0;
+ last_obj->base_obj = prev_obj;
+ }
+ else if (next_obj && prev_obj)
+ {
+ /* Merge with both next and previous ranges. */
+ prev_obj->range_size += obj->range_size + next_obj->range_size;
+ obj->range_size = 0;
+ next_obj->range_size = 0;
+ TAILQ_REMOVE(&obj_rsc->free_objs, next_obj, list);
+ last_obj->base_obj = NULL;
+ last_obj = &prev_obj[prev_obj->range_size - 1];
+ last_obj->base_obj = prev_obj;
+ }
+ else
+ {
+ /* No merge at all. */
+ TAILQ_INSERT_TAIL(&obj_rsc->free_objs, obj, list);
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_obj_get(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_obj **obj, dev_log_id log_id)
+{
+ bcmos_errno rc;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ if (!obj_rsc->is_valid_data_obj_id_cb(access_int_id, obj_id, obj_rsc->min_data_obj_id))
+ {
+ BCM_LOG(ERROR, log_id, "%s must be in the range %u .. %u\n",
+ obj_rsc->obj_name, obj_rsc->min_data_obj_id, obj_rsc->get_last_data_obj_id_cb(access_int_id, obj_rsc->min_data_obj_id));
+ return BCM_ERR_PARM;
+ }
+
+ *obj = &obj_rsc->objs[obj_id - obj_rsc->min_data_obj_id];
+ /* Only base object must have its reference count > 0. */
+ if (!(*obj)->ref_count)
+ {
+ BCM_LOG(ERROR, log_id, "%s hasn't been allocated before\n", obj_rsc->obj_name);
+ return BCM_ERR_PARM;
+ }
+
+ return BCM_ERR_OK;
+}
+
+/** @brief stores user passed in data in the linked list inside the obj */
+static bcmos_errno rsc_mgr_obj_store_user_data(rsc_mgr_obj *obj, void *user_data)
+{
+ rsc_mgr_user_data_entry *user_data_entry = NULL;
+
+ if (NULL == user_data)
+ return BCM_ERR_OK;
+
+ user_data_entry = bcmos_calloc(sizeof(rsc_mgr_user_data_entry));
+ user_data_entry->user_data = user_data;
+ TAILQ_INSERT_HEAD(&obj->user_data_list, user_data_entry, next);
+
+ return BCM_ERR_OK;
+}
+
+/** @brief removes user data from the linked list inside the obj */
+static bcmos_errno rsc_mgr_obj_remove_user_data(rsc_mgr_obj *obj, void *user_data)
+{
+ rsc_mgr_user_data_entry *user_data_entry = NULL, *user_data_entry_tmp;
+
+ if (NULL == user_data)
+ return BCM_ERR_OK;
+
+ TAILQ_FOREACH_SAFE(user_data_entry, &obj->user_data_list, next, user_data_entry_tmp)
+ {
+ if (user_data == user_data_entry->user_data)
+ break;
+ }
+ TAILQ_REMOVE(&obj->user_data_list, user_data_entry, next);
+
+ user_data_entry->user_data = NULL;
+ bcmos_free(user_data_entry);
+
+ return BCM_ERR_OK;
+}
+
+/** @brief iterator to iterate through the user data list in obj
+ * @note the assumption is if a NULL is returned, then caller code stop the iteration.
+ * */
+static void *rsc_mgr_obj_get_next_user_data(rsc_mgr_obj *obj, void **curr_user_data_entry, void **next_user_data_entry)
+{
+ if (NULL == *curr_user_data_entry)
+ {
+ *curr_user_data_entry = TAILQ_FIRST(&obj->user_data_list);
+ if (*curr_user_data_entry)
+ {
+ *next_user_data_entry = TAILQ_NEXT(((rsc_mgr_user_data_entry *)*curr_user_data_entry), next);
+ return ((rsc_mgr_user_data_entry *)(*curr_user_data_entry))->user_data;
+ }
+ }
+ else
+ {
+ *curr_user_data_entry = *next_user_data_entry;
+ if (*next_user_data_entry)
+ {
+ *next_user_data_entry = TAILQ_NEXT(((rsc_mgr_user_data_entry *)*next_user_data_entry), next);
+ return ((rsc_mgr_user_data_entry *)(*curr_user_data_entry))->user_data;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Alloc ID (aggregation port ID) */
+static bcmos_errno _rsc_mgr_access_int_base_alloc_id_set(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id min_data_agg_port_id)
+{
+ bcmolt_pon_alloc_index alloc_index;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ if (bcm_topo_pon_get_pon_mode(access_int_id) == BCM_TOPO_PON_MODE_GPON)
+ {
+ bcmolt_gpon_ni_cfg gpon_ni_cfg = {};
+ bcmolt_gpon_ni_cfg_id failed_prop;
+
+ BCMOLT_CFG_PROP_SET(&gpon_ni_cfg, gpon_ni, min_data_alloc_id, min_data_agg_port_id);
+ if (!bcmolt_gpon_ni_cfg_data_bounds_check(&gpon_ni_cfg.data, (1ULL << BCMOLT_GPON_NI_CFG_ID_MIN_DATA_ALLOC_ID), &failed_prop))
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal data alloc ID is not in the allowed range\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {};
+ bcmolt_xgpon_ni_cfg_id failed_prop;
+
+ BCMOLT_CFG_PROP_SET(&xgpon_ni_cfg, xgpon_ni, min_data_alloc_id, min_data_agg_port_id);
+ if (!bcmolt_xgpon_ni_cfg_data_bounds_check(&xgpon_ni_cfg.data, (1ULL << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_ALLOC_ID), &failed_prop))
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal data alloc ID is not in the allowed range\n");
+ return BCM_ERR_PARM;
+ }
+ }
+
+ if (!TAILQ_EMPTY(&topo_context->alloc_ids.allocated_objs))
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal alloc ID cannot be set when there are allocated alloc IDs\n");
+ return BCM_ERR_STATE;
+ }
+
+ topo_context->alloc_ids.min_data_obj_id = (rsc_mgr_obj_id)min_data_agg_port_id;
+ RSC_MGR_FOR_EACH_ALLOC_INDEX(access_int_id, alloc_index)
+ topo_context->alloc_ids.objs[alloc_index].id = topo_context->alloc_ids.min_data_obj_id + alloc_index;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno rsc_mgr_access_int_base_alloc_id_set(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id min_data_agg_port_id)
+{
+ bcmos_errno rc;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ return _rsc_mgr_access_int_base_alloc_id_set(access_int_id, min_data_agg_port_id);
+}
+
+
+static bcmos_errno rsc_mgr_alloc_validate_common(bcmbal_intf_id access_int_id)
+{
+ bcmos_errno rc;
+
+ rc = rsc_mgr_init_validate();
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager is uninitialized\n");
+ return rc;
+ }
+
+ if (!bcm_topo_pon_is_valid(access_int_id))
+ return BCM_ERR_PARM;
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_alloc_validate_non_unicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id topo_context_gem_port,
+ bcmbal_service_port_id req_gem_port, uint32_t range_size, rsc_mgr_obj_type type,
+ dev_log_id log_id)
+{
+ if (topo_context_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID && req_gem_port && req_gem_port != topo_context_gem_port)
+ {
+ BCM_LOG(ERROR, log_id, "Access interface already has %s service port ID=%u configured\n", RSC_MGR_OBJ_TYPE_STR(type), topo_context_gem_port);
+ return BCM_ERR_ALREADY;
+ }
+
+ if (range_size > 1)
+ {
+ BCM_LOG(ERROR, log_id, "Range bigger than 1 for %s GEM port is not allowed\n", RSC_MGR_OBJ_TYPE_STR(type));
+ return BCM_ERR_PARM;
+ }
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno rsc_mgr_alloc_id_alloc(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id *agg_port_id, uint32_t range_size, void *user_data)
+{
+ bcmos_errno rc;
+ rsc_mgr_obj_id obj_id = *agg_port_id;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_ALLOC_ID, &topo_context->alloc_ids, user_data, topo_context->log_id);
+ *agg_port_id = obj_id;
+
+ return rc;
+}
+
+bcmos_errno rsc_mgr_alloc_id_free(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void *user_data)
+{
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ if (!bcm_topo_pon_is_valid(access_int_id))
+ return BCM_ERR_PARM;
+
+ return rsc_mgr_obj_free(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, user_data, topo_context->log_id);
+}
+
+bcmos_errno rsc_mgr_alloc_id_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, uint32_t *ref_count)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, &obj, topo_context->log_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ *ref_count = obj->ref_count;
+
+ return BCM_ERR_OK;
+}
+
+/** @brief iterates through user data list of an alloc id object */
+void *rsc_mgr_alloc_id_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void **curr_user_data_entry, void **next_user_data_entry)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, &obj, topo_context->log_id);
+ if (rc != BCM_ERR_OK)
+ return NULL;
+
+ return rsc_mgr_obj_get_next_user_data(obj, curr_user_data_entry, next_user_data_entry);
+}
+
+/* GEM (service port ID) */
+static bcmos_errno _rsc_mgr_access_int_base_gem_set(bcmbal_intf_id access_int_id, bcmbal_service_port_id min_data_svc_port_id)
+{
+ bcmolt_pon_gem_port_index gem_index;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ if (bcm_topo_pon_get_pon_mode(access_int_id) == BCM_TOPO_PON_MODE_GPON)
+ {
+ bcmolt_gpon_gem_port_cfg gpon_gem_port_cfg = { .key.gem_port_id = min_data_svc_port_id };
+ bcmolt_gpon_gem_port_key_id failed_prop;
+
+ if (!bcmolt_gpon_gem_port_key_bounds_check(&gpon_gem_port_cfg.key, 1ULL << BCMOLT_GPON_GEM_PORT_KEY_ID_GEM_PORT_ID, &failed_prop) ||
+ min_data_svc_port_id < MIN_BASE_GEM_PORT_ID_GPON)
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal data GEM port is not in the allowed range\n");
+ return BCM_ERR_PARM;
+ }
+ }
+ else
+ {
+ bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {};
+ bcmolt_xgpon_ni_cfg_id failed_prop;
+
+ BCMOLT_CFG_PROP_SET(&xgpon_ni_cfg, xgpon_ni, min_data_gem_port_id, min_data_svc_port_id);
+ if (!bcmolt_xgpon_ni_cfg_data_bounds_check(&xgpon_ni_cfg.data, 1ULL << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_GEM_PORT_ID, &failed_prop))
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal data GEM port is not in the allowed range\n");
+ return BCM_ERR_PARM;
+ }
+ }
+
+ if (!TAILQ_EMPTY(&topo_context->gems.allocated_objs))
+ {
+ BCM_LOG(ERROR, topo_context->log_id, "Minimal GEM port cannot be set when there are allocated GEM ports\n");
+ return BCM_ERR_STATE;
+ }
+
+ topo_context->gems.min_data_obj_id = (rsc_mgr_obj_id)min_data_svc_port_id;
+ RSC_MGR_FOR_EACH_GEM_INDEX(access_int_id, gem_index)
+ topo_context->gems.objs[gem_index].id = topo_context->gems.min_data_obj_id + gem_index;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno rsc_mgr_access_int_base_gem_set(bcmbal_intf_id access_int_id, bcmbal_service_port_id min_data_svc_port_id)
+{
+ bcmos_errno rc;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ return _rsc_mgr_access_int_base_gem_set(access_int_id, min_data_svc_port_id);
+}
+
+static bcmos_errno _rsc_mgr_base_tm_sched_auto_id_set (bcmbal_tm_sched_id min_tm_sched_auto_id)
+{
+ bcmbal_tm_sched_id_index i;
+
+
+ if (!TAILQ_EMPTY(&tm_context.tm_sched_auto_key_ids.allocated_objs))
+ {
+ BCM_LOG(ERROR, tm_context.log_id, "Minimal tm node auto id cannot be set when there are allocated ids \n");
+ return BCM_ERR_STATE;
+ }
+
+ tm_context.tm_sched_auto_key_ids.min_data_obj_id = (rsc_mgr_obj_id)min_tm_sched_auto_id;
+ RSC_MGR_FOR_EACH_TM_SCHED_AUTO_INDEX(i)
+ {
+ tm_context.tm_sched_auto_key_ids.objs[i].id = tm_context.tm_sched_auto_key_ids.min_data_obj_id + i;
+ }
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno rsc_mgr_gem_alloc_unicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data)
+{
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = NULL;
+ rsc_mgr_obj_id obj_id = *svc_port_id;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_UNICAST, &topo_context->gems, user_data, topo_context->log_id);
+ *svc_port_id = obj_id;
+
+ return rc;
+}
+
+
+bcmos_errno rsc_mgr_gem_alloc_multicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data)
+{
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = NULL;
+ rsc_mgr_obj_id obj_id = *svc_port_id;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ rc = rsc_mgr_alloc_validate_non_unicast(access_int_id, topo_context->multicast_gem_port, *svc_port_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST, topo_context->log_id);
+
+ if (topo_context->multicast_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID)
+ obj_id = topo_context->multicast_gem_port; /* This will cause the reference count of the multicast GEM to increase. */
+#endif
+
+ rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST, &topo_context->gems, user_data, topo_context->log_id);
+ *svc_port_id = obj_id;
+
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ if (!rc)
+ RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->multicast_gem_port = *svc_port_id;
+#endif
+
+ return rc;
+}
+
+bcmos_errno rsc_mgr_gem_alloc_broadcast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data)
+{
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = NULL;
+ rsc_mgr_obj_id obj_id = *svc_port_id;
+
+ rc = rsc_mgr_alloc_validate_common(access_int_id);
+ if (BCM_ERR_OK != rc)
+ return rc;
+
+ topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+#ifndef MULTIPLE_BROADCAST_GEM_PORTS_PER_PON
+ rc = rsc_mgr_alloc_validate_non_unicast(access_int_id, topo_context->broadcast_gem_port, *svc_port_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST, topo_context->log_id);
+
+ if (topo_context->broadcast_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID)
+ obj_id = topo_context->broadcast_gem_port; /* This will cause the reference count of the broadcast GEM to increase. */
+#endif
+
+ rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST, &topo_context->gems, user_data, topo_context->log_id);
+ *svc_port_id = obj_id;
+
+#ifndef MULTIPLE_BROADCAST_GEM_PORTS_PER_PON
+ if (!rc)
+ RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->broadcast_gem_port = *svc_port_id;
+#endif
+
+ return rc;
+}
+
+bcmos_errno rsc_mgr_gem_free(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void *user_data)
+{
+ bcmos_errno rc;
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ rsc_mgr_topo_pon_context *topo_context;
+#endif
+
+ if (!bcm_topo_pon_is_valid(access_int_id))
+ return BCM_ERR_PARM;
+
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+#endif
+
+ rc = rsc_mgr_obj_free(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, user_data, topo_context->log_id);
+
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ if (!rc && topo_context->multicast_gem_port == svc_port_id)
+ RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->multicast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID;
+#endif
+
+ return rc;
+}
+
+bcmos_errno rsc_mgr_gem_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, uint32_t *ref_count)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, &obj, topo_context->log_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ *ref_count = obj->ref_count;
+
+ return BCM_ERR_OK;
+}
+
+/** @brief iterates through user data list of a gem object */
+void *rsc_mgr_gem_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void **curr_user_data_entry, void **next_user_data_entry)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+
+ rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, &obj, topo_context->log_id);
+ if (rc != BCM_ERR_OK)
+ return NULL;
+
+ return rsc_mgr_obj_get_next_user_data(obj, curr_user_data_entry, next_user_data_entry);
+}
+
+
+
+bcmos_errno _rsc_mgr_tm_sched_auto_id_alloc(bcmbal_tm_sched_id *tm_sched_id)
+{
+ bcmos_errno rc;
+ rsc_mgr_obj_id obj_id = *tm_sched_id;
+
+ rc = rsc_mgr_init_validate();
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager is uninitialized\n");
+ return rc;
+ }
+
+ /* Allocate a new object. */
+ rc = rsc_mgr_obj_alloc(0, &obj_id, 1, RSC_MGR_OBJ_TYPE_TM_SCHED, &tm_context.tm_sched_auto_key_ids, NULL, tm_context.log_id);
+ *tm_sched_id = obj_id;
+
+ return rc;
+}
+
+bcmos_errno _rsc_mgr_tm_sched_auto_id_free(bcmbal_tm_sched_id tm_sched_id)
+{
+ bcmos_errno rc;
+
+ rc = rsc_mgr_obj_free(0, (rsc_mgr_obj_id)tm_sched_id, &tm_context.tm_sched_auto_key_ids, NULL, tm_context.log_id);
+
+ return rc;
+}
+
+bcmos_errno _rsc_mgr_tm_sched_auto_id_get_ref_count(bcmbal_tm_sched_id tm_sched_id, uint32_t *ref_count)
+{
+ rsc_mgr_obj *obj;
+ bcmos_errno rc;
+
+ rc = rsc_mgr_obj_get(0, (rsc_mgr_obj_id)tm_sched_id, &tm_context.tm_sched_auto_key_ids, &obj, tm_context.log_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ *ref_count = obj->ref_count;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_bool _rsc_mgr_tm_sched_id_validate(bcmbal_tm_sched_id tm_sched_key_id)
+{
+ return (!rsc_mgr_is_valid_data_tm_sched_auto_id(tm_sched_key_id));
+}
+
+static void rsc_mgr_init_obj_rsc(rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_is_valid_data_obj_id_cb_t is_valid_data_obj_id_cb,
+ rsc_mgr_get_last_data_obj_id_cb_t get_last_data_obj_id_cb, uint32_t num_of_objs, const char *obj_name)
+{
+ rsc_mgr_obj *obj;
+
+ obj_rsc->obj_name = obj_name;
+ obj_rsc->is_valid_data_obj_id_cb = is_valid_data_obj_id_cb;
+ obj_rsc->get_last_data_obj_id_cb = get_last_data_obj_id_cb;
+ TAILQ_INIT(&obj_rsc->free_objs);
+ TAILQ_INIT(&obj_rsc->allocated_objs);
+ obj_rsc->objs = bcmos_calloc(num_of_objs * sizeof(*obj_rsc->objs));
+ obj_rsc->num_of_objs = num_of_objs;
+
+ /* Insert a first entry to the list of free objects. */
+ obj = &obj_rsc->objs[0];
+ obj->range_size = num_of_objs;
+ TAILQ_INSERT_HEAD(&obj_rsc->free_objs, obj, list);
+}
+
+static void rsc_mgr_uninit_obj_rsc(rsc_mgr_obj_rsc *obj_rsc)
+{
+ bcmos_free(obj_rsc->objs);
+}
+
+bcmos_errno rsc_mgr_mac_init(void)
+{
+ bcmos_errno rc = BCM_ERR_OK;
+ bcmolt_devid device_id;
+ uint32_t pon_id;
+ rsc_mgr_topo_pon_context *topo_context, *old_topo_context;
+
+ do
+ {
+ rc = rsc_mgr_init_validate();
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(INFO, rsc_mgr_log_id, "Resource Manager was not initialized");
+ break;
+ }
+ BCM_TOPO_FOR_EACH_PON(device_id, pon_id)
+ {
+ old_topo_context = bcm_topo_pon_get_context(pon_id, BCM_TOPO_PON_CONTEXT_ID_RSC_MGR);
+ if (old_topo_context)
+ {
+ bcmos_free(old_topo_context);
+ }
+ topo_context = bcmos_calloc(sizeof(*topo_context));
+ if (bcm_topo_pon_get_pon_mode(pon_id) == BCM_TOPO_PON_MODE_GPON)
+ {
+ topo_context->num_of_alloc_ids = GPON_NUM_OF_ALLOC_IDS;
+ topo_context->num_of_gem_ports = GPON_NUM_OF_GEM_PORT_IDS_PER_PON;
+ }
+ else
+ {
+ topo_context->num_of_alloc_ids = XGPON_NUM_OF_ALLOC_IDS;
+ topo_context->num_of_gem_ports = XGPON_NUM_OF_GEM_PORT_IDS_PER_PON;
+ }
+ topo_context->multicast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID;
+ topo_context->broadcast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID;
+ bcm_topo_pon_set_context(pon_id, BCM_TOPO_PON_CONTEXT_ID_RSC_MGR, topo_context);
+#ifdef ENABLE_LOG
+ snprintf(topo_context->log_id_name, sizeof(topo_context->log_id_name), "RSC_MGR%u", pon_id);
+ topo_context->log_id = bcm_dev_log_id_register(topo_context->log_id_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(topo_context->log_id == DEV_LOG_INVALID_ID);
+#endif
+ rsc_mgr_init_obj_rsc(&topo_context->alloc_ids, rsc_mgr_is_valid_data_alloc_id_cb, rsc_mgr_get_last_data_alloc_id_cb,
+ RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids, "alloc ID");
+ rsc_mgr_init_obj_rsc(&topo_context->gems, rsc_mgr_is_valid_data_gem_cb, rsc_mgr_get_last_data_gem_cb,
+ RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports, "GEM port");
+
+ if (bcm_topo_pon_get_pon_mode(pon_id) == BCM_TOPO_PON_MODE_GPON)
+ {
+ bcmolt_gpon_ni_cfg gpon_ni_cfg = {};
+
+ bcmolt_gpon_ni_cfg_data_set_default(&gpon_ni_cfg.data, 1 << BCMOLT_GPON_NI_CFG_ID_MIN_DATA_ALLOC_ID);
+ _rsc_mgr_access_int_base_alloc_id_set(pon_id, gpon_ni_cfg.data.min_data_alloc_id);
+
+ _rsc_mgr_access_int_base_gem_set(pon_id, MIN_BASE_GEM_PORT_ID_GPON);
+ }
+ else
+ {
+ bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {};
+
+ bcmolt_xgpon_ni_cfg_data_set_default(&xgpon_ni_cfg.data, 1 << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_ALLOC_ID);
+ _rsc_mgr_access_int_base_alloc_id_set(pon_id, xgpon_ni_cfg.data.min_data_alloc_id);
+
+ bcmolt_xgpon_ni_cfg_data_set_default(&xgpon_ni_cfg.data, 1 << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_GEM_PORT_ID);
+ _rsc_mgr_access_int_base_gem_set(pon_id, xgpon_ni_cfg.data.min_data_gem_port_id);
+ }
+ }
+
+ }while(0);
+ return rc;
+}
+
+bcmos_errno rsc_mgr_init(void)
+{
+ if (rsc_mgr_init_validate() == BCM_ERR_OK)
+ {
+ BCM_LOG(INFO, rsc_mgr_log_id, "Resource Manager was already initialized");
+ return BCM_ERR_OK;
+ }
+
+#ifdef ENABLE_LOG
+ if (rsc_mgr_log_id == DEV_LOG_INVALID_ID)
+ {
+ rsc_mgr_log_id = bcm_dev_log_id_register("RSC_MGR", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(rsc_mgr_log_id == DEV_LOG_INVALID_ID);
+ }
+#endif
+
+ /*Init the tm object*/
+ tm_context.num_of_tm_sched_auto_key_ids = NUM_OF_TM_SCHED_AUTO_KEY_IDS;
+ snprintf(tm_context.log_id_name , sizeof(tm_context.log_id_name) , "RSC_MGR_TM");
+ tm_context.log_id = bcm_dev_log_id_register(tm_context.log_id_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(tm_context.log_id == DEV_LOG_INVALID_ID);
+
+ rsc_mgr_init_obj_rsc(&tm_context.tm_sched_auto_key_ids, rsc_mgr_is_valid_data_tm_sched_auto_id_cb, rsc_mgr_get_last_data_tm_sched_auto_id_cb,
+ tm_context.num_of_tm_sched_auto_key_ids, "TM node auto id");
+
+ _rsc_mgr_base_tm_sched_auto_id_set(MIN_BASE_TM_SCHED_AUTO_ID);
+
+ rsc_mgr_context.is_initialized = BCMOS_TRUE;
+ return BCM_ERR_OK;
+}
+
+void rsc_mgr_uninit(void)
+{
+ bcmolt_devid device_id;
+ uint32_t pon_id;
+
+ if (!rsc_mgr_context.is_initialized)
+ return;
+
+ BCM_TOPO_FOR_EACH_PON(device_id, pon_id)
+ {
+ rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(pon_id);
+
+ rsc_mgr_uninit_obj_rsc(&topo_context->gems);
+ rsc_mgr_uninit_obj_rsc(&topo_context->alloc_ids);
+ }
+ rsc_mgr_context.is_initialized = BCMOS_FALSE;
+}
+
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr.h b/bal_release/src/lib/librscmgr/rsc_mgr.h
new file mode 100644
index 0000000..072d37e
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr.h
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef _RSC_MGR_H_
+#define _RSC_MGR_H_
+
+#include <bal_objs.h>
+
+/* Alloc ID (aggregation port ID) */
+bcmos_errno rsc_mgr_access_int_base_alloc_id_set(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id min_data_agg_port_id);
+bcmos_errno rsc_mgr_alloc_id_alloc(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id *agg_port_id, uint32_t range_size, void *user_data);
+bcmos_errno rsc_mgr_alloc_id_free(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void *user_data);
+bcmos_errno rsc_mgr_alloc_id_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, uint32_t *ref_count);
+void* rsc_mgr_alloc_id_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void **curr_user_data_entry, void **next_user_data_entry);
+
+
+/* GEM (service port ID) */
+bcmos_errno rsc_mgr_access_int_base_gem_set(bcmbal_intf_id access_int_id, bcmbal_service_port_id min_data_svc_port_id);
+bcmos_errno rsc_mgr_gem_alloc_unicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data);
+bcmos_errno rsc_mgr_gem_alloc_multicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data);
+bcmos_errno rsc_mgr_gem_alloc_broadcast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data);
+bcmos_errno rsc_mgr_gem_free(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void *user_data);
+bcmos_errno rsc_mgr_gem_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, uint32_t *ref_count);
+void* rsc_mgr_gem_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void **curr_user_data_entry, void **next_user_data_entry);
+
+bcmos_errno _rsc_mgr_tm_sched_auto_id_alloc(bcmbal_tm_sched_id *tm_sched_key_id);
+bcmos_errno _rsc_mgr_tm_sched_auto_id_free(bcmbal_tm_sched_id tm_sched_key_id);
+bcmos_errno _rsc_mgr_tm_sched_auto_id_get_ref_count(bcmbal_tm_sched_id tm_sched_key_id, uint32_t *ref_count);
+bcmos_bool _rsc_mgr_tm_sched_id_validate(bcmbal_tm_sched_id tm_sched_key_id);
+
+bcmos_errno rsc_mgr_mac_init(void);
+bcmos_errno rsc_mgr_init(void);
+void rsc_mgr_uninit(void);
+
+#endif
+
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr_cli.c b/bal_release/src/lib/librscmgr/rsc_mgr_cli.c
new file mode 100644
index 0000000..7584741
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr_cli.c
@@ -0,0 +1,315 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bcm_dev_log.h>
+#include <bcmcli.h>
+#include <bal_objs.h>
+#include <bal_api.h>
+#include <bcm_topo.h>
+#include "rsc_mgr.h"
+#include "rsc_mgr_common.h"
+#include "rsc_mgr_cli.h"
+
+static bcmos_errno rsc_mgr_cli_cmd_init(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ return rsc_mgr_init();
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_base_alloc_id_set(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmbal_aggregation_port_id min_data_agg_port_id = (bcmbal_aggregation_port_id)bcmcli_find_named_parm(session, "min_data_agg_port_id")->value.unumber;
+
+ return rsc_mgr_access_int_base_alloc_id_set(access_int_id, min_data_agg_port_id);
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_base_gem_set(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmbal_service_port_id min_data_svc_port_id = (bcmbal_service_port_id)bcmcli_find_named_parm(session, "min_data_svc_port_id")->value.unumber;
+
+ return rsc_mgr_access_int_base_gem_set(access_int_id, min_data_svc_port_id);
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_alloc_id_alloc(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmcli_cmd_parm *agg_port_id_parm = bcmcli_find_named_parm(session, "agg_port_id");
+ bcmbal_aggregation_port_id agg_port_id = 0;
+ uint32_t range_size = (uint32_t)bcmcli_find_named_parm(session, "range_size")->value.unumber;
+ uint32_t ref_count;
+ bcmos_errno rc;
+
+ if (agg_port_id_parm)
+ agg_port_id = (bcmbal_aggregation_port_id)agg_port_id_parm->value.unumber;
+
+ rc = rsc_mgr_alloc_id_alloc(access_int_id, &agg_port_id, range_size, NULL);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ rc = rsc_mgr_alloc_id_get_ref_count(access_int_id, agg_port_id, &ref_count);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcmcli_session_print(session, "Allocated alloc ID=%u (ref_count=%u)\n", agg_port_id, ref_count);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_alloc_id_free(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmbal_aggregation_port_id agg_port_id = (bcmbal_aggregation_port_id)bcmcli_find_named_parm(session, "agg_port_id")->value.unumber;
+ uint32_t ref_count;
+ bcmos_errno rc;
+
+ rc = rsc_mgr_alloc_id_get_ref_count(access_int_id, agg_port_id, &ref_count);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ rc = rsc_mgr_alloc_id_free(access_int_id, agg_port_id, NULL);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcmcli_session_print(session, "Freed alloc ID=%u (ref_count=%u)\n", agg_port_id, ref_count - 1);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_gem_alloc(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmcli_cmd_parm *svc_port_id_parm = bcmcli_find_named_parm(session, "svc_port_id");
+ bcmbal_service_port_id svc_port_id = 0;
+ uint32_t range_size = (uint32_t)bcmcli_find_named_parm(session, "range_size")->value.unumber;
+ rsc_mgr_obj_type gem_type = (rsc_mgr_obj_type)bcmcli_find_named_parm(session, "gem_type")->value.enum_val;
+ uint32_t ref_count;
+ bcmos_errno rc;
+
+ if (svc_port_id_parm)
+ svc_port_id = (bcmbal_service_port_id)svc_port_id_parm->value.unumber;
+
+ if (RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST == gem_type)
+ rc = rsc_mgr_gem_alloc_multicast(access_int_id, &svc_port_id, range_size, NULL);
+ else if (RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST == gem_type)
+ rc = rsc_mgr_gem_alloc_broadcast(access_int_id, &svc_port_id, range_size, NULL);
+ else
+ rc = rsc_mgr_gem_alloc_unicast(access_int_id, &svc_port_id, range_size, NULL);
+
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ rc = rsc_mgr_gem_get_ref_count(access_int_id, svc_port_id, &ref_count);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcmcli_session_print(session, "Allocated GEM port=%u (ref_count=%u)\n", svc_port_id, ref_count);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_gem_free(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+ bcmbal_service_port_id svc_port_id = (bcmbal_service_port_id)bcmcli_find_named_parm(session, "svc_port_id")->value.unumber;
+ uint32_t ref_count;
+ bcmos_errno rc;
+
+ rc = rsc_mgr_gem_get_ref_count(access_int_id, svc_port_id, &ref_count);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ rc = rsc_mgr_gem_free(access_int_id, svc_port_id, NULL);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcmcli_session_print(session, "Freed GEM port=%u (ref_count=%u)\n", svc_port_id, ref_count - 1);
+
+ return BCM_ERR_OK;
+}
+/*allocates a new tm node auto id
+no inputs parameters are used */
+static bcmos_errno rsc_mgr_cli_cmd_tm_sched_auto_alloc(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_tm_sched_id tm_sched_auto_id = 0;
+ bcmos_errno rc;
+
+ rc = _rsc_mgr_tm_sched_auto_id_alloc(&tm_sched_auto_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+
+ bcmcli_session_print(session, "Allocated TM SCHED AUTO ID %u \n", tm_sched_auto_id);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_tm_sched_auto_free(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_tm_sched_id tm_sched_auto_id = (bcmbal_tm_sched_id)bcmcli_find_named_parm(session, "tm_sched_auto_id")->value.unumber;
+ uint32_t ref_count;
+ bcmos_errno rc;
+
+ rc = _rsc_mgr_tm_sched_auto_id_get_ref_count(tm_sched_auto_id, &ref_count);
+
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ rc = _rsc_mgr_tm_sched_auto_id_free(tm_sched_auto_id);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcmcli_session_print(session, "Freed TM NODE AUTO ID %u (ref_count=%u)\n", tm_sched_auto_id, ref_count - 1);
+
+ return BCM_ERR_OK;
+}
+
+static void rsc_mgr_show_objs_list(bcmcli_session *session, bcmbal_intf_id access_int_id, rsc_mgr_obj_rsc *obj_rsc,
+ rsc_mgr_obj_list *obj_list)
+{
+ rsc_mgr_obj *obj_iter;
+
+ TAILQ_FOREACH(obj_iter, obj_list, list)
+ {
+ if (obj_iter->range_size == 1)
+ {
+ bcmcli_session_print(session, "\t%s=%u (obj_type=%s, ref_count=%u)\n",
+ obj_rsc->obj_name, obj_iter->id, RSC_MGR_OBJ_TYPE_STR(obj_iter->type), obj_iter->ref_count);
+ }
+ else
+ {
+ bcmcli_session_print(session, "\t%s=%u .. %u (obj_type=%s, ref_count=%u)\n",
+ obj_rsc->obj_name, obj_iter->id, obj_iter->id + obj_iter->range_size - 1, RSC_MGR_OBJ_TYPE_STR(obj_iter->type), obj_iter->ref_count);
+ }
+ }
+}
+
+static void rsc_mgr_show_objs(bcmcli_session *session, bcmbal_intf_id access_int_id, rsc_mgr_obj_rsc *obj_rsc)
+{
+ bcmcli_session_print(session, "Base data %s=%u\n", obj_rsc->obj_name, obj_rsc->min_data_obj_id);
+ bcmcli_session_print(session, "Allocated %ss:\n", obj_rsc->obj_name);
+ rsc_mgr_show_objs_list(session, access_int_id, obj_rsc, &obj_rsc->allocated_objs);
+ bcmcli_session_print(session, "Free %ss:\n", obj_rsc->obj_name);
+ rsc_mgr_show_objs_list(session, access_int_id, obj_rsc, &obj_rsc->free_objs);
+}
+
+static bcmos_errno rsc_mgr_show(bcmcli_session *session, bcmbal_intf_id access_int_id)
+{
+ bcmos_errno rc;
+ rsc_mgr_topo_pon_context *topo_context;
+
+ rc = rsc_mgr_init_validate();
+ if (rc != BCM_ERR_OK)
+ {
+ BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager is uninitialized\n");
+ return rc;
+ }
+
+ if (!bcm_topo_pon_is_valid(access_int_id))
+ return BCM_ERR_PARM;
+
+ topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id);
+ rsc_mgr_show_objs(session, access_int_id, &topo_context->alloc_ids);
+ rsc_mgr_show_objs(session, access_int_id, &topo_context->gems);
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno rsc_mgr_cli_cmd_show(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
+{
+ bcmbal_intf_id access_int_id = (bcmbal_intf_id)bcmcli_find_named_parm(session, "key.access_int_id")->value.unumber;
+
+ return rsc_mgr_show(session, access_int_id);
+}
+
+void rsc_mgr_cli_init(bcmcli_entry *cli_dir)
+{
+ bcmcli_entry *dbg_dir;
+
+ static bcmcli_enum_val rsc_mgr_cli_enum_gem_type_table[] =
+ {
+ { .name = "unicast", .val = RSC_MGR_OBJ_TYPE_GEM_PORT_UNICAST },
+ { .name = "multicast", .val = RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST },
+ { .name = "broadcast", .val = RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST },
+ BCMCLI_ENUM_LAST
+ };
+
+ dbg_dir = bcmcli_dir_add(cli_dir, "rsc_mgr", "BAL resource manager API access", BCMCLI_ACCESS_ADMIN, NULL);
+
+ BCMCLI_MAKE_CMD(dbg_dir, "init", "Initialize resource manager for a specific access terminal", rsc_mgr_cli_cmd_init,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "base_alloc_id_set", "Set the base alloc ID for an access interface", rsc_mgr_cli_cmd_base_alloc_id_set,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("min_data_agg_port_id", "minimal data aggregation port ID", BCMCLI_PARM_UNUMBER, 0));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "base_gem_set", "Set the base GEM port for an access interface", rsc_mgr_cli_cmd_base_gem_set,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("min_data_svc_port_id", "minimal data service port ID", BCMCLI_PARM_UNUMBER, 0));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "alloc_id_alloc", "Allocate an alloc ID range or reuse an existing alloc ID range", rsc_mgr_cli_cmd_alloc_id_alloc,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("agg_port_id", "aggregation port ID (if omitted a new alloc ID is allocated, otherwise we reuse an existing alloc ID)",
+ BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL),
+ BCMCLI_MAKE_PARM_RANGE("range_size", "range size", BCMCLI_PARM_UNUMBER, 0, RSC_MGR_MIN_RANGE_SIZE, RSC_MGR_MAX_RANGE_SIZE));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "alloc_id_free", "Free an alloc ID range", rsc_mgr_cli_cmd_alloc_id_free,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("agg_port_id", "base of alloc ID range", BCMCLI_PARM_UNUMBER, 0));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "gem_alloc", "Allocate a GEM port range or reuse an existing GEM port range", rsc_mgr_cli_cmd_gem_alloc,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("svc_port_id", "service port ID (if omitted a new GEM port is allocated, otherwise we reuse an existing GEM port)",
+ BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL),
+ BCMCLI_MAKE_PARM_RANGE("range_size", "range size", BCMCLI_PARM_UNUMBER, 0, RSC_MGR_MIN_RANGE_SIZE, RSC_MGR_MAX_RANGE_SIZE),
+ BCMCLI_MAKE_PARM_ENUM("gem_type", "GEM type", rsc_mgr_cli_enum_gem_type_table, 0));
+
+ BCMCLI_MAKE_CMD(dbg_dir, "gem_free", "Free a GEM port range", rsc_mgr_cli_cmd_gem_free,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0),
+ BCMCLI_MAKE_PARM("svc_port_id", "base of GEM port range", BCMCLI_PARM_UNUMBER, 0));
+
+ BCMCLI_MAKE_CMD_NOPARM(dbg_dir, "tm_sched_auto_id_alloc", "Allocate a tm node auto id or reuse an existing id", rsc_mgr_cli_cmd_tm_sched_auto_alloc);
+
+ BCMCLI_MAKE_CMD(dbg_dir, "tm_sched_auto_id_free", "Free a tm node auto id", rsc_mgr_cli_cmd_tm_sched_auto_free,
+ BCMCLI_MAKE_PARM("tm_sched_auto_id", "tm node auto id to be free", BCMCLI_PARM_UNUMBER, 0));
+
+
+ BCMCLI_MAKE_CMD(dbg_dir, "show", "Show the database of the resource manager", rsc_mgr_cli_cmd_show,
+ BCMCLI_MAKE_PARM_RANGE("key.access_term_id", "access terminal identifier", BCMCLI_PARM_UNUMBER, 0, 0, MAX_SUPPORTED_OLTS),
+ BCMCLI_MAKE_PARM("key.access_int_id", "access interface identifier", BCMCLI_PARM_UNUMBER, 0));
+}
+
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr_cli.h b/bal_release/src/lib/librscmgr/rsc_mgr_cli.h
new file mode 100644
index 0000000..7d9085c
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr_cli.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef _RSC_MGR_CLI_H_
+#define _RSC_MGR_CLI_H_
+
+#include <bcmcli.h>
+
+void rsc_mgr_cli_init(bcmcli_entry *cli_dir);
+
+#endif
+
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr_common.c b/bal_release/src/lib/librscmgr/rsc_mgr_common.c
new file mode 100644
index 0000000..71bcee9
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr_common.c
@@ -0,0 +1,61 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bcm_topo.h>
+#include "rsc_mgr_common.h"
+
+#ifdef ENABLE_LOG
+dev_log_id rsc_mgr_log_id = DEV_LOG_INVALID_ID;
+#endif
+
+bcmos_errno rsc_mgr_init_validate(void)
+{
+ if (!rsc_mgr_context.is_initialized)
+ {
+#ifdef ENABLE_LOG
+ if (rsc_mgr_log_id == DEV_LOG_INVALID_ID)
+ {
+ rsc_mgr_log_id = bcm_dev_log_id_register("RSC_MGR", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(rsc_mgr_log_id == DEV_LOG_INVALID_ID);
+ }
+#endif
+ return BCM_ERR_STATE;
+ }
+
+ if (!bcm_topo_is_initialized())
+ {
+ BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager cannot be called before topology is initialized\n");
+ return BCM_ERR_STATE;
+ }
+
+ return BCM_ERR_OK;
+}
+
diff --git a/bal_release/src/lib/librscmgr/rsc_mgr_common.h b/bal_release/src/lib/librscmgr/rsc_mgr_common.h
new file mode 100644
index 0000000..4d19176
--- /dev/null
+++ b/bal_release/src/lib/librscmgr/rsc_mgr_common.h
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef _RSC_MGR_COMMON_H_
+#define _RSC_MGR_COMMON_H_
+
+#include <bcmolt_host_api.h>
+#include <bcm_dev_log.h>
+#include <bal_objs.h>
+#include <bcmolt_math.h>
+
+#define RSC_MGR_MIN_RANGE_SIZE 1
+#define RSC_MGR_MAX_RANGE_SIZE 8
+
+#define RSC_MGR_PON_TOPO_CONTEXT(pon_id) ((rsc_mgr_topo_pon_context *)bcm_topo_pon_get_context(pon_id, BCM_TOPO_PON_CONTEXT_ID_RSC_MGR))
+
+typedef enum rsc_mgr_obj_type
+{
+ RSC_MGR_OBJ_TYPE_INVALID = 0,
+ RSC_MGR_OBJ_TYPE_GEM_PORT_UNICAST,
+ RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST,
+ RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST,
+ RSC_MGR_OBJ_TYPE_ALLOC_ID,
+ RSC_MGR_OBJ_TYPE_TM_SCHED,
+} rsc_mgr_obj_type;
+
+#define RSC_MGR_OBJ_TYPE_STR(_type) \
+ ((_type) == RSC_MGR_OBJ_TYPE_GEM_PORT_UNICAST ? "gem_port_unicast":\
+ (_type) == RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST ? "gem_port_multicast":\
+ (_type) == RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST ? "gem_port_broadcast":\
+ (_type) == RSC_MGR_OBJ_TYPE_ALLOC_ID ? "alloc_id":\
+ (_type) == RSC_MGR_OBJ_TYPE_TM_SCHED ? "tm_sched":"invalid")
+
+
+typedef struct
+{
+ bcmos_bool is_initialized;
+} rsc_mgr_context_t;
+
+extern rsc_mgr_context_t rsc_mgr_context;
+
+/** @brief container for storing user data */
+typedef struct rsc_mgr_user_data_entry
+{
+ TAILQ_ENTRY(rsc_mgr_user_data_entry) next;
+ void *user_data;
+} rsc_mgr_user_data_entry;
+
+/** @brief linked list of flow entries sharing the same GEM port or Alloc Id */
+typedef TAILQ_HEAD(, rsc_mgr_user_data_entry) shared_obj_user_data_list;
+
+/* An object ID can be either alloc ID or GEM port. */
+typedef uint32_t rsc_mgr_obj_id;
+
+/* An element for an object linked list. */
+typedef struct rsc_mgr_obj
+{
+ TAILQ_ENTRY(rsc_mgr_obj) list;
+ struct rsc_mgr_obj *base_obj; /* The last object of a range points to the base object of the range. */
+ rsc_mgr_obj_id id;
+ uint32_t ref_count;
+ uint32_t range_size;
+ rsc_mgr_obj_type type;
+ shared_obj_user_data_list user_data_list; /* this stores a list of flows sharing the same gem or alloc id object */
+} rsc_mgr_obj;
+
+typedef TAILQ_HEAD(, rsc_mgr_obj) rsc_mgr_obj_list;
+
+typedef bcmos_bool (*rsc_mgr_is_valid_data_obj_id_cb_t)(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id);
+typedef rsc_mgr_obj_id (*rsc_mgr_get_last_data_obj_id_cb_t)(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id);
+
+typedef struct
+{
+ const char *obj_name;
+ rsc_mgr_is_valid_data_obj_id_cb_t is_valid_data_obj_id_cb;
+ rsc_mgr_get_last_data_obj_id_cb_t get_last_data_obj_id_cb;
+ rsc_mgr_obj_list free_objs;
+ rsc_mgr_obj_list allocated_objs;
+ rsc_mgr_obj *objs; /* Dynamically allocated */
+ uint32_t num_of_objs;
+ rsc_mgr_obj_id min_data_obj_id;
+} rsc_mgr_obj_rsc;
+
+typedef struct
+{
+ rsc_mgr_obj_rsc alloc_ids;
+ rsc_mgr_obj_rsc gems;
+ uint16_t num_of_alloc_ids;
+ uint16_t num_of_gem_ports;
+#ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON
+ uint16_t multicast_gem_port; /* For validation purposes (validate there is no more than a single multicast GEM port per PON). */
+#endif
+#ifndef MULTIPLE_BROADCAST_GEM_PORTS_PER_PON
+ uint16_t broadcast_gem_port; /* For validation purposes (validate there is no more than a single broadcast GEM port per PON). */
+#endif
+#ifdef ENABLE_LOG
+ dev_log_id log_id;
+ char log_id_name[MAX_DEV_LOG_ID_NAME];
+#endif
+} rsc_mgr_topo_pon_context;
+
+typedef struct
+{
+ rsc_mgr_obj_rsc tm_sched_auto_key_ids;
+ uint16_t num_of_tm_sched_auto_key_ids;
+#ifdef ENABLE_LOG
+ dev_log_id log_id;
+ char log_id_name[MAX_DEV_LOG_ID_NAME];
+#endif
+
+} rsc_mgr_tm_context;
+#ifdef ENABLE_LOG
+extern dev_log_id rsc_mgr_log_id;
+#endif
+
+bcmos_errno rsc_mgr_init_validate(void);
+
+#endif
+
diff --git a/bal_release/src/lib/libtopology/Makefile b/bal_release/src/lib/libtopology/Makefile
new file mode 100644
index 0000000..7507881
--- /dev/null
+++ b/bal_release/src/lib/libtopology/Makefile
@@ -0,0 +1,36 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = topology
+MOD_TYPE = lib
+MOD_DEPS = dev_log maple_sdk
+
+srcs = bcm_topo.c
+
diff --git a/bal_release/src/lib/libtopology/bcm_topo.c b/bal_release/src/lib/libtopology/bcm_topo.c
new file mode 100644
index 0000000..4b092a0
--- /dev/null
+++ b/bal_release/src/lib/libtopology/bcm_topo.c
@@ -0,0 +1,650 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#include <bcm_dev_log.h>
+#include <bcmolt_math.h>
+#include "bcm_topo.h"
+
+#define BCM_TOPO_MAX_LINE_SIZE 256
+#define BCM_TOPO_MAX_NNI_DEVICES 1
+
+uint32_t g_max_nni_ports[BCM_TOPO_MAX_NNI_DEVICES] = {BCM_TOPO_MAX_NNI_PORTS};
+
+typedef struct bcm_topo_dev_context_t bcm_topo_dev_context_t;
+
+typedef struct
+{
+ bcm_topo_dev_context_t *dev; /* Back pointer to the physical device this PON belongs to */
+ bcmos_bool is_initialized;
+ uint32_t pon_id;
+ uint32_t logical_pon;
+ bcm_topo_pon_mode pon_mode;
+ uint32_t max_num_of_onus;
+ void *contexts[BCM_TOPO_PON_CONTEXT_ID__NUM_OF]; /* User context - 1 entry per user */
+} bcm_topo_pon_context_t;
+
+struct bcm_topo_dev_context_t
+{
+ bcm_topo_pon_mode pon_mode; /* Currently we do not allow more than one PON mode per device (e.g: GPONx8 + XGPONx4) */
+ bcmos_bool is_initialized;
+ uint32_t device_id;
+ uint32_t max_num_of_pons;
+ bcm_topo_pon_context_t pons[BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV];
+};
+
+typedef struct
+{
+ bcmos_bool is_initialized;
+ bcm_topo_dev_context_t devs[BCM_TOPO_MAX_NUM_OF_DEVS];
+ bcm_topo_pon_context_t *logical_pon2physical_pon[BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS];
+} bcm_topo_context_t;
+
+static bcm_topo_context_t bcm_topo_context;
+
+#ifdef ENABLE_LOG
+static dev_log_id topo_log_id = DEV_LOG_INVALID_ID;
+#endif
+
+static int2str_t pon_mode2str[] =
+{
+ {BCM_TOPO_PON_MODE_GPON, "gpon"},
+ {BCM_TOPO_PON_MODE_XGPON, "xgpon"},
+ {BCM_TOPO_PON_MODE_XGS, "xgs"},
+ {BCM_TOPO_PON_MODE_EPON_TDMA, "epon_tdma"},
+ {BCM_TOPO_PON_MODE_EPON_1G, "epon_1g"},
+ {BCM_TOPO_PON_MODE_EPON_10G, "epon_10g"},
+ {-1},
+};
+
+static int2int_t pon_mode2max_num_of_pons[] =
+{
+ {BCM_TOPO_PON_MODE_GPON, 16},
+ {BCM_TOPO_PON_MODE_XGPON, 8},
+ {BCM_TOPO_PON_MODE_XGS, 2},
+ {BCM_TOPO_PON_MODE_EPON_TDMA, 8},
+ {BCM_TOPO_PON_MODE_EPON_1G, 16},
+ {BCM_TOPO_PON_MODE_EPON_10G, 8},
+ {-1},
+};
+
+const char *bcm_topo_dev_get_pon_mode_str(bcmolt_devid device_id)
+{
+ return int2str(pon_mode2str, bcm_topo_context.devs[device_id].pon_mode);
+}
+
+int bcm_topo_dev_get_max_pon(bcmolt_devid device_id)
+{
+ return int2int(pon_mode2max_num_of_pons, bcm_topo_context.devs[device_id].pon_mode);
+}
+
+bcm_topo_pon_mode bcm_topo_pon_get_pon_mode(uint32_t pon)
+{
+ bcmolt_devid device_id;
+ uint32_t physical_pon;
+ bcmos_errno rc;
+
+ rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
+ if (rc != BCM_ERR_OK)
+ return BCM_TOPO_PON_MODE_INVALID;
+
+ return bcm_topo_context.devs[device_id].pons[physical_pon].pon_mode;
+}
+
+bcm_topo_pon_family bcm_topo_pon_get_pon_family(uint32_t pon)
+{
+ switch (bcm_topo_pon_get_pon_mode(pon))
+ {
+ case BCM_TOPO_PON_MODE_GPON:
+ case BCM_TOPO_PON_MODE_XGPON:
+ case BCM_TOPO_PON_MODE_XGS:
+ return BCM_TOPO_PON_FAMILY_GPON;
+ case BCM_TOPO_PON_MODE_EPON_TDMA:
+ case BCM_TOPO_PON_MODE_EPON_1G:
+ case BCM_TOPO_PON_MODE_EPON_10G:
+ return BCM_TOPO_PON_FAMILY_EPON;
+ default:
+ return BCM_TOPO_PON_FAMILY_INVALID;
+ }
+}
+
+bcm_topo_pon_sub_family bcm_topo_pon_get_pon_sub_family(uint32_t pon)
+{
+ switch (bcm_topo_pon_get_pon_mode(pon))
+ {
+ case BCM_TOPO_PON_MODE_GPON:
+ return BCM_TOPO_PON_SUB_FAMILY_GPON;
+ case BCM_TOPO_PON_MODE_XGPON:
+ case BCM_TOPO_PON_MODE_XGS:
+ return BCM_TOPO_PON_SUB_FAMILY_XGPON;
+ case BCM_TOPO_PON_MODE_EPON_TDMA:
+ case BCM_TOPO_PON_MODE_EPON_1G:
+ case BCM_TOPO_PON_MODE_EPON_10G:
+ return BCM_TOPO_PON_SUB_FAMILY_EPON;
+ default:
+ return BCM_TOPO_PON_SUB_FAMILY_INVALID;
+ }
+}
+
+uint32_t bcm_topo_pon_get_max_num_of_onus(uint32_t pon)
+{
+ bcmolt_devid device_id;
+ uint32_t physical_pon;
+ bcmos_errno rc;
+
+ rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
+ if (rc != BCM_ERR_OK)
+ return BCM_TOPO_ERR_INVALID;
+
+ return bcm_topo_context.devs[device_id].pons[physical_pon].max_num_of_onus;
+}
+
+bcmos_bool bcm_topo_pon_is_valid(uint32_t pon)
+{
+ bcmolt_devid device_id;
+ uint32_t physical_pon;
+
+ if (bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon) != BCM_ERR_OK)
+ return BCMOS_FALSE;
+
+ return BCMOS_TRUE;
+}
+
+bcmolt_devid bcm_topo_dev_get_next(bcmolt_devid device_id)
+{
+ if (device_id == BCM_TOPO_DEV_INVALID)
+ device_id = 0;
+ else
+ device_id++;
+
+ for (; device_id < BCM_TOPO_MAX_NUM_OF_DEVS && !bcm_topo_context.devs[device_id].is_initialized; device_id++);
+
+ return device_id == BCM_TOPO_MAX_NUM_OF_DEVS ? BCM_TOPO_DEV_INVALID : device_id;
+}
+
+uint32_t bcm_topo_pon_get_next(bcmolt_devid device_id, uint32_t pon)
+{
+ uint32_t physical_pon;
+ bcmos_errno rc;
+
+ if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
+ return BCM_TOPO_PON_INVALID;
+ }
+
+ if (pon == BCM_TOPO_PON_INVALID)
+ physical_pon = 0;
+ else
+ {
+ bcmolt_devid dummy;
+
+ rc = bcm_topo_pon_get_logical2physical(pon, &dummy, &physical_pon);
+ if (rc != BCM_ERR_OK)
+ {
+ return BCM_TOPO_PON_INVALID;
+ }
+ else
+ {
+ physical_pon++;
+ }
+ }
+
+ if (physical_pon < bcm_topo_context.devs[device_id].max_num_of_pons)
+ {
+ rc = bcm_topo_pon_get_physical2logical(device_id, physical_pon, &pon);
+ if (rc != BCM_ERR_OK)
+ {
+ return BCM_TOPO_PON_INVALID;
+ }
+ else
+ {
+ return pon;
+ }
+ }
+
+ return BCM_TOPO_PON_INVALID;
+}
+
+bcmos_errno bcm_topo_pon_get_logical2physical(uint32_t logical_pon, bcmolt_devid *device_id, uint32_t *physical_pon)
+{
+ if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Logical PON ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ if (!bcm_topo_context.logical_pon2physical_pon[logical_pon])
+ {
+ BCM_LOG(ERROR, topo_log_id, "Logical PON=%u was not associated with a physical PON\n", logical_pon);
+ return BCM_ERR_RANGE;
+ }
+
+ *physical_pon = bcm_topo_context.logical_pon2physical_pon[logical_pon]->pon_id;
+ *device_id = bcm_topo_context.logical_pon2physical_pon[logical_pon]->dev->device_id;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno bcm_topo_pon_get_physical2logical(bcmolt_devid device_id, uint32_t physical_pon, uint32_t *logical_pon)
+{
+ if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ if (physical_pon >= bcm_topo_context.devs[device_id].max_num_of_pons)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Physical PON ID must be in the range 0 .. %u\n", bcm_topo_context.devs[device_id].max_num_of_pons - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ if (bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon == BCM_TOPO_PON_INVALID)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Physical PON=%u on device=%u was not associated with a logical PON\n", physical_pon, device_id);
+ return BCM_ERR_RANGE;
+ }
+
+ *logical_pon = bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon;
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno bcm_topo_pon_set_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id, void *context)
+{
+ bcmolt_devid device_id;
+ uint32_t physical_pon;
+ bcmos_errno rc;
+
+ if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
+ return BCM_ERR_RANGE;
+ }
+
+ rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
+ if (rc != BCM_ERR_OK)
+ return rc;
+
+ bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id] = context;
+
+ return BCM_ERR_OK;
+}
+
+void *bcm_topo_pon_get_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id)
+{
+ bcmolt_devid device_id;
+ uint32_t physical_pon;
+ bcmos_errno rc;
+
+ if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
+ return NULL;
+ }
+
+ rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
+ if (rc != BCM_ERR_OK)
+ return NULL;
+
+ return bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id];
+}
+
+static void bcm_topo_init_context(void)
+{
+ uint32_t device_id;
+
+ for (device_id = 0; device_id < BCM_TOPO_MAX_NUM_OF_DEVS; device_id++)
+ {
+ bcm_topo_dev_context_t *dev;
+ uint32_t pon_id;
+
+ dev = &bcm_topo_context.devs[device_id];
+ dev->device_id = device_id;
+ dev->pon_mode = BCM_TOPO_PON_MODE_INVALID;
+ for (pon_id = 0; pon_id < BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV; pon_id++)
+ {
+ bcm_topo_pon_context_t *pon;
+
+ pon = &dev->pons[pon_id];
+ pon->dev = dev;
+ pon->pon_id = pon_id;
+ pon->pon_mode = BCM_TOPO_PON_MODE_INVALID;
+ pon->logical_pon = BCM_TOPO_PON_INVALID;
+ }
+ }
+}
+
+static bcmos_errno bcm_topo_init_line_parse(const char *line, const char *filename, uint32_t line_num, bcmos_bool *is_skipped, uint32_t *logical_pon, bcm_topo_pon_mode *pon_mode,
+ uint32_t *device_id, uint32_t *physical_pon)
+{
+ int rc;
+ char logical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
+ char pon_mode_str[BCM_TOPO_MAX_LINE_SIZE];
+ char device_id_str[BCM_TOPO_MAX_LINE_SIZE];
+ char physical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
+ int2str_t *p;
+
+ /* Skip blank lines and comments. */
+ if (!*line || *line == '\n' || *line == '#')
+ {
+ *is_skipped = BCMOS_TRUE;
+ return BCM_ERR_OK;
+ }
+
+ *is_skipped = BCMOS_FALSE;
+
+ /* Read the tokens separated by commas. */
+ rc = sscanf(line, "%[^,],%*[ ]%[^,],%[^,],%[^\n]", logical_pon_str, pon_mode_str, device_id_str, physical_pon_str);
+ if (rc < 4)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
+ return BCM_ERR_PARSE;
+ }
+
+ if (sscanf(logical_pon_str, "%u", logical_pon) < 1)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
+ return BCM_ERR_PARSE;
+ }
+
+ if (sscanf(device_id_str, "%u", device_id) < 1)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
+ return BCM_ERR_PARSE;
+ }
+
+ if (sscanf(physical_pon_str, "%u", physical_pon) < 1)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
+ return BCM_ERR_PARSE;
+ }
+
+ BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical Pon ID=%u, PON mode='%s')\n", *logical_pon, *device_id, *physical_pon, pon_mode_str);
+
+ for (p = pon_mode2str; p->from != -1 && strcmp(pon_mode_str, p->to); p++);
+
+ if (p->from == -1)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Error parsing PON mode at %s:%u\n", filename, line_num);
+ return BCM_ERR_PARSE;
+ }
+
+ *pon_mode = p->from;
+
+ return BCM_ERR_OK;
+}
+
+static void bcm_topo_init_dev(bcm_topo_dev_context_t *dev, bcm_topo_pon_mode pon_mode)
+{
+ dev->pon_mode = pon_mode;
+ dev->max_num_of_pons = int2int(pon_mode2max_num_of_pons, pon_mode);
+}
+
+static void bcm_topo_init_pon(bcm_topo_pon_context_t *pon, bcm_topo_pon_mode pon_mode)
+{
+ pon->pon_mode = pon_mode;
+ switch (pon_mode)
+ {
+ case BCM_TOPO_PON_MODE_GPON:
+ pon->max_num_of_onus = 128;
+ break;
+ case BCM_TOPO_PON_MODE_XGPON:
+ case BCM_TOPO_PON_MODE_XGS:
+ pon->max_num_of_onus = 256;
+ break;
+ case BCM_TOPO_PON_MODE_EPON_TDMA:
+ case BCM_TOPO_PON_MODE_EPON_1G:
+ case BCM_TOPO_PON_MODE_EPON_10G:
+ pon->max_num_of_onus = 0; /* There is no "ONU" in EPON, but LLIDs. */
+ break;
+ default:
+ break;
+ }
+}
+
+static bcmos_errno bcm_topo_init_by_file(FILE *fp, const char *filename)
+{
+ char line[BCM_TOPO_MAX_LINE_SIZE];
+ uint32_t line_num;
+
+ /* Read next line. */
+ line_num = 1;
+ while (fgets(line, sizeof(line), fp))
+ {
+ bcmos_bool is_skipped;
+ uint32_t logical_pon, device_id, physical_pon;
+ bcm_topo_pon_mode pon_mode;
+ bcm_topo_dev_context_t *dev;
+ bcm_topo_pon_context_t *pon;
+
+ if (bcm_topo_init_line_parse(line, filename, line_num, &is_skipped, &logical_pon, &pon_mode, &device_id, &physical_pon) != BCM_ERR_OK)
+ return BCM_ERR_PARSE;
+
+ if (is_skipped)
+ {
+ line_num++;
+ continue;
+ }
+
+ if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ if (bcm_topo_context.logical_pon2physical_pon[logical_pon])
+ {
+ BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u has already been set before\n", filename, line_num);
+ return BCM_ERR_ALREADY;
+ }
+
+ if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Physical device ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_DEVS - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ dev = &bcm_topo_context.devs[device_id];
+ if (!dev->is_initialized)
+ {
+ bcm_topo_init_dev(dev, pon_mode);
+ dev->is_initialized = BCMOS_TRUE;
+ }
+ else if (dev->pon_mode != pon_mode)
+ {
+ BCM_LOG(ERROR, topo_log_id, "PON mode at %s:%u conflicts with PON mode='%s' that has already been set for this device\n", filename, line_num,
+ int2str(pon_mode2str, dev->pon_mode));
+ return BCM_ERR_NOT_SUPPORTED;
+ }
+
+ if (physical_pon >= dev->max_num_of_pons)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, dev->max_num_of_pons - 1);
+ return BCM_ERR_RANGE;
+ }
+
+ pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
+ if (!pon->is_initialized)
+ {
+ bcm_topo_init_pon(pon, pon_mode);
+ pon->is_initialized = BCMOS_TRUE;
+ }
+ else
+ {
+ BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u has already been set before\n", filename, line_num);
+ return BCM_ERR_ALREADY;
+ }
+
+ bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
+ bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;
+
+ line_num++;
+ }
+
+ return BCM_ERR_OK;
+}
+
+static bcmos_errno bcm_topo_init_by_args(bcm_topo_params *params)
+{
+ uint32_t device_id;
+ uint32_t max_num_of_pons_per_dev;
+
+ if (params->num_of_devs > BCM_TOPO_MAX_NUM_OF_DEVS)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Number of devices must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS);
+ return BCM_ERR_RANGE;
+ }
+
+ max_num_of_pons_per_dev = int2int(pon_mode2max_num_of_pons, params->pon_mode);
+
+ if (params->num_of_pons_per_dev > max_num_of_pons_per_dev)
+ {
+ BCM_LOG(ERROR, topo_log_id, "Number of PONs per device for PON mode '%s' must be in the range 0 .. %u\n", int2str(pon_mode2str, params->pon_mode), BCM_TOPO_MAX_NUM_OF_DEVS);
+ return BCM_ERR_RANGE;
+ }
+
+ for (device_id = 0; device_id < params->num_of_devs; device_id++)
+ {
+ uint32_t physical_pon;
+ bcm_topo_dev_context_t *dev;
+ bcm_topo_pon_context_t *pon;
+
+ dev = &bcm_topo_context.devs[device_id];
+ bcm_topo_init_dev(dev, params->pon_mode);
+ dev->is_initialized = BCMOS_TRUE;
+
+ for (physical_pon = 0; physical_pon < params->num_of_pons_per_dev; physical_pon++)
+ {
+ uint32_t logical_pon;
+
+ logical_pon = (device_id * params->num_of_pons_per_dev) + physical_pon;
+
+ BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical pon ID=%u, PON mode='%s')\n", logical_pon, device_id, physical_pon,
+ int2str(pon_mode2str, params->pon_mode));
+
+ pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
+ bcm_topo_init_pon(pon, params->pon_mode);
+ pon->is_initialized = BCMOS_TRUE;
+
+ bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
+ bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;
+ }
+ }
+
+ return BCM_ERR_OK;
+}
+
+bcmos_errno bcm_topo_init(bcm_topo_params *params, const char *topo_filename)
+{
+ bcmos_errno ret;
+ FILE *topo_fp;
+
+#ifdef ENABLE_LOG
+ if (topo_log_id == DEV_LOG_INVALID_ID)
+ {
+ topo_log_id = bcm_dev_log_id_register("TOPOLOGY", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+ BUG_ON(topo_log_id == DEV_LOG_INVALID_ID);
+ }
+#endif
+
+ bcm_topo_init_context();
+
+ topo_fp = fopen(topo_filename, "r");
+ if (topo_fp)
+ {
+ BCM_LOG(INFO, topo_log_id, "Topology is taken from file\n");
+ ret = bcm_topo_init_by_file(topo_fp, topo_filename);
+ fclose(topo_fp);
+ }
+ else if (params)
+ {
+ BCM_LOG(INFO, topo_log_id, "Topology is taken from arguments\n");
+ ret = bcm_topo_init_by_args(params);
+ }
+ else
+ {
+ BCM_LOG(INFO, topo_log_id, "At least one of topo_fp and params must be specified and exist\n");
+ ret = BCM_ERR_PARM;
+ }
+
+ if (ret != BCM_ERR_OK)
+ goto exit;
+
+ bcm_topo_context.is_initialized = BCMOS_TRUE;
+
+ ret = BCM_ERR_OK;
+
+exit:
+ return ret;
+}
+
+bcmos_bool bcm_topo_is_initialized(void)
+{
+ return bcm_topo_context.is_initialized;
+}
+
+bcmos_bool bcm_topo_dev_set_max_nni(bcmolt_devid device_id, uint32_t num_nni_ports)
+{
+ if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
+ {
+ return BCM_ERR_PARM;
+ }
+ /* make sure the max number does not exceed the allocated resrouce */
+ if( num_nni_ports > BCM_TOPO_MAX_NNI_PORTS)
+ {
+ return BCM_ERR_PARM;
+ }
+ g_max_nni_ports[device_id] = num_nni_ports;
+
+ return BCMOS_TRUE;
+}
+
+bcmos_bool bcm_topo_dev_get_max_nni(bcmolt_devid device_id, uint32_t *p_num_nni_ports)
+{
+ if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
+ {
+ return BCM_ERR_PARM;
+ }
+ *p_num_nni_ports = g_max_nni_ports[device_id];
+
+ return BCMOS_TRUE;
+}
+
+bcmos_bool bcm_topo_nni_is_valid(uint32_t nni)
+{
+
+ if (nni >= g_max_nni_ports[0])
+ return BCMOS_FALSE;
+
+ return BCMOS_TRUE;
+}
+
diff --git a/bal_release/src/lib/libtopology/bcm_topo.h b/bal_release/src/lib/libtopology/bcm_topo.h
new file mode 100644
index 0000000..9c6ec1c
--- /dev/null
+++ b/bal_release/src/lib/libtopology/bcm_topo.h
@@ -0,0 +1,270 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+#ifndef _BCM_TOPO_H_
+#define _BCM_TOPO_H_
+
+#include <bcmolt_conv.h>
+#include <bcmos_system.h>
+#include <bcmolt_model_types.h>
+#include <bal_model_types.h>
+
+#define BCM_TOPO_DEV_INVALID UINT8_MAX
+#define BCM_TOPO_PON_INVALID UINT32_MAX
+#define BCM_TOPO_ERR_INVALID UINT32_MAX
+#define BCM_TOPO_MAX_NUM_OF_DEVS 8 /* Maxmimum of 8 devices per vOLT. */
+#define BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV 16
+#define BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS (BCM_TOPO_MAX_NUM_OF_DEVS * BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV)
+
+#define BCM_TOPO_FOR_EACH_DEV(device_id) \
+ for (device_id = bcm_topo_dev_get_next(BCM_TOPO_DEV_INVALID); device_id != BCM_TOPO_DEV_INVALID; device_id = bcm_topo_dev_get_next(device_id))
+
+#define BCM_TOPO_DEV_FOR_EACH_PON(device_id, pon) \
+ for (pon = bcm_topo_pon_get_next(device_id, BCM_TOPO_PON_INVALID); pon != BCM_TOPO_PON_INVALID; pon = bcm_topo_pon_get_next(device_id, pon))
+
+#define BCM_TOPO_FOR_EACH_PON(device_id, pon) \
+ for (device_id = bcm_topo_dev_get_next(BCM_TOPO_DEV_INVALID); device_id != BCM_TOPO_DEV_INVALID; device_id = bcm_topo_dev_get_next(device_id)) \
+ BCM_TOPO_DEV_FOR_EACH_PON(device_id, pon)
+
+#define BCM_TOPO_FOR_EACH_ONU(pon, onu) \
+ for (onu = 0; onu < bcm_topo_pon_get_max_num_of_onus(pon); onu++)
+
+typedef enum
+{
+ BCM_TOPO_PON_MODE_GPON,
+ BCM_TOPO_PON_MODE_XGPON,
+ BCM_TOPO_PON_MODE_XGS,
+ BCM_TOPO_PON_MODE_EPON_TDMA,
+ BCM_TOPO_PON_MODE_EPON_1G,
+ BCM_TOPO_PON_MODE_EPON_10G,
+ BCM_TOPO_PON_MODE_INVALID,
+ BCM_TOPO_PON_MODE__NUM_OF,
+} bcm_topo_pon_mode;
+
+typedef enum
+{
+ BCM_TOPO_PON_FAMILY_GPON, /* GPON, XGPON, XGS, NGPON2 */
+ BCM_TOPO_PON_FAMILY_EPON,
+ BCM_TOPO_PON_FAMILY_INVALID,
+ BCM_TOPO_PON_FAMILY__NUM_OF,
+} bcm_topo_pon_family;
+
+typedef enum
+{
+ BCM_TOPO_PON_SUB_FAMILY_GPON, /* GPON only */
+ BCM_TOPO_PON_SUB_FAMILY_XGPON, /* XGPON, XGS, NGPON2 */
+ BCM_TOPO_PON_SUB_FAMILY_EPON,
+ BCM_TOPO_PON_SUB_FAMILY_INVALID,
+ BCM_TOPO_PON_SUB_FAMILY__NUM_OF,
+} bcm_topo_pon_sub_family;
+
+/* User context identifier - can be extended if more modules in the system use the bcm_topo.context. */
+typedef enum
+{
+ BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL,
+ BCM_TOPO_PON_CONTEXT_ID_OMCI_SVC,
+ BCM_TOPO_PON_CONTEXT_ID_RSC_MGR,
+ BCM_TOPO_PON_CONTEXT_ID__NUM_OF,
+} bcm_topo_pon_context_id;
+
+typedef struct
+{
+ uint32_t num_of_devs;
+ uint32_t num_of_pons_per_dev;
+ bcm_topo_pon_mode pon_mode;
+} bcm_topo_params;
+
+/**
+ * @brief Get the PON mode of a given device ID.
+ * @param device_id device ID
+ *
+ * @returns PON mode or Null on error
+ */
+const char *bcm_topo_dev_get_pon_mode_str(bcmolt_devid device_id);
+
+
+/**
+ * @brief Get the max number of pons of a given device ID.
+ * @param device_id device ID
+ *
+ * @returns the max number of pons or -1 on error
+ */
+int bcm_topo_dev_get_max_pon(bcmolt_devid device_id);
+
+/**
+ * @brief Get the PON mode of a given logical PON ID.
+ * @param pon Logical PON ID
+ *
+ * @returns PON mode or BCM_TOPO_PON_MODE_INVALID on error
+ */
+bcm_topo_pon_mode bcm_topo_pon_get_pon_mode(uint32_t pon);
+
+/**
+ * @brief Get the PON family of a given logical PON ID.
+ * @param pon Logical PON ID
+ *
+ * @returns PON mode or BCM_TOPO_PON_FAMILY_INVALID on error
+ */
+bcm_topo_pon_family bcm_topo_pon_get_pon_family(uint32_t pon);
+
+/**
+ * @brief Get the PON sub-family of a given logical PON ID.
+ * @param pon Logical PON ID
+ *
+ * @returns PON mode or BCM_TOPO_PON_SUB_FAMILY_INVALID on error
+ */
+bcm_topo_pon_sub_family bcm_topo_pon_get_pon_sub_family(uint32_t pon);
+
+/**
+ * @brief Get the number of ONUs of a given logical PON ID.
+ * @param pon Logical PON ID
+ *
+ * @returns Number of ONUs or BCM_TOPO_ERR_INVALID on error
+ */
+uint32_t bcm_topo_pon_get_max_num_of_onus(uint32_t pon);
+
+/**
+ * @brief Return whether a given logical PON is in the valid range.
+ *
+ * @returns BCMOS_TRUE is the given logical PON is in the valid range, BCMOS_FALSE otherwise
+ */
+bcmos_bool bcm_topo_pon_is_valid(uint32_t pon);
+
+/**
+ * @brief Traverse devices
+ * @param device_id Device iterator. Should be BCM_TOPO_DEV_INVALID at the beginning.
+ *
+ * @returns Next device, or BCM_TOPO_DEV_INVALID to mark that no more devices are available.
+ */
+bcmolt_devid bcm_topo_dev_get_next(bcmolt_devid device_id);
+
+/**
+ * @brief Traverse logical PONs within a given device.
+ * @param device_id Device id
+ * @param pon Logical PON iterator. Should be BCM_TOPO_PON_INVALID at the beginning.
+ *
+ * @returns Next logical PON on this device, or BCM_TOPO_PON_INVALID to mark that no more PONs are available.
+ */
+uint32_t bcm_topo_pon_get_next(bcmolt_devid device_id, uint32_t pon);
+
+/**
+ * @brief Get device ID and physical PON ID from logical PON ID.
+ * @param logical_pon logical PON ID
+ * @param *device_id Pointer to device id
+ * @param *physical_pon Pointer to physical PON ID
+ *
+ * @returns bcmos_errno
+ * @note In general, the physical PON ID is used in the hardware directed function calls.
+ */
+bcmos_errno bcm_topo_pon_get_logical2physical(uint32_t logical_pon, bcmolt_devid *device_id, uint32_t *physical_pon);
+
+/**
+ * @brief Get logical PON ID from device ID and physical PON ID.
+ * @param device_id Device id
+ * @param physical_pon Physical PON ID
+ * @param *logical_pon Pointer to logical PON ID
+ *
+ * @returns bcmos_errno
+ * @note In general, the logical PON ID is used in the BAL core directed function calls.
+ */
+bcmos_errno bcm_topo_pon_get_physical2logical(bcmolt_devid device_id, uint32_t physical_pon, uint32_t *logical_pon);
+
+/**
+ * @brief Set user context for a given logical PON ID.
+ * @param pon Logical PON ID
+ * @param pon_context_id The identity of the module using the context
+ * @param context Pointer to user context
+ *
+ * @returns bcmos_errno
+ */
+bcmos_errno bcm_topo_pon_set_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id, void *context);
+
+/**
+ * @brief Get user context for a given logical PON ID.
+ * @param pon Logical PON ID
+ * @param pon_context_id The identity of the module using the context
+ *
+ * @returns User context or NULL if there's an error
+ */
+void *bcm_topo_pon_get_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id);
+
+/**
+ * @brief Initialize topology module, either by arguments (probably received from CLI) or by a topology file. The rule is at least one of them must be specified and exist. If both are
+ * specified and exist, then we rely on topology file.
+ * Pay attention that when not using a file, the user have less freedom. For example:
+ * - The user won't be able to have devices with different PON modes.
+ * - The user won't be able to have devices with different number of PONs.
+ * - The user won't be able to map logical PON to (device, physical PON). We assume that logical_pon = (device * num_of_pons_per_dev) + physical_pon.
+ * @param params Topology parameters. If NULL, we rely on topology file.
+ * @param topo_filename File containing bcm_topo.configuration in a .csv format
+ * The columns are:
+ * Logical PON ID, PON Mode, Physical Device ID, Physical PON ID
+ *
+ * @returns bcmos_errno
+ */
+bcmos_errno bcm_topo_init(bcm_topo_params *params, const char *topo_filename);
+
+/**
+ * @brief Returns whether the topology module has been initialized.
+ *
+ * @returns BCMOS_TRUE if topology module has been initialized
+ */
+bcmos_bool bcm_topo_is_initialized(void);
+
+#define BCM_TOPO_MAX_NNI_PORTS 16
+
+/**
+ * @brief Set the max number of nnis of a given device ID.
+ * @param device_id device ID
+ * @param num_nni_ports nni ports on the device
+ *
+ * @returns BCMOS_TRUE
+ */
+bcmos_bool bcm_topo_dev_set_max_nni(bcmolt_devid device_id, uint32_t num_nni_ports);
+
+/**
+ * @brief Get the max number of nnis of a given device ID.
+ * @param device_id device ID
+ * @param p_num_nni_ports pointer for the retrieved nni ports on the device
+ *
+ * @returns BCMOS_TRUE
+ */
+bcmos_bool bcm_topo_dev_get_max_nni(bcmolt_devid device_id, uint32_t *p_num_nni_ports);
+
+/**
+ * @brief Return whether a given logical NNI is in the valid range.
+ *
+ * @returns BCMOS_TRUE is the given logical NNI is in the valid range, BCMOS_FALSE otherwise
+ */
+bcmos_bool bcm_topo_nni_is_valid(uint32_t nni);
+
+#endif
+
diff --git a/bal_release/src/lib/libutils/Makefile b/bal_release/src/lib/libutils/Makefile
new file mode 100644
index 0000000..8b4dd50
--- /dev/null
+++ b/bal_release/src/lib/libutils/Makefile
@@ -0,0 +1,35 @@
+###############################################################################
+#
+# <:copyright-BRCM:2016:DUAL/GPL:standard
+#
+# Copyright (c) 2016 Broadcom
+# All Rights Reserved
+#
+# Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed
+# to you under the terms of the GNU General Public License version 2
+# (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+# with the following added to such license:
+#
+# As a special exception, the copyright holders of this software give
+# you permission to link this software with independent modules, and
+# to copy and distribute the resulting executable under terms of your
+# choice, provided that you also meet, for each linked independent
+# module, the terms and conditions of the license of that module.
+# An independent module is a module which is not derived from this
+# software. The special exception does not apply to any modifications
+# of the software.
+#
+# Not withstanding the above, under no circumstances may you combine
+# this software in any way with any other Broadcom software provided
+# under a license other than the GPL, without Broadcom's express prior
+# written consent.
+#
+# :>
+#
+###############################################################################
+MOD_NAME = balutils
+MOD_TYPE = lib
+
+srcs = bal_utils.c
+
diff --git a/bal_release/src/lib/libutils/bal_utils.c b/bal_release/src/lib/libutils/bal_utils.c
new file mode 100644
index 0000000..024b3d9
--- /dev/null
+++ b/bal_release/src/lib/libutils/bal_utils.c
@@ -0,0 +1,541 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_utils.c
+ * @brief BAL Utilities source
+ *
+ * This file contains the implementation of various BAL "utilities",
+ * which are provided via the libutils.a library.
+ */
+
+/*@{*/
+
+#ifdef USING_BAL_UTILS
+
+/* --- system includes ---*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include <bcmos_system.h>
+
+/* --- project includes ---*/
+#include "bal_utils.h"
+
+
+/*
+ * Generic helper functions
+ */
+char *mac_addr_to_str(char *buffer, bcmos_mac_address mac)
+{
+ char *fmt_str = NULL;
+
+ fmt_str = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
+
+ snprintf(buffer, 20, fmt_str,
+ mac.u8[0], mac.u8[1],
+ mac.u8[2], mac.u8[3],
+ mac.u8[4], mac.u8[5]);
+
+ return buffer;
+}
+
+
+bcmos_bool mac_add_is_null(bcmos_mac_address mac)
+{
+ return ((0 != mac.u8[0]) || (0 != mac.u8[1]) || (0 != mac.u8[2]) ||
+ (0 != mac.u8[3]) || (0 != mac.u8[4]) || (0 != mac.u8[5])) ? BCMOS_FALSE : BCMOS_TRUE;
+}
+
+/**
+ * @brief Determines if string contains a valid IPv4 or IPv6 address
+ *
+ *
+ * @param ipAddrStr Pointer to string to parse
+ *
+ * @return bcmos_bool
+ * @retval TRUE String contains a valid IP address
+ * @retval FALSE String does not
+ */
+bcmos_bool BalIsValidIp(const char *ipAddrStr)
+{
+ struct sockaddr_in addr4;
+ struct in6_addr addr6;
+ bcmos_bool ret = BCMOS_FALSE;
+
+ /* Parameter checks. */
+ BUG_UNLESS(NULL != ipAddrStr, BCMOS_FALSE);
+
+ /* First look to see if it's a valid IPv4 address, then look to see if it's
+ a valid IPv6 address*/
+ if (inet_pton(AF_INET, ipAddrStr, &addr4) > 0 || inet_pton(AF_INET6, ipAddrStr, &addr6) > 0)
+ {
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Convert a string to the specified type of integer
+ *
+ * NOTE: This function uses the strtoll() function to convert the string to an
+ * integer value. U64 values greater than 0x7fffffffffffffff cannot be converted
+ * by the strtoll() function because the string value is considered out of the
+ * valid -0x8000000000000000 to 0x7fffffffffffffff 64-bit integer range.
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+static bcmos_errno BalStringToInt(char *str, BalIntStringT *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ U64 u64 = 0;
+ S64 s64 = 0;
+ char *endptr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+ BUG_UNLESS(pVal->intType > BAL_STR2INT_INVALID, BAL_PARAM);
+ BUG_UNLESS(pVal->intType < BAL_STR2INT_MAX, BAL_PARAM);
+
+ do
+ {
+ if ((pVal->intType >= BAL_STR2INT_S8) &&
+ (pVal->intType <= BAL_STR2INT_S64))
+ {
+ /* Just assume a signed 64-bit value when converting the string to
+ * an integer. Range checking is done below. Make sure that errno
+ * is set to zero before calling strtoll().
+ */
+ errno = 0;
+ pVal->intU.s64 = 0; /* Clear all possibilities to 0 */
+ s64 = strtoll(str, &endptr, 10);
+
+ /* General range and error check */
+ if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
+ || (errno != 0 && s64 == 0))
+ {
+ errno = 0;
+ rc = BCM_ERR_RANGE;
+ break;
+
+ }
+
+ /* test for no digits or mixed digits and characters */
+ if (endptr == str || '\0' != *endptr)
+ {
+ errno = 0;
+ rc = BCM_ERR_PARM;
+ break;
+ }
+
+ /* routine specific range check */
+ switch (pVal->intType)
+ {
+ case BAL_STR2INT_S8:
+ if ((s64 < -128) || (s64 > 127))
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.s8 = (S8)s64;
+ }
+ break;
+ case BAL_STR2INT_S16:
+ if ((s64 < -32768) || (s64 > 32767))
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.s16 = (S16)s64;
+ }
+ break;
+ case BAL_STR2INT_S32:
+ if ((s64 < (-2147483647L -1L)) || (s64 > 2147483647L))
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.s32 = (S32)s64;
+ }
+ break;
+ case BAL_STR2INT_S64:
+ /* No range checking is needed since the strtoll() function
+ * does the range checking. If the string was invalid, errno
+ * would have been non-zero.
+ */
+ pVal->intU.s64 = s64;
+ break;
+ default:
+ /* Should never make it here. */
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ else {
+ /* Just assume an unsigned 64-bit value when converting the string
+ * to an integer. Range checking is done below. Make sure that errno
+ * is set to zero before calling strtoull().
+ */
+ errno = 0;
+ pVal->intU.u64 = 0;
+ u64 = strtoull(str, &endptr, 10);
+
+ /* General range and error check */
+ if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
+ || (errno != 0 && s64 == 0))
+ {
+ errno = 0;
+ rc = BCM_ERR_RANGE;
+ break;
+
+ }
+
+ /* test for no digits or mixed digits and characters */
+ if (endptr == str || '\0' != *endptr)
+ {
+ errno = 0;
+ rc = BCM_ERR_PARM;
+ break;
+ }
+
+ /* routine specific range check */
+ switch(pVal->intType)
+ {
+ case BAL_STR2INT_U8:
+ if (u64 > 255)
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.u8 = (U8)u64;
+ }
+ break;
+ case BAL_STR2INT_U16:
+ if (u64 > 65535)
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.u16 = (U16)u64;
+ }
+ break;
+ case BAL_STR2INT_U32:
+ if (u64 > 4294967295UL)
+ {
+ rc = BCM_ERR_RANGE;
+ }
+ else
+ {
+ pVal->intU.u32 = (U32)u64;
+ }
+ break;
+ case BAL_STR2INT_U64:
+ /* No range checking is needed since the strtoull() function
+ * does the range checking. If the string was invalid, errno
+ * would have been non-zero.
+ */
+ pVal->intU.u64 = u64;
+ break;
+ default:
+ /* Should never make it here. */
+ rc = BCM_ERR_PARM;
+ break;
+ }
+ }
+ } while (0);
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to an S8 type integer
+ *
+ * This function converts a string to an S8 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToS8(char *str, S8 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_S8;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.s8;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to an S16 type integer
+ *
+ * This function converts a string to an S16 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToS16(char *str, S16 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_S16;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.s16;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to an S32 type integer
+ *
+ * This function converts a string to an S32 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToS32(char *str, S32 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_S32;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.s32;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to an S64 type integer
+ *
+ * This function converts a string to an S64 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToS64(char *str, S64 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_S64;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.s64;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to a U8 type integer
+ *
+ * This function converts a string to a U8 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToU8(char *str, U8 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_U8;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.u8;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to a U16 type integer
+ *
+ * This function converts a string to a U16 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToU16(char *str, U16 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_U16;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.u16;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to a U32 type integer
+ *
+ * This function converts a string to a U32 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToU32(char *str, U32 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_U32;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.u32;
+ }
+
+ return(rc);
+}
+
+/**
+ * @brief Convert a string to a U64 type integer
+ *
+ * This function converts a string to a U64 type integer
+ *
+ * @param str String to convert
+ * @param pVal Pointer to the return value
+ *
+ * @return bcmos_errno
+ */
+bcmos_errno BalStringToU64(char *str, U64 *pVal)
+{
+ bcmos_errno rc = BAL_OK;
+ BalIntStringT intStr;
+
+ BUG_UNLESS(NULL != str, BAL_PARAM);
+ BUG_UNLESS(NULL != pVal, BAL_PARAM);
+
+ memset(&intStr, 0, sizeof(intStr));
+
+ intStr.intType = BAL_STR2INT_U64;
+
+ rc = BalStringToInt(str, &intStr);
+ if (BAL_OK == rc)
+ {
+ *pVal = intStr.intU.u64;
+ }
+
+ return(rc);
+}
+
+
+#endif /* USING_BAL_UTILS */
diff --git a/bal_release/src/lib/libutils/bal_utils.h b/bal_release/src/lib/libutils/bal_utils.h
new file mode 100644
index 0000000..78c6134
--- /dev/null
+++ b/bal_release/src/lib/libutils/bal_utils.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/**
+ * @file bal_utils.h
+ * @brief BAL Utilities include file
+ *
+ */
+
+#ifndef BALUTILS_H
+#define BALUTILS_H
+
+/*@{*/
+
+/**
+ * @brief General purpose BAL String structure.
+ *
+ * This is typically used for debugging or log messages.
+ */
+#define BAL_STRING_LENGTH 256
+
+#define MAC_STR_LEN 18
+
+/**
+ * @brief BAL String Structure
+ */
+typedef struct bal_string
+{
+ char str[BAL_STRING_LENGTH+1]; /**< The string */
+} bal_string;
+
+extern char *mac_addr_to_str(char *buffer, bcmos_mac_address mac);
+extern bcmos_bool mac_add_is_null(bcmos_mac_address mac);
+
+/*@}*/
+
+#endif /* BALUTILS_H */
diff --git a/bal_release/tools/copyright_tools/insert_copyright.pl b/bal_release/tools/copyright_tools/insert_copyright.pl
new file mode 100755
index 0000000..6f01d1a
--- /dev/null
+++ b/bal_release/tools/copyright_tools/insert_copyright.pl
@@ -0,0 +1,169 @@
+#!/usr/bin/perl
+###############################################################################
+#
+# Copyright 2015 Broadcom Corporation
+#
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified or
+# distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom (an
+# "Authorized License"). Except as set forth in an Authorized License,
+# Broadcom grants no license (express or implied), right to use, or
+# waiver of any kind with respect to the Software, and Broadcom
+# expressly reserves all rights in and to the Software and all
+# intellectual property rights therein. IF YOU HAVE NO AUTHORIZED
+# LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND
+# SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE
+# SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+# "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+# OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+# OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+# OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
+# RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
+# BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+# ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
+# ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+# NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
+# REMEDY.
+#
+###############################################################################
+#
+# Script: insert_copyright.pl
+#
+# Purpose: This script inserts a copyright header into the beginning
+# of a c/c++, shell script, and Makefiles.
+#
+# Usage: ./insert_copyright.pl -l <license file> [-t <type>] <source file>
+# Options:
+#
+# -l <file> Specifies the license/copyright file to be inserted into the file
+# -t <type> Specifies the type of copyright to insert...
+# 's' - shell script
+# 'm' - Makefile
+# 'c' - (default) c/c++ file
+#
+###############################################################################
+use Getopt::Long;
+my $licfile = "";
+my $srcfile = "";
+my $type = "";
+$result = GetOptions ("license_file=s" => \$licfile,
+ "type=s" => \$type);
+
+$srcfile = shift;
+
+## printf "$licfile, $type, $srcfile\n";
+
+sub InsertCfileCopyright
+{
+ my $lic = shift;
+ my $src = shift;
+
+ print "/******************************************************************************\n";
+ print " *\n";
+
+ open( LICF, "< $lic" ) or die "Can't open $lic : $!";
+ while( $line = <LICF> ) {
+ print " * $line";
+ }
+ close LICF;
+
+ print " *\n";
+ print " *****************************************************************************/\n";
+ print " \n";
+
+ if (length($srcfile) > 0) {
+ open( SRCF, "< $src" ) or die "Can't open $src : $!";
+ while( $line = <SRCF> ) {
+ print "$line";
+ }
+ close SRCF;
+ }
+}
+
+sub InsertMakefileCopyright
+{
+ my $lic = shift;
+ my $src = shift;
+
+ print "###############################################################################\n";
+ print "#\n";
+
+ open( LICF, "< $lic" ) or die "Can't open $lic : $!";
+ while( $line = <LICF> ) {
+ print "# $line";
+ }
+ close LICF;
+
+ print "#\n";
+ print "###############################################################################\n";
+
+ if (length($srcfile) > 0) {
+ open( SRCF, "< $src" ) or die "Can't open $src : $!";
+ while( $line = <SRCF> ) {
+ print "$line";
+ }
+ close SRCF;
+ }
+}
+
+sub InsertShCopyright
+{
+ my $lic = shift;
+ my $src = shift;
+
+ if (length($srcfile) > 0) {
+ open( SRCF, "< $src" ) or die "Can't open $src : $!";
+ $line = <SRCF>;
+ print "$line";
+ }
+
+ print "###############################################################################\n";
+ print "#\n";
+
+ open( LICF, "< $lic" ) or die "Can't open $lic : $!";
+ while( $line = <LICF> ) {
+ print "# $line";
+ }
+ close LICF;
+
+ print "#\n";
+ print "###############################################################################\n";
+
+ if (length($srcfile) > 0) {
+ while( $line = <SRCF> ) {
+ print "$line";
+ }
+ close SRCF;
+ }
+}
+
+if ($type eq "s") {
+ InsertShCopyright($licfile, $srcfile);
+} elsif ($type eq "m") {
+ InsertMakefileCopyright($licfile, $srcfile);
+} elsif ($type eq "c" || $type == "") {
+ InsertCfileCopyright($licfile, $srcfile);
+}
+
+exit;
+
+
diff --git a/bal_release/tools/copyright_tools/strip_c_copyright.pl b/bal_release/tools/copyright_tools/strip_c_copyright.pl
new file mode 100755
index 0000000..2464c58
--- /dev/null
+++ b/bal_release/tools/copyright_tools/strip_c_copyright.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+###############################################################################
+#
+# Copyright 2008-2014 Broadcom Corporation
+#
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified or
+# distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom (an
+# "Authorized License"). Except as set forth in an Authorized License,
+# Broadcom grants no license (express or implied), right to use, or
+# waiver of any kind with respect to the Software, and Broadcom
+# expressly reserves all rights in and to the Software and all
+# intellectual property rights therein. IF YOU HAVE NO AUTHORIZED
+# LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND
+# SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE
+# SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+# "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+# OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+# OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+# OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
+# RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
+# BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+# ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
+# ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+# NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
+# REMEDY.
+#
+###############################################################################
+#
+# Script: strip_c_copyright.pl
+#
+# Purpose: This script removes a copyright header from a c/c++
+# file. The file is passed into the perl script via STDIN, so this
+# script must be used in conjunction with something like 'cat'.
+#
+# Usage: cat <file> | ./strip_c_copyright.pl
+#
+#
+# Previous attemps at c-style regular expressions...
+# s#(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/).*\n##;
+# s#(?:\/\*.*Copyright\(c\)(?:[^*]|(?:\*+[^*\/]))*\*+\/).*\n|(?:\/\*(?:[^*]|(?:\*+[^*\/]))*Copyright\(c\)(?:[^*]|(?:\*+[^*\/]))*\*+\/).*\n##;
+# good => s#(?:\/\*.*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*\n|(?:\/\*(?:[^*]|(?:\*+[^*\/]))*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*\n##;
+# good => s#(?:\/\*.*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*(?:\s)+|(?:\/\*(?:[^*]|(?:\*+[^*\/]))*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*(?:\s)+##;
+#
+# The following regex can be used for removing redundant C++
+# copyright header from libssd files...
+#
+# s#\/\/\*+[^*]*Copyright[^*]*\/\/\*+#//****************************************************************************#;
+#
+###############################################################################
+
+$/ = undef;
+$_ = <>;
+
+#
+# The following regex handles the old Teknovus-style copyright headers
+#
+# e.g. "/* Copyright(c) 2008-2012 Broadcom, Corp. */"
+#
+#s#(?:\/\*.*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*(?:\s)+##;
+
+#
+# The following regex handles the new Broadcom standard copyright headers
+#
+s#(?:\/\*(?:[^*]|(?:\*+[^*\/]))*Copyright(?:[^*]|(?:\*+[^*\/]))*\*+\/).*(?:\s)+##;
+print;
+
diff --git a/bal_release/tools/copyright_tools/strip_sh_copyright.pl b/bal_release/tools/copyright_tools/strip_sh_copyright.pl
new file mode 100755
index 0000000..82406b1
--- /dev/null
+++ b/bal_release/tools/copyright_tools/strip_sh_copyright.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+###############################################################################
+#
+# Copyright 2008-2014 Broadcom Corporation
+#
+# This program is the proprietary software of Broadcom Corporation
+# and/or its licensors, and may only be used, duplicated, modified or
+# distributed pursuant to the terms and conditions of a separate,
+# written license agreement executed between you and Broadcom (an
+# "Authorized License"). Except as set forth in an Authorized License,
+# Broadcom grants no license (express or implied), right to use, or
+# waiver of any kind with respect to the Software, and Broadcom
+# expressly reserves all rights in and to the Software and all
+# intellectual property rights therein. IF YOU HAVE NO AUTHORIZED
+# LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND
+# SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE
+# SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+# "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+# OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+# OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+# OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY
+# RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF
+# BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+# ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE
+# ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+# NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED
+# REMEDY.
+#
+###############################################################################
+#
+# Script: strip_sh_copyright.pl
+#
+# Purpose: This script removes a copyright header from a shell script
+# file or Makefile. The file is passed into the perl script via
+# STDIN, so this script must be used in conjunction with something
+# like 'cat'.
+#
+# Usage: cat <file> | ./strip_sh_copyright.pl
+#
+###############################################################################
+
+$/ = undef;
+$_ = <>;
+s/##+(?:[^#]|(?:#[^#])*)*Copyright(?:[^#]|(?:#[^#])*)*##+\n//g;
+print;
diff --git a/bal_release/tools/copyright_tools/update_copyright.sh b/bal_release/tools/copyright_tools/update_copyright.sh
new file mode 100755
index 0000000..15f414d
--- /dev/null
+++ b/bal_release/tools/copyright_tools/update_copyright.sh
@@ -0,0 +1,221 @@
+#!/bin/sh
+###############################################################################
+#
+# <:copyright-BRCM:2016:proprietary:standard
+#
+# Broadcom Ltd. Proprietary and Confidential.(c) 2016 Broadcom Ltd.
+# All Rights Reserved
+#
+# This program is the proprietary software of Broadcom Ltd. and/or its
+# licensors, and may only be used, duplicated, modified or distributed pursuant
+# to the terms and conditions of a separate, written license agreement executed
+# between you and Broadcom Ltd. (an "Authorized License"). Except as set forth in
+# an Authorized License, Broadcom Ltd. grants no license (express or implied), right
+# to use, or waiver of any kind with respect to the Software, and Broadcom Ltd.
+# expressly reserves all rights in and to the Software and all intellectual
+# property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+# NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+# BROADCOM LTD AND DISCONTINUE ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom Ltd., and you shall use
+# all reasonable efforts to protect the confidentiality thereof, and to
+# use this information only in connection with your use of Broadcom Ltd.
+# integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+# RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+# ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+# FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+# COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+# TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+# PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+# INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+# WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+# IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+# OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+# SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+# LIMITED REMEDY.
+# :>
+#
+###############################################################################
+#
+# Script: update_copyright.sh
+#
+# Purpose: This script updates the copyright comment headers in
+# c/c++, shell script, and Makefiles. Depending on the options
+# specified below, this script will also automatically create a
+# Perforce changelist and checkout the files before updating the
+# copyright headers.
+#
+# Usage: ./update_copyright.sh [-c chglist num|"none"] <files>
+# Options:
+#
+# -c num|"none" If -c is specified with a Perforce changelist
+# number, then files that are updated by this
+# script will be put into the specified changelist.
+#
+# If '-c none' is specified, the script will not
+# execute any Perforce commands before updating the
+# copyright in files. The user is expected to checkout
+# the files prior to excuting this script.
+#
+# If -c is not specified (default), a new change list
+# is created and all updated files are put into the new
+# change list.
+#
+#
+# This script makes use of the following perl scripts:
+# strip_c_copyright.pl - Strips a copyright header from a c/c++ file.
+# strip_sh_copyright.pl - Strips a copyright header from a Makefile or shell
+# script.
+# insert_copyright.pl - Inserts a copyright header into a c/c++, shell script,
+# or Makefile file.
+#
+#
+# --------------------------
+# Copyright Update Procedure
+# --------------------------
+#
+# The following procedure should be used to update the copyright information.
+#
+# 1) find . -regextype egrep -regex '.*\.c|.*\.h|.*\.cpp|.*Makefile|.*Makefile\.sdk|.*\.mk|.*\.sh' | xargs $PROJROOT/tools/copyright_tools/update_copyright.sh
+#
+# To exlude a directory from the search, use the following command
+#
+# 1a) find . -path ./3rdparty -prune -o -regextype egrep -regex '.*\.c|.*\.h|.*\.cpp|.*Makefile|.*Makefile\.sdk|.*\.mk|.*\.sh' | xargs $PROJROOT/tools/copyright_tools/update_copyright.sh
+#
+# 2) Update the "Copyright (c)" statement in the debug CLI (./lib/libdbg/dbgCli.c)
+# - Note: newer versions of the script may already handle this automatically.
+#
+# 3) Update the following files by hand because they do not follow
+# the standard source file naming conventions:
+# - bal/cur/3rdparty/indigo/indigo/modules/ofpal_driver/module/src/ofpal_driver.c
+# - bal/cur/3rdparty/indigo/indigo/modules/ofpal-driver/utest/main.c
+# - bal/cur/doxygen/Makefile
+#
+# Also, you can use the following command to find additional straglers...
+#
+# find . | xargs grep 2013
+#
+# (Optional) Use the following procedure to verify the changes.
+#
+# a) Use p4 to build a list of files that are being modified by this CL.
+#
+# p4 describe <CL from step1> | grep '^\.\.\.' | awk '{print $2}' | sed 's%//SystemSoftware/Rel/pioneer/dml/%%g' | sed 's%\#.$%%g' > p4_changes_files.txt
+#
+# b) Add the following bash script to a file called temp.sh and
+# add execute permissions to the file.
+#
+# #!/bin/sh
+# #
+# while read -r line; do
+# echo "$line: "`p4 diff -ds $line | grep changed`
+# done < p4_changes_files.txt
+#
+# c) Run the script
+#
+# ./temp.sh | tee p4_diffs.txt
+#
+# d) Check the scripe for unusual/unexpected changes and use 'p4 diff file'
+# to investigate.
+#
+# cat p4_diffs.txt | grep -v "changed 1 chunks 1 / 1 lines" | tee t1.txt
+#
+#
+###############################################################################
+
+COPYRIGHT_FILE=${PROJROOT}/COPYRIGHT
+P4_CHANGELIST_DESC="Copyright Header Update - "`date`
+
+if [ "$1" = "-c" ]
+ then
+ P4_CHANGELIST_NUM="$2"
+
+ if [ "$P4_CHANGELIST_NUM" = "" ]
+ then
+ echo "ERROR: must specify 'none' or P4 change list number for the '-c' option."
+ exit 1
+ elif [ "$P4_CHANGELIST_NUM" = "none" ]
+ then
+ echo "NOTE: Perforce commands will be skipped"
+ else
+ echo "Using existing change list $P4_CHANGELIST_NUM"
+ fi
+ shift ; shift
+else
+ P4_CHANGELIST_NUM=`echo -e "Change: new\nDescription: ${P4_CHANGELIST_DESC}" | p4 change -i | cut -d " " -f 2`
+ echo "Created change list $P4_CHANGELIST_NUM"
+fi
+
+for path in "$@"
+do
+ file=`basename $path`
+
+ file_ext="${file#*.}"
+
+ # Only checkout files from perforce is an existing or new change list was specified
+ if [ "$P4_CHANGELIST_NUM" != "none" ]
+ then
+
+ # Only update text files
+ p4_file_type=`p4 fstat $path | grep headType | cut -d " " -f 3 | grep -o text`
+ if [ "$p4_file_type" != "text" ]
+ then
+ echo "WARNING: skipping file '$path' because it it not a text file."
+ continue ### resumes iteration of an enclosing for loop ###
+ fi
+
+ # Open the file for editing
+ p4 opened $path 2>&1 | grep -q "not opened"
+ if [ $? != 0 ]
+ then
+ echo "WARNING: file '$path' is already opened for edit..."
+ else
+ p4 edit -c $P4_CHANGELIST_NUM $path &>/dev/null
+ fi
+ fi
+
+ # Update the Copyright based on file type
+ if [ "$file_ext" == "c" ] || [ "$file_ext" == "h" ] || [ "$file_ext" == "cpp" ]
+ then
+ #
+ # C/C++ files
+ #
+ echo -ne "Updating '$file', type = c/c++ ... "
+ cat $path | perl ${PROJROOT}/tools/copyright_tools/strip_c_copyright.pl > $path"_crtemp";
+ perl ${PROJROOT}/tools/copyright_tools/insert_copyright.pl -t c -l ${COPYRIGHT_FILE} $path"_crtemp" > $path;
+ rm $path"_crtemp"
+ echo "done."
+ elif [ "$file_ext" == "sh" ]
+ then
+ #
+ # Shell script files
+ #
+ echo -ne "Updating '$file', type = shell script ... "
+ cat $path | perl ${PROJROOT}/tools/copyright_tools/strip_sh_copyright.pl > $path"_crtemp";
+ perl ${PROJROOT}/tools/copyright_tools/insert_copyright.pl -t s -l ${COPYRIGHT_FILE} $path"_crtemp" > $path;
+ rm $path"_crtemp"
+ echo "done."
+ elif [ "$file" == "Makefile" ] || [ "$file" == "Makefile.sdk" ] || [ "$file_ext" == "mk" ]
+ then
+ #
+ # Makefiles
+ #
+ echo -ne "Updating '$file', type = Makefile ... "
+ cat $path | perl ${PROJROOT}/tools/copyright_tools/strip_sh_copyright.pl > $path"_crtemp";
+ perl ${PROJROOT}/tools/copyright_tools/insert_copyright.pl -t m -l ${COPYRIGHT_FILE} $path"_crtemp" > $path;
+ rm $path"_crtemp"
+ echo "done."
+ else
+ echo "Skipping $file, type = unknown type"
+ fi
+done
\ No newline at end of file