BAL and Maple Release 2.2

Signed-off-by: Shad Ansari <developer@Carbon.local>
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, &current_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, 
+                      &current_entry->agg_port_id_list, 
+                      next)
+        {
+           
+             bcmos_free(agg_port_entry); 
+        } 
+
+        /* free the service port list */
+        TAILQ_FOREACH(svc_port_entry, 
+                      &current_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(&current_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(&current_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 */