BAL and Maple Release 2.2

Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_customized/os_abstraction/Makefile b/bcm68620_release/release/host_customized/os_abstraction/Makefile
new file mode 100644
index 0000000..258f45f
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/Makefile
@@ -0,0 +1,51 @@
+# OS abstraction layer
+#
+MOD_NAME = os
+MOD_TYPE = lib
+MOD_INC_DIRS = $(SRC_DIR) $(SRC_DIR)/$(OS)
+MOD_INC_DIRS += $(OS_PLATFORM_DIR) $(CONFIG_DIR)
+MOD_SUPPRESS_OS_DEP = y
+
+ifeq ("$(OS)", "threadx")
+	MOD_DEPS = threadx bsp
+	MOD_INC_DIRS += $(SUBSYSTEM)/sys/inc
+	MOD_DEFS = -DBCMOS_TRACE_IN_DEV_LOG
+endif
+
+ifeq ("$(OS)", "posix")
+	ENABLE_MSG_QUEUE_DOMAIN_SOCKET ?= y
+	ENABLE_MSG_QUEUE_UDP_SOCKET ?= y
+endif
+
+ifeq ("$(ENABLE_MSG_QUEUE_DOMAIN_SOCKET)", "y")
+	MOD_DEFS += -DBCMOS_MSG_QUEUE_DOMAIN_SOCKET
+endif
+
+ifeq ("$(ENABLE_MSG_QUEUE_UDP_SOCKET)", "y")
+	MOD_DEFS += -DBCMOS_MSG_QUEUE_UDP_SOCKET
+endif
+
+ifeq ("$(BUF_IN_DMA_MEM)", "y")
+	EXTRA_CFLAGS += -DBCMOS_BUF_IN_DMA_MEM
+    BUF_DATA_UNIT_SIZE ?= 1024
+	EXTRA_CFLAGS += -DBCMOS_BUF_DATA_UNIT_SIZE=$(BUF_DATA_UNIT_SIZE)
+endif
+
+ifneq ("$(BUF_POOL_SIZE)", "")
+    ifeq ("$(BUF_POOL_BUF_SIZE)", "")
+        BUF_POOL_BUF_SIZE = 4096
+    endif
+    EXTRA_CFLAGS += -DBCMOS_BUF_POOL_SIZE=$(BUF_POOL_SIZE) -DBCMOS_BUF_POOL_BUF_SIZE=$(BUF_POOL_BUF_SIZE)
+endif
+
+srcs  = bcmos_common.c bcmos_errno.c bcmos_hash_table.c bcmos_rw_lock.c $(OS)/bcmos_system.c
+
+ifeq ("$(DEBUG)", "y")
+	MOD_DEFS	+= -DBCMOS_MEM_DEBUG -DBCMOS_SYS_UNITTEST
+endif
+
+ifeq ("$(SUBSYSTEM)", "embedded")
+    USE_LINT = yes
+endif
+
+#EXTRA_DEFINES += -DBCMOS_SYS_UNITTEST
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.c b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.c
new file mode 100644
index 0000000..d2d552a
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.c
@@ -0,0 +1,2772 @@
+/*
+<: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"
+
+/* task control blocks */
+STAILQ_HEAD(task_list, bcmos_task) task_list = STAILQ_HEAD_INITIALIZER(task_list);
+
+/* module control blocks */
+bcmos_module *bcmos_modules[BCMOS_MODULE_ID__NUM_OF];
+
+/* event control blocks */
+bcmos_event *bcmos_events[BCMOS_EVENT_ID__NUM_OF];
+
+/* Global trace level */
+bcmos_trace_level bcmos_sys_trace_level = BCMOS_TRACE_LEVEL_ERROR;
+
+/* Global OS mutex */
+bcmos_mutex bcmos_res_lock;
+
+/* Total memory occupied by block pools */
+uint32_t bcmos_total_blk_pool_size;
+
+/* Total memory occupied by message pools */
+uint32_t bcmos_total_msg_pool_size;
+
+f_bcmolt_sw_error_handler sw_error_handler;
+
+/* Block pools */
+static STAILQ_HEAD(blk_pool_list, bcmos_blk_pool) blk_pool_list = STAILQ_HEAD_INITIALIZER(blk_pool_list);
+
+/* Message pools */
+static STAILQ_HEAD(msg_pool_list, bcmos_blk_pool) msg_pool_list = STAILQ_HEAD_INITIALIZER(msg_pool_list);
+
+/* Message queues */
+static STAILQ_HEAD(msg_queue_list, bcmos_msg_queue) msg_queue_list = STAILQ_HEAD_INITIALIZER(msg_queue_list);
+
+/* Message queue groups */
+static STAILQ_HEAD(msg_qgroup_list, bcmos_msg_qgroup) msg_qgroup_list = STAILQ_HEAD_INITIALIZER(msg_qgroup_list);
+
+/* Lock used to protect msg registration / deregistration */
+static bcmos_fastlock bcmos_msg_register_lock;
+
+/* Shutdown mode: when this is set, we expect message handler deregistration to happen while messages are still being
+ * sent/received. We should handle this gracefully. */
+static bcmos_bool bcmos_msg_shutdown_mode = BCMOS_FALSE;
+
+/* Timer management block */
+typedef struct bcmos_timer_pool
+{
+    bcmos_fastlock lock;                        /* Pool protection lock */
+    bcmos_sys_timer sys_timer;                  /* System timer handle */
+    uint32_t num_active_timers;                 /* Number of active timers in the pool */
+#ifdef BCMOS_TIMER_RB_TREE
+    RB_HEAD(bcmos_timers, bcmos_timer) pool;    /* Timer pool. RB tree */
+#else
+    TAILQ_HEAD(bcmos_timers, bcmos_timer) pool; /* Timer pool: TAILQ */
+#endif
+} bcmos_timer_pool;
+
+static int32_t _bcmos_timer_compare(bcmos_timer *t1, bcmos_timer *t2);
+
+/*
+ * Macros for RB-TREE and TAILQ-based timer tool implementations
+ */
+
+#ifdef BCMOS_TIMER_RB_TREE
+
+#ifdef __arm__
+/* ARM compiler doesn't like unused inline functions. Disable the warning */
+#pragma diag_suppress 177
+#endif
+
+/* Generate RB tree functions */
+RB_GENERATE_INLINE(bcmos_timers, bcmos_timer, entry, _bcmos_timer_compare)
+
+#define TMR_POOL_INIT(tmr_pool)                 RB_INIT(&(tmr_pool)->pool)
+#define TMR_POOL_INSERT(tmr_pool, tmr)          RB_INSERT(bcmos_timers, &(tmr_pool)->pool, tmr)
+#define TMR_POOL_REMOVE(tmr_pool, tmr)          RB_REMOVE(bcmos_timers, &(tmr_pool)->pool, tmr)
+#define TMR_POOL_FIRST(tmr_pool)                RB_MIN(bcmos_timers, &(tmr_pool)->pool)
+
+#else
+
+#define TMR_POOL_INIT(tmr_pool)                 TAILQ_INIT(&(tmr_pool)->pool)
+
+#define TMR_POOL_INSERT(tmr_pool, tmr)                          \
+    do {                                                        \
+        bcmos_timer *_last = TAILQ_LAST(&(tmr_pool)->pool, bcmos_timers);    \
+        if (_last)                                              \
+        {                                                       \
+            if (_bcmos_timer_compare(tmr, _last) >= 0)          \
+            {                                                   \
+                TAILQ_INSERT_TAIL(&(tmr_pool)->pool, tmr, entry); \
+            }                                                   \
+            else                                                \
+            {                                                   \
+                bcmos_timer *_t;                                \
+                uint32_t iter = 0;                              \
+                TAILQ_FOREACH(_t, &(tmr_pool)->pool, entry)     \
+                {                                               \
+                    BUG_ON(iter >= (tmr_pool)->num_active_timers);\
+                    ++iter;                                     \
+                    if (_bcmos_timer_compare(tmr, _t) <= 0)     \
+                    {                                           \
+                        TAILQ_INSERT_BEFORE(_t, tmr, entry);    \
+                        break;                                  \
+                    }                                           \
+                }                                               \
+            }                                                   \
+        }                                                       \
+        else                                                    \
+        {                                                       \
+            TAILQ_INSERT_HEAD(&(tmr_pool)->pool, tmr, entry);   \
+        }                                                       \
+        ++(tmr_pool)->num_active_timers;                        \
+    } while (0)
+
+#define TMR_POOL_REMOVE(tmr_pool, tmr)                          \
+    do {                                                        \
+        BUG_ON(!(tmr_pool)->num_active_timers);                 \
+        TAILQ_REMOVE(&(tmr_pool)->pool, tmr, entry);            \
+        TAILQ_NEXT(tmr, entry) = NULL;                          \
+        --(tmr_pool)->num_active_timers;                        \
+    } while (0)
+
+#define TMR_POOL_FIRST(tmr_pool)                TAILQ_FIRST(&(tmr_pool)->pool)
+
+#endif
+
+#define BCMOS_TIMER_IS_RUNNING(tmr)             ((tmr->flags & BCMOS_TIMER_FLAG_RUNNING) != 0)
+#define BCMOS_TIMER_IS_EXPIRED(tmr)             ((tmr->flags & BCMOS_TIMER_FLAG_EXPIRED) != 0)
+#define BCMOS_TIMER_IS_VALID(tmr)               ((tmr->flags & BCMOS_TIMER_FLAG_VALID) != 0)
+#define BCMOS_TIMER_IS_ACTIVE(tmr)              ((tmr->flags & BCMOS_TIMER_FLAG_ACTIVE) != 0)
+
+static bcmos_bool bcmos_initialized;
+static bcmos_timer_pool tmr_pool;
+static void _sys_timer_handler(void *data);
+
+/*
+ * Print variables
+ */
+
+static bcmos_print_redirect_mode print_redirect_mode;
+static bcmos_print_redirect_cb print_redirect_cb;
+static void *print_redirect_cb_data;
+static bcmos_mutex bcmos_print_lock;
+#ifdef BCMOS_BUF_POOL_SIZE
+static bcmos_blk_pool sys_buf_pool;
+static bcmos_errno bcmos_buf_pool_create(void);
+#endif
+
+/** Initialize system library
+ * \ingroup system
+ * Must be called before any other system function
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_init(void)
+{
+    bcmos_errno rc;
+
+    if (bcmos_initialized)
+        return BCM_ERR_OK;
+    rc = bcmos_sys_init();
+    bcmos_mutex_create(&bcmos_res_lock, 0, "res_lock");
+    bcmos_mutex_create(&bcmos_print_lock, 0, "print_lock");
+    TMR_POOL_INIT(&tmr_pool);
+    bcmos_fastlock_init(&tmr_pool.lock, 0);
+    bcmos_fastlock_init(&bcmos_msg_register_lock, 0);
+    rc = rc ? rc : bcmos_sys_timer_create(&tmr_pool.sys_timer, _sys_timer_handler, &tmr_pool);
+
+    /* Create default buffer pool if so requested by compilation options */
+#ifdef BCMOS_BUF_POOL_SIZE
+    rc = rc ? rc : bcmos_buf_pool_create();
+#endif
+
+    if (!rc)
+    {
+        bcmos_initialized = BCMOS_TRUE;
+    }
+
+    return rc;
+}
+
+/** Cleanup system library
+ * \ingroup system
+ */
+void bcmos_exit(void)
+{
+    if (!bcmos_initialized)
+        return;
+    bcmos_sys_timer_destroy(&tmr_pool.sys_timer);
+    bcmos_mutex_destroy(&bcmos_print_lock);
+    bcmos_mutex_destroy(&bcmos_res_lock);
+#ifdef BCMOS_BUF_POOL_SIZE
+    bcmos_blk_pool_reset(&sys_buf_pool);
+    bcmos_blk_pool_destroy(&sys_buf_pool);
+#endif
+    bcmos_sys_exit();
+    bcmos_initialized = BCMOS_FALSE;
+}
+
+/*
+ * Common task services
+ */
+
+/* Query task info */
+bcmos_errno bcmos_task_query(const bcmos_task *task, bcmos_task_parm *parm)
+{
+    if (task == NULL || task->magic != BCMOS_TASK_MAGIC || parm == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    *parm = task->parm;
+    return BCM_ERR_OK;
+}
+
+/** Task iterator
+ * \param[in] prev      Previous task. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_task_get_next(bcmos_task **prev)
+{
+    bcmos_task *task;
+    if (prev == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    task = *prev;
+    if (task && task->magic != BCMOS_TASK_MAGIC)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (task)
+    {
+        task = STAILQ_NEXT(task, list);
+    }
+    else
+    {
+        task = STAILQ_FIRST(&task_list);
+    }
+    *prev = task;
+    if (!task)
+    {
+        return BCM_ERR_NO_MORE;
+    }
+    return BCM_ERR_OK;
+}
+
+/*
+ * Message queue
+ */
+
+static void _bcmos_msgq_notify(bcmos_msg_queue *q, const char *txt)
+{
+    BCMOS_TRACE_INFO("Msg queue %s: %s\n", q->q.parm.name, txt);
+}
+
+/* Decrement in-queue statistics */
+static inline void _bcmos_msgq_stat_dec(bcmos_msg_queue_nw *q)
+{
+    bcmos_msg_queue_stat *stat = &q->stat;
+    uint32_t old_in = stat->msg_in;
+
+    if (stat->msg_in == 0)
+    {
+        BCMOS_TRACE_ERR("Attempt to decrement statistics for an empty queue ('%s')\n", q->parm.name);
+    }
+    else
+    {
+        --stat->msg_in;
+        ++stat->msg_received;
+    }
+
+    if (old_in == q->parm.low_wm)
+    {
+        q->parm.notify((bcmos_msg_queue *)q, "becomes uncongested");
+        stat->is_congested = BCMOS_FALSE;
+    }
+}
+
+/* Increment in-queue statistics */
+static inline void _bcmos_msgq_stat_inc(bcmos_msg_queue_nw *q)
+{
+    bcmos_msg_queue_stat *stat = &q->stat;
+    uint32_t old_in = stat->msg_in;
+
+    ++stat->msg_in;
+    ++stat->msg_sent;
+    if (old_in == q->parm.high_wm)
+    {
+        q->parm.notify((bcmos_msg_queue *)q, "becomes congested");
+        stat->is_congested = BCMOS_TRUE;
+    }
+    if (stat->is_congested)
+        ++stat->msg_almost_full;
+}
+
+static void _bcmos_qgroup_notify(bcmos_msg_qgroup *qgroup, const char *txt)
+{
+    BCMOS_TRACE_INFO("Msg queue %s: %s\n", qgroup->parm.name, txt);
+}
+
+/* Decrement in-queue statistics for queue group */
+static inline void _bcmos_qgroup_stat_dec(bcmos_msg_qgroup *qgroup)
+{
+    bcmos_msg_queue_stat *stat = &qgroup->stat;
+    uint32_t old_in = stat->msg_in;
+
+    if (stat->msg_in == 0)
+    {
+        BCMOS_TRACE_ERR("Attempt to decrement statistics for an empty queue ('%s')\n", qgroup->parm.name);
+    }
+    else
+    {
+        --stat->msg_in;
+        ++stat->msg_received;
+    }
+
+    if (old_in == qgroup->parm.low_wm)
+    {
+        qgroup->parm.notify(qgroup, "becomes uncongested");
+        stat->is_congested = BCMOS_FALSE;
+    }
+}
+
+/* Increment in-queue statistics */
+static inline void _bcmos_qgroup_stat_inc(bcmos_msg_qgroup *qgroup)
+{
+    bcmos_msg_queue_stat *stat = &qgroup->stat;
+    uint32_t old_in = stat->msg_in;
+
+    ++stat->msg_in;
+    ++stat->msg_sent;
+    if (old_in == qgroup->parm.high_wm)
+    {
+        qgroup->parm.notify(qgroup, "becomes congested");
+        stat->is_congested = BCMOS_TRUE;
+    }
+    if (stat->is_congested)
+        ++stat->msg_almost_full;
+}
+
+
+/* Get message from queue.
+ * Urgent queue is checked 1st, then regular queue
+ * Must be called under lock!
+ * Returns msg or NULL if queue is empty
+ */
+static inline bcmos_msg *_bcmos_msg_get(bcmos_msg_queue_nw *q)
+{
+    bcmos_msg *msg;
+
+    msg = STAILQ_FIRST(&q->msgl_urg);
+    if (msg)
+    {
+        STAILQ_REMOVE_HEAD(&q->msgl_urg, next);
+        _bcmos_msgq_stat_dec(q);
+        return msg;
+    }
+
+    msg = STAILQ_FIRST(&q->msgl);
+    if (msg)
+    {
+        STAILQ_REMOVE_HEAD(&q->msgl, next);
+        _bcmos_msgq_stat_dec(q);
+    }
+
+    return msg;
+}
+
+/* Put message on queue.
+ * Must be called under lock!
+ * Returns error in case of queue overflow
+ */
+static inline bcmos_errno _bcmos_msg_put(bcmos_msg_queue_nw *q, bcmos_msg *msg, bcmos_msg_send_flags flags)
+{
+    /* Overflow check */
+    if (q->stat.msg_in >= q->parm.size)
+    {
+        if (!(flags & BCMOS_MSG_SEND_NOLIMIT))
+        {
+            ++q->stat.msg_discarded;
+            return BCM_ERR_OVERFLOW;
+        }
+    }
+    /* Put onto the relevant queue */
+    if ((flags & BCMOS_MSG_SEND_URGENT))
+        STAILQ_INSERT_TAIL(&q->msgl_urg, msg, next);
+    else
+        STAILQ_INSERT_TAIL(&q->msgl, msg, next);
+    _bcmos_msgq_stat_inc(q);
+
+    return BCM_ERR_OK;
+}
+
+/* Create message queue without wait support */
+static void bcmos_msg_queue_nw_init(bcmos_msg_queue_nw *q, const bcmos_msg_queue_parm *parm)
+{
+    q->parm = *parm;
+    STAILQ_INIT(&q->msgl);
+    STAILQ_INIT(&q->msgl_urg);
+    bcmos_fastlock_init(&q->lock, parm->flags);
+    memset(&q->stat, 0, sizeof(q->stat));
+    q->flags = 0;
+    if (!q->parm.size)
+        q->parm.size = BCMOS_MSG_QUEUE_SIZE_UNLIMITED;
+    if (!q->parm.high_wm)
+        q->parm.high_wm = BCMOS_MSG_QUEUE_SIZE_UNLIMITED;
+    if (!q->parm.low_wm)
+        q->parm.low_wm = q->parm.high_wm;
+    if (!q->parm.notify)
+        q->parm.notify = _bcmos_msgq_notify;
+}
+
+/* Destroy message list */
+static void bcmos_msg_list_destroy(bcmos_msg_list *l)
+{
+    bcmos_msg *msg, *tmp;
+    STAILQ_FOREACH_SAFE(msg, l, next, tmp)
+    {
+        STAILQ_REMOVE_HEAD(l, next);
+        bcmos_msg_free(msg);
+    }
+}
+
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+
+/* Remote queue support - common part of create/destroy */
+
+static bcmos_errno _bcmos_msg_queue_destroy_remote_ep(bcmos_msg_queue *queue)
+{
+    if (queue->q.parm.close)
+        queue->q.parm.close(queue);
+    bcmos_mutex_destroy(&queue->send_lock);
+    if (queue->send_buf)
+        bcmos_free(queue->send_buf);
+    if (queue->recv_buf)
+        bcmos_free(queue->recv_buf);
+    return BCM_ERR_OK;
+}
+
+static bcmos_errno _bcmos_msg_queue_create_remote_ep(bcmos_msg_queue *queue)
+{
+    bcmos_errno rc;
+
+    /* Allocate tx and rx buffers */
+    if (!queue->q.parm.max_mtu)
+    {
+        queue->q.parm.max_mtu = BCMOS_MSG_QUEUE_DEFAULT_MAX_MTU;
+    }
+    queue->send_buf = bcmos_calloc(queue->q.parm.max_mtu);
+    if (!queue->send_buf)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "Can't allocate send_buf\n");
+    }
+
+    queue->recv_buf = bcmos_calloc(queue->q.parm.max_mtu);
+    if (!queue->recv_buf)
+    {
+        bcmos_free(queue->send_buf);
+        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "Can't allocate recv_buf\n");
+    }
+    bcmos_mutex_create(&queue->send_lock, 0, queue->q.parm.name);
+
+    switch (queue->q.parm.ep_type)
+    {
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+    case BCMOS_MSG_QUEUE_EP_DOMAIN_SOCKET:
+        rc = bcmos_sys_msg_queue_domain_socket_open(queue);
+        break;
+#endif
+#ifdef BCMOS_MSG_QUEUE_UDP_SOCKET
+    case BCMOS_MSG_QUEUE_EP_UDP_SOCKET:
+        rc = bcmos_sys_msg_queue_udp_socket_open(queue);
+        break;
+#endif
+#ifdef BCMOS_MSG_QUEUE_USER_DEFINED
+    case BCMOS_MSG_QUEUE_EP_USER_DEFINED:
+        if (parm.open == NULL || parm.close == NULL || parm.send==NULL || parm.recv == NULL)
+        {
+            rc = BCM_ERR_PARM;
+            break;
+        }
+        rc = parm.open(queue);
+        break;
+#endif
+    default:
+        rc = BCM_ERR_PARM;
+        break;
+    }
+
+    if (rc)
+    {
+        _bcmos_msg_queue_destroy_remote_ep(queue);
+    }
+
+    return rc;
+}
+
+#endif /* #ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT */
+
+/* Create message queue. */
+bcmos_errno bcmos_msg_queue_create(bcmos_msg_queue *queue, const bcmos_msg_queue_parm *parm)
+{
+    bcmos_errno rc;
+
+    if (!queue || !parm)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue %p, parm %p\n", queue, parm);
+    memset(queue, 0, sizeof(*queue));
+    queue->q.parm = *parm;
+
+    if (parm->ep_type == BCMOS_MSG_QUEUE_EP_LOCAL)
+    {
+        rc = bcmos_sem_create(&queue->m, 0, parm->flags, queue->q.parm.name);
+        if (!rc)
+            bcmos_msg_queue_nw_init(&queue->q, parm);
+    }
+    else
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    {
+        rc = _bcmos_msg_queue_create_remote_ep(queue);
+    }
+#else
+    {
+        rc = BCM_ERR_PARM;
+    }
+#endif
+
+    if (rc)
+        return rc;
+
+    queue->magic = BCMOS_MSG_QUEUE_VALID;
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (queue->q.parm.name)
+    {
+        strncpy(queue->name, queue->q.parm.name, sizeof(queue->name) - 1);
+        queue->q.parm.name = queue->name;
+    }
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&msg_queue_list, queue, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    return BCM_ERR_OK;
+}
+
+/* Destroy queue */
+bcmos_errno bcmos_msg_queue_destroy(bcmos_msg_queue *queue)
+{
+    bcmos_errno rc = BCM_ERR_OK;
+
+    if (!queue || queue->magic != BCMOS_MSG_QUEUE_VALID)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue handle is invalid\n");
+    }
+    queue->magic = BCMOS_MSG_QUEUE_DELETED;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&msg_queue_list, queue, bcmos_msg_queue, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    if (queue->q.parm.ep_type == BCMOS_MSG_QUEUE_EP_LOCAL)
+    {
+        bcmos_sem_destroy(&queue->m);
+        /* Release all pending messages */
+        bcmos_msg_list_destroy(&queue->q.msgl_urg);
+        bcmos_msg_list_destroy(&queue->q.msgl);
+    }
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    else
+    {
+        rc = _bcmos_msg_queue_destroy_remote_ep(queue);
+    }
+#endif
+
+    return rc;
+}
+
+/* Get queue info */
+bcmos_errno bcmos_msg_queue_query(const bcmos_msg_queue *queue, bcmos_msg_queue_info *info)
+{
+    if (!queue || !info)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue %p, info %p\n", queue, info);
+    info->stat = queue->q.stat;
+    info->parm = queue->q.parm;
+    return BCM_ERR_OK;
+}
+
+/* Message queue iterator */
+bcmos_errno bcmos_msg_queue_get_next(const bcmos_msg_queue **prev)
+{
+    const bcmos_msg_queue *queue;
+
+    if (prev == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    queue = *prev;
+    if (queue && queue->magic != BCMOS_MSG_QUEUE_VALID)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (queue)
+    {
+        queue = STAILQ_NEXT(queue, list);
+    }
+    else
+    {
+        queue = STAILQ_FIRST(&msg_queue_list);
+    }
+    *prev = queue;
+    if (!queue)
+    {
+        return BCM_ERR_NO_MORE;
+    }
+    return BCM_ERR_OK;
+}
+
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+
+/* Pack / unpack message header.
+ * In the future we might adopt bcmolt_buf service into OS abstraction and use it
+ * for packing / unpacking.
+ */
+
+void bcmos_msg_hdr_pack(const bcmos_msg *msg, uint8_t *buf, uint32_t data_size)
+{
+    uint16_t val16;
+    uint32_t val32;
+    val16 = BCMOS_ENDIAN_CPU_TO_BIG_U16(msg->type);
+    memcpy(buf, &val16, sizeof(val16));
+    buf[2] = (uint8_t)msg->instance;
+    buf[3] = (uint8_t)msg->sender;
+    val32 = BCMOS_ENDIAN_CPU_TO_BIG_U32(data_size);
+    memcpy(&buf[4], &val32, sizeof(val32));
+}
+
+void bcmos_msg_hdr_unpack(const uint8_t *buf, bcmos_msg *msg)
+{
+    uint16_t val16;
+    uint32_t val32;
+    memcpy(&val16, buf, sizeof(val16));
+    val16 = BCMOS_ENDIAN_BIG_TO_CPU_U16(val16);
+    msg->type = (bcmos_msg_id)val16;
+    msg->instance = (bcmos_msg_instance)buf[2];
+    msg->sender = (bcmos_module_id)buf[3];
+    memcpy(&val32, &buf[4], sizeof(val32));
+    msg->size = BCMOS_ENDIAN_BIG_TO_CPU_U32(val32); /* can be overwritten by unpacker */
+    msg->handler = NULL;
+    msg->send_flags = 0;
+}
+
+/* Send message to remote EP wrapper */
+static bcmos_errno _bcmos_msg_send_to_remote_ep(bcmos_msg_queue *queue, bcmos_msg *msg, bcmos_msg_send_flags flags)
+{
+    uint8_t *buf = NULL;
+    uint32_t buf_length = 0;
+    bcmos_errno rc;
+
+    bcmos_mutex_lock(&queue->send_lock);
+    rc = queue->q.parm.pack(queue, msg, &buf, &buf_length);
+    rc = rc ? rc : queue->q.parm.send(queue, buf, buf_length);
+    bcmos_mutex_unlock(&queue->send_lock);
+
+    /* Release if sent successfully or if auto-release flag is set */
+    if (rc == BCM_ERR_OK || !(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+    {
+        bcmos_msg_free(msg);
+    }
+    if (buf && queue->q.parm.free_packed)
+    {
+        queue->q.parm.free_packed(queue, buf);
+    }
+    if (rc)
+    {
+        ++queue->q.stat.msg_discarded;
+    }
+    else
+    {
+        ++queue->q.stat.msg_sent;
+    }
+
+    return rc;
+}
+
+/* Receive message from remote EP wrapper */
+static bcmos_errno _bcmos_msg_recv_from_remote_ep(bcmos_msg_queue *queue, uint32_t timeout, bcmos_msg **msg)
+{
+    uint8_t *buf = NULL;
+    uint32_t buf_length = 0;
+    bcmos_errno rc;
+
+    rc = queue->q.parm.recv(queue, timeout, &buf, &buf_length);
+    rc = rc ? rc : queue->q.parm.unpack(queue, buf, buf_length, msg);
+    if (buf && queue->q.parm.free_packed)
+    {
+        queue->q.parm.free_packed(queue, buf);
+    }
+    if (!rc)
+    {
+        ++queue->q.stat.msg_received;
+    }
+
+    return rc;
+}
+
+#endif /* BCMOS_MSG_QUEUE_REMOTE_SUPPORT */
+
+/* Send message to queue */
+bcmos_errno bcmos_msg_send(bcmos_msg_queue *queue, bcmos_msg *msg, bcmos_msg_send_flags flags)
+{
+    long lock_flags;
+    bcmos_errno rc;
+
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    if (queue->q.parm.ep_type != BCMOS_MSG_QUEUE_EP_LOCAL)
+    {
+        return _bcmos_msg_send_to_remote_ep(queue, msg, flags);
+    }
+#endif
+
+    lock_flags = bcmos_fastlock_lock(&queue->q.lock);
+    rc = _bcmos_msg_put(&queue->q, msg, flags);
+    if (rc)
+    {
+        bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+        if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+        {
+            bcmos_msg_free(msg);
+        }
+        BCMOS_TRACE_ERR("Overflow: Queue %s\n", queue->q.parm.name);
+        return rc;
+    }
+
+    /* Success */
+    if (queue->is_waiting)
+    {
+        /* Kick waiting task */
+        queue->is_waiting = BCMOS_FALSE;
+        bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+        bcmos_sem_post(&queue->m);
+    }
+    else
+    {
+        bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+    }
+
+    return BCM_ERR_OK;
+}
+
+/* Send message to module (internal) - doesn't post any semaphores so it's safe to call under a fastlock */
+static bcmos_errno _bcmos_msg_send_to_module(
+    bcmos_module_id module_id,
+    bcmos_msg *msg,
+    bcmos_msg_send_flags flags,
+    bcmos_sem **sem_to_post)
+{
+    bcmos_module *module = _bcmos_module_get(module_id);
+    bcmos_task *task;
+    long lock_flags, q_lock_flags;
+    uint32_t active_modules;
+    bcmos_errno rc;
+    *sem_to_post = NULL;
+
+    if (!module || !msg->handler)
+    {
+        if (!module)
+        {
+            BCMOS_TRACE_ERR("Module %d doesn't exist\n", module_id);
+            rc = BCM_ERR_NOENT;
+        }
+        else
+        {
+            BCMOS_TRACE_ERR("msg->handler is not set. msg->type=%d\n", msg->type);
+            rc = BCM_ERR_PARM;
+        }
+        if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+        {
+            bcmos_msg_free(msg);
+        }
+        return rc;
+    }
+
+    task = module->my_task;
+    lock_flags = bcmos_fastlock_lock(&task->active_lock);
+    q_lock_flags = bcmos_fastlock_lock(&module->msgq.lock);
+
+    rc = _bcmos_msg_put(&module->msgq, msg, flags);
+    if (rc)
+    {
+        bcmos_fastlock_unlock(&module->msgq.lock, q_lock_flags);
+        bcmos_fastlock_unlock(&task->active_lock, lock_flags);
+
+        /* Queue overflow */
+        if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+            bcmos_msg_free(msg);
+
+        BCMOS_TRACE_ERR("Overflow: Queue %s\n", module->parm.qparm.name);
+
+        return rc;
+    }
+    bcmos_fastlock_unlock(&module->msgq.lock, q_lock_flags);
+
+    /* Success. Update active_modules task and kick the task */
+    active_modules = task->active_modules;
+    task->active_modules |= (1 << module->idx);
+    bcmos_fastlock_unlock(&task->active_lock, lock_flags);
+
+    /* Notify caller to kick task if there is a chance it was waiting */
+    if (!active_modules)
+        *sem_to_post = &task->active_sem;
+
+    return BCM_ERR_OK;
+}
+
+/* Send message to module */
+bcmos_errno bcmos_msg_send_to_module(bcmos_module_id module_id, bcmos_msg *msg, bcmos_msg_send_flags flags)
+{
+    bcmos_sem *sem_to_post;
+    bcmos_errno err = _bcmos_msg_send_to_module(module_id, msg, flags, &sem_to_post);
+    if (sem_to_post)
+        bcmos_sem_post(sem_to_post);
+    return err;
+}
+
+/* Get message from the head of message queue */
+bcmos_errno bcmos_msg_recv(bcmos_msg_queue *queue, uint32_t timeout, bcmos_msg **msg)
+{
+    long lock_flags;
+
+    if (!queue || !msg)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue %p, msg %p\n", queue, msg);
+
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    if (queue->q.parm.ep_type != BCMOS_MSG_QUEUE_EP_LOCAL)
+    {
+        return _bcmos_msg_recv_from_remote_ep(queue, timeout, msg);
+    }
+#endif
+
+    lock_flags = bcmos_fastlock_lock(&queue->q.lock);
+    *msg = _bcmos_msg_get(&queue->q);
+    if (*msg)
+    {
+        bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+        return BCM_ERR_OK;
+    }
+    if (!timeout)
+    {
+        bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+        return BCM_ERR_NOENT;
+    }
+
+    /* Receive with wait */
+    queue->is_waiting = BCMOS_TRUE;
+    bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+
+    /* wait for it */
+    bcmos_sem_wait(&queue->m, timeout);
+    lock_flags = bcmos_fastlock_lock(&queue->q.lock);
+    *msg = _bcmos_msg_get(&queue->q);
+    queue->is_waiting = BCMOS_FALSE;
+    bcmos_fastlock_unlock(&queue->q.lock, lock_flags);
+    if (!*msg)
+        return BCM_ERR_TIMEOUT;
+
+    return BCM_ERR_OK;
+}
+
+
+/*
+ * Queue group support
+ */
+
+/* Create message queue group. */
+bcmos_errno bcmos_msg_qgroup_create(bcmos_msg_qgroup *qgroup, const bcmos_msg_qgroup_parm *parm)
+{
+    bcmos_errno rc;
+    bcmos_qgroup_prty prty;
+
+    if (!qgroup || !parm || !parm->nqueues || parm->nqueues>32)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue %p, parm %p nqueues %u\n", qgroup, parm, parm ? parm->nqueues: 0);
+    memset(qgroup, 0, sizeof(*qgroup));
+    rc = bcmos_sem_create(&qgroup->m, 0, parm->flags, NULL);
+    if (rc)
+        return rc;
+    qgroup->parm = *parm;
+    bcmos_fastlock_init(&qgroup->lock, parm->flags);
+    if (!qgroup->parm.size)
+        qgroup->parm.size = BCMOS_MSG_QUEUE_SIZE_UNLIMITED;
+    if (!qgroup->parm.high_wm)
+        qgroup->parm.high_wm = BCMOS_MSG_QUEUE_SIZE_UNLIMITED;
+    if (!qgroup->parm.low_wm)
+        qgroup->parm.low_wm = qgroup->parm.high_wm;
+    if (!qgroup->parm.notify)
+        qgroup->parm.notify = _bcmos_qgroup_notify;
+    qgroup->msgl = bcmos_calloc(sizeof(bcmos_msg_list) * (uint32_t)parm->nqueues);
+    if (!qgroup->msgl)
+    {
+        bcmos_msg_qgroup_destroy(qgroup);
+        return BCM_ERR_NOMEM;
+    }
+    for (prty = 0; prty < qgroup->parm.nqueues; prty++)
+    {
+        STAILQ_INIT(&qgroup->msgl[prty]);
+    }
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (qgroup->parm.name)
+    {
+        strncpy(qgroup->name, qgroup->parm.name, sizeof(qgroup->parm.name) - 1);
+        qgroup->parm.name = qgroup->name;
+    }
+    qgroup->magic = BCMOS_MSG_QGROUP_VALID;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&msg_qgroup_list, qgroup, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    return BCM_ERR_OK;
+}
+
+/** Destroy queue group
+ *
+ * \param[in]   qgroup       Queue group handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_qgroup_destroy(bcmos_msg_qgroup *qgroup)
+{
+    bcmos_qgroup_prty prty;
+
+    if (!qgroup || qgroup->magic != BCMOS_MSG_QGROUP_VALID)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "queue group handle is invalid\n");
+    }
+
+    qgroup->magic = BCMOS_MSG_QGROUP_DELETED;
+
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&msg_qgroup_list, qgroup, bcmos_msg_qgroup, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    bcmos_sem_destroy(&qgroup->m);
+
+    /* Release all pending messages */
+    if (qgroup->msgl)
+    {
+        for (prty = 0; prty < qgroup->parm.nqueues; prty++)
+        {
+            bcmos_msg_list_destroy(&qgroup->msgl[prty]);
+        }
+        bcmos_free(qgroup->msgl);
+    }
+    return BCM_ERR_OK;
+
+}
+
+/** Get queue group info */
+bcmos_errno bcmos_msg_qgroup_query(const bcmos_msg_qgroup *qgroup, bcmos_msg_qgroup_info *info)
+{
+    if (!qgroup || !info)
+        return BCM_ERR_PARM;
+
+    info->parm = qgroup->parm;
+    info->stat = qgroup->stat;
+
+    return BCM_ERR_OK;
+}
+
+/** Message queue group iterator
+ * \param[in] prev      Previous queue group. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_msg_qgroup_get_next(const bcmos_msg_qgroup **prev)
+{
+    const bcmos_msg_qgroup *qgrp;
+
+    if (prev == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    qgrp = *prev;
+    if (qgrp && qgrp->magic != BCMOS_MSG_QGROUP_VALID)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (qgrp)
+    {
+        qgrp = STAILQ_NEXT(qgrp, list);
+    }
+    else
+    {
+        qgrp = STAILQ_FIRST(&msg_qgroup_list);
+    }
+    *prev = qgrp;
+    if (!qgrp)
+    {
+        return BCM_ERR_NO_MORE;
+    }
+    return BCM_ERR_OK;
+}
+
+/* get message from non-empty queue group queue */
+static inline bcmos_msg *_bcmos_qgroup_msg_get(bcmos_msg_qgroup *qgroup, bcmos_qgroup_prty prty)
+{
+    bcmos_msg *msg;
+    msg = STAILQ_FIRST(&qgroup->msgl[prty]);
+    BUG_ON(!msg);
+    STAILQ_REMOVE_HEAD(&qgroup->msgl[prty], next);
+    if (STAILQ_EMPTY(&qgroup->msgl[prty]))
+    {
+        qgroup->active_mask &= ~(1 << prty);
+    }
+    return msg;
+}
+
+/* Send message to queue group */
+bcmos_errno bcmos_msg_send_to_qgroup(bcmos_msg_qgroup *qgroup, bcmos_msg *msg, bcmos_qgroup_prty prty,
+    bcmos_msg_send_flags flags)
+{
+    long lock_flags;
+    bcmos_errno rc = BCM_ERR_OK;
+
+    if (prty >= qgroup->parm.nqueues)
+    {
+        if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+        {
+            bcmos_msg_free(msg);
+        }
+        return BCM_ERR_PARM;
+    }
+    msg->send_flags = flags;
+
+    lock_flags = bcmos_fastlock_lock(&qgroup->lock);
+
+    /* Put into the relevant queue */
+    STAILQ_INSERT_TAIL(&qgroup->msgl[prty], msg, next);
+    qgroup->active_mask |= (1 << prty);
+    _bcmos_qgroup_stat_inc(qgroup);
+
+    /* Overflow check */
+    if ((qgroup->stat.msg_in > qgroup->parm.size))
+    {
+        bcmos_msg *m;
+        bcmos_qgroup_prty i;
+        /* Find the lowest-priority queue with data and discard the head message.
+         * The loop always finds something because we've just added a message
+         */
+        for (i = qgroup->parm.nqueues - 1; (qgroup->active_mask & (1 << i)) == 0; i--)
+            ;
+        m = _bcmos_qgroup_msg_get(qgroup, i);
+        --qgroup->stat.msg_in;
+        ++qgroup->stat.msg_discarded;
+        if (!(m->send_flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+        {
+            bcmos_msg_free(m);
+        }
+        rc = BCM_ERR_OVERFLOW;
+    }
+
+    /* Kick waiting task */
+    if (qgroup->is_waiting)
+    {
+        qgroup->is_waiting = BCMOS_FALSE;
+        bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+        bcmos_sem_post(&qgroup->m);
+    }
+    else
+    {
+        bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+    }
+
+    return rc;
+
+}
+
+/* Get highest priority message from queue group */
+bcmos_errno bcmos_msg_recv_from_qgroup(bcmos_msg_qgroup *qgroup, uint32_t timeout, bcmos_msg **msg)
+{
+    long lock_flags;
+    bcmos_qgroup_prty prty;
+
+    if (!qgroup || !msg)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "qgroup %p, msg %p\n", qgroup, msg);
+
+    lock_flags = bcmos_fastlock_lock(&qgroup->lock);
+    if (!qgroup->active_mask)
+    {
+        if (!timeout)
+        {
+            bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+            return BCM_ERR_NOENT;
+        }
+
+        /* Receive with wait */
+        qgroup->is_waiting = BCMOS_TRUE;
+        bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+
+        /* wait for it */
+        bcmos_sem_wait(&qgroup->m, timeout);
+
+        /* Done waiting. Either got a message or a timeout */
+        lock_flags = bcmos_fastlock_lock(&qgroup->lock);
+        qgroup->is_waiting = BCMOS_FALSE;
+        if (!qgroup->active_mask)
+        {
+            bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+            return BCM_ERR_TIMEOUT;
+        }
+    }
+
+    prty = (bcmos_qgroup_prty)(ffs(qgroup->active_mask) - 1);
+    BUG_ON(prty >= qgroup->parm.nqueues);
+    *msg = _bcmos_qgroup_msg_get(qgroup, prty);
+    _bcmos_qgroup_stat_dec(qgroup);
+    bcmos_fastlock_unlock(&qgroup->lock, lock_flags);
+
+    return BCM_ERR_OK;
+}
+
+
+/*
+ * Message registration and dispatch
+ */
+
+/* Hash entry */
+typedef struct msg_hash_entry msg_hash_entry;
+
+struct msg_hash_entry
+{
+    /* Key */
+    uint32_t key;       /* msg_type + instance */
+
+    /* Value */
+    bcmos_module_id module_id;
+    F_bcmos_msg_handler handler;
+
+    /* List of entries with the same key */
+    SLIST_ENTRY(msg_hash_entry) list;
+};
+
+/* Hash table */
+static SLIST_HEAD(msg_hash, msg_hash_entry) msg_hash_table[BCMOS_MSG_HASH_SIZE];
+
+/* Make hash key from msg_type and instance */
+static inline uint32_t _bcmos_msg_hash_key(bcmos_msg_id msg_type, bcmos_msg_instance instance)
+{
+    return ((uint32_t)instance << 16) | (uint32_t)msg_type;
+}
+
+/* Hash function */
+static inline uint32_t _bcmos_msg_hash_func(uint32_t key)
+{
+    key ^= (key >> 9);
+    key ^= (key << 3);
+    key ^= (key >> 15);
+    return key % BCMOS_MSG_HASH_SIZE;
+}
+
+/* Find entry in hash */
+static inline msg_hash_entry *_bcmos_msg_hash_find(bcmos_msg_id msg_type, bcmos_msg_instance instance)
+{
+    uint32_t key = _bcmos_msg_hash_key(msg_type, instance);
+    uint32_t hash = _bcmos_msg_hash_func(key);
+    msg_hash_entry *entry;
+    SLIST_FOREACH(entry, &msg_hash_table[hash], list)
+    {
+        if (entry->key == key)
+            break;
+    }
+    return entry;
+}
+
+/* Register message_type+instance --> module+handler */
+bcmos_errno bcmos_msg_register(bcmos_msg_id msg_type, bcmos_msg_instance instance,
+    bcmos_module_id module_id, F_bcmos_msg_handler handler)
+{
+    uint32_t key = _bcmos_msg_hash_key(msg_type, instance);
+    uint32_t hash = _bcmos_msg_hash_func(key);
+    msg_hash_entry *entry;
+    long lock_flags;
+
+    if (!handler)
+        return BCM_ERR_PARM;
+
+    entry = bcmos_calloc(sizeof(*entry));
+    if (!entry)
+        return BCM_ERR_NOMEM;
+
+    entry->key = key;
+    entry->module_id = module_id;
+    entry->handler = handler;
+    lock_flags = bcmos_fastlock_lock(&bcmos_msg_register_lock);
+    if (_bcmos_msg_hash_find(msg_type, instance) != NULL)
+    {
+        bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+        bcmos_free(entry);
+        return BCM_ERR_ALREADY;
+    }
+    SLIST_INSERT_HEAD(&msg_hash_table[hash], entry, list);
+    bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmos_msg_unregister(bcmos_msg_id msg_type, bcmos_msg_instance instance, bcmos_module_id module_id)
+{
+    uint32_t key = _bcmos_msg_hash_key(msg_type, instance);
+    uint32_t hash = _bcmos_msg_hash_func(key);
+    msg_hash_entry *entry;
+    long lock_flags;
+
+    lock_flags = bcmos_fastlock_lock(&bcmos_msg_register_lock);
+    entry = _bcmos_msg_hash_find(msg_type, instance);
+    if (!entry)
+    {
+        bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+        return BCM_ERR_NOENT;
+    }
+
+    if (entry->module_id != module_id)
+    {
+        bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+        return BCM_ERR_INVALID_OP;
+    }
+
+    SLIST_REMOVE(&msg_hash_table[hash], entry, msg_hash_entry, list);
+    bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+    bcmos_free(entry);
+
+    return BCM_ERR_OK;
+}
+
+void bcmos_msg_shutdown_mode_set(bcmos_bool shutdown_mode)
+{
+    bcmos_msg_shutdown_mode = shutdown_mode;
+}
+
+bcmos_bool bcmos_msg_shutdown_mode_get(void)
+{
+    return bcmos_msg_shutdown_mode;
+}
+
+/* Dispatch message to registered module */
+bcmos_errno bcmos_msg_dispatch(bcmos_msg *msg, bcmos_msg_send_flags flags)
+{
+    bcmos_errno err;
+
+    if (unlikely(bcmos_msg_shutdown_mode))
+    {
+        /* In shutdown mode, we need to acquire the same lock used to protect bcmos_msg_register() /
+         * bcmos_msg_unregister(), since we must support calling these functions concurrently. */
+        msg_hash_entry *entry;
+        bcmos_sem *sem_to_post = NULL;
+        long lock_flags = bcmos_fastlock_lock(&bcmos_msg_register_lock);
+        entry = _bcmos_msg_hash_find(msg->type, msg->instance);
+
+        if (entry)
+        {
+            msg->handler = entry->handler;
+            err = _bcmos_msg_send_to_module(entry->module_id, msg, flags, &sem_to_post);
+        }
+        else
+        {
+            /* Not found. Release automatically if requested. */
+            if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+                bcmos_msg_free(msg);
+            err = BCM_ERR_OK;
+        }
+
+        bcmos_fastlock_unlock(&bcmos_msg_register_lock, lock_flags);
+        if (sem_to_post)
+            bcmos_sem_post(sem_to_post);
+    }
+    else
+    {
+        msg_hash_entry *entry = _bcmos_msg_hash_find(msg->type, msg->instance);
+
+        if (entry)
+        {
+            msg->handler = entry->handler;
+            err = bcmos_msg_send_to_module(entry->module_id, msg, flags);
+        }
+        else
+        {
+            /* Not found. Release automatically if requested. */
+            BCMOS_TRACE_ERR("Can't dispatch unregistered msg %d:%d\n", msg->type, msg->instance);
+            if (!(flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR))
+                bcmos_msg_free(msg);
+            err = BCM_ERR_NOENT;
+        }
+    }
+
+    return err;
+}
+
+/*
+ * Task management
+ */
+
+/*
+ * Default task handler
+ */
+/*lint -e{632,633,634}
+ * There are a few warnings about
+ * implicit bcmos_errno conversion to int. It is to bothersome now
+ * to change task handler prototype everywhere and the warning is harmless
+ */
+int bcmos_dft_task_handler(long data)
+{
+    bcmos_task *task = (bcmos_task *)data;
+    long flags = 0, q_flags = 0;
+    uint32_t active_modules;
+    int last_module = 0; /* 1-based last handled module index */
+    bcmos_module *module;
+    bcmos_msg *msg;
+    int rc;
+
+
+    /* Set / validate task timeout */
+    rc = bcmos_task_timeout_set(task, task->parm.msg_wait_timeout, task->parm.timeout_handler);
+    if (rc)
+    {
+        return rc;
+    }
+
+    /* Call init callback if any */
+    if (task->parm.init_handler)
+    {
+        rc = task->parm.init_handler(task->parm.data);
+        if (rc)
+        {
+            BCMOS_TRACE_ERR("Task %s: init_handler returned error %s (%d)\n",
+                task->parm.name, bcmos_strerror((bcmos_errno)rc), rc);
+            bcmos_task_destroy(task);
+            return rc;
+        }
+    }
+
+    /* Wait for module activity */
+    while (!task->destroy_request)
+    {
+        task->current_module = BCMOS_MODULE_ID_NONE;
+
+        /* Wait for module activity */
+        rc = bcmos_sem_wait(&task->active_sem, task->parm.msg_wait_timeout);
+        if (rc == BCM_ERR_TIMEOUT)
+        {
+            F_bcmos_task_handler timeout_handler = task->parm.timeout_handler;
+
+            /* Handle possible race condition */
+            if (!timeout_handler)
+                continue;
+            rc = timeout_handler(data);
+            if (rc != BCM_ERR_OK)
+            {
+                BCMOS_TRACE_ERR("Task %s: terminated by timeout_handler. error %s (%d)\n",
+                    task->parm.name, bcmos_strerror(rc), rc);
+                break;
+            }
+            /* Keep waiting */
+            continue;
+        }
+
+        /* RR active modules */
+        do
+        {
+            flags = bcmos_fastlock_lock(&task->active_lock);
+            active_modules = (task->active_modules >> last_module);
+            if (!active_modules)
+            {
+                last_module = 0;
+                active_modules = task->active_modules;
+                if (!active_modules)
+                {
+                    /* No modules with work to do */
+                    bcmos_fastlock_unlock(&task->active_lock, flags);
+                    continue;
+                }
+            }
+            last_module += ffs(active_modules);
+            BUG_ON(last_module > BCMOS_MAX_MODULES_PER_TASK);
+            module = task->modules[last_module - 1];
+            BUG_ON(!module);
+
+            q_flags = bcmos_fastlock_lock(&module->msgq.lock);
+            /* Get message from the module's message queue */
+            msg = _bcmos_msg_get(&module->msgq);
+            if (!msg)
+            {
+                bcmos_fastlock_unlock(&module->msgq.lock, q_flags);
+                task->active_modules &= ~(1 << (last_module - 1));
+                bcmos_fastlock_unlock(&task->active_lock, flags);
+                continue;
+            }
+
+            bcmos_fastlock_unlock(&module->msgq.lock, q_flags);
+            bcmos_fastlock_unlock(&task->active_lock, flags);
+
+            /* Handle the message */
+            if (msg->handler)
+            {
+                task->current_module = module->id;
+                msg->handler(module->id, msg);
+            }
+            else
+            {
+                BCMOS_TRACE_ERR("msg->handler is not set. msg->type=%d\n", msg->type);
+                bcmos_msg_free(msg);
+            }
+
+        } while (task->active_modules);
+    }
+
+    return 0;
+}
+
+/* Set task message timeout.
+ * The function is only supported in integration mode
+ */
+bcmos_errno bcmos_task_timeout_set(bcmos_task *task, uint32_t timeout, F_bcmos_task_handler timeout_handler)
+{
+    if (task->parm.handler)
+    {
+        BCMOS_TRACE_ERR("%s: The function is only supported in integration mode (task handler == NULL)\n", task->parm.name);
+        return BCM_ERR_NOT_SUPPORTED;
+    }
+    if ((timeout && timeout != BCMOS_WAIT_FOREVER) && !timeout_handler)
+    {
+        BCMOS_TRACE_ERR("%s: timeout_handler is not set\n", task->parm.name);
+        return BCM_ERR_PARM;
+    }
+
+    /* 0 means FOREVER here */
+    if (!timeout)
+        timeout = BCMOS_WAIT_FOREVER;
+
+    task->parm.timeout_handler = timeout_handler;
+    task->parm.msg_wait_timeout = timeout;
+
+    return BCM_ERR_OK;
+}
+
+/*
+ * Module
+ */
+
+/* Register module */
+bcmos_errno bcmos_module_create(bcmos_module_id module_id, bcmos_task *task, bcmos_module_parm *parm)
+{
+    bcmos_module *module;
+    bcmos_errno rc = BCM_ERR_OK;
+    int i;
+
+    if ((unsigned)module_id >= (unsigned)BCMOS_MODULE_ID__NUM_OF || !parm)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "module %d, parm %p\n", module_id, parm);
+    if (!task)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOT_SUPPORTED, "No task\n");
+    if (bcmos_modules[module_id])
+        BCMOS_TRACE_RETURN(BCM_ERR_ALREADY, "module_id %d\n", module_id);
+
+    module = bcmos_calloc(sizeof(bcmos_module));
+    if (!module)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "module_id %d\n", module_id);
+    module->id = module_id;
+    module->my_task = task;
+    module->parm = *parm;
+    module->context = (void *)parm->data;
+    bcmos_msg_queue_nw_init(&module->msgq, &parm->qparm);
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (module->parm.qparm.name)
+    {
+        strncpy(module->name, module->parm.qparm.name, sizeof(module->name) - 1);
+        module->parm.qparm.name = module->name;
+    }
+
+    /* Assign module id */
+    for (i = 0; i < BCMOS_MAX_MODULES_PER_TASK; i++)
+    {
+        if (!task->modules[i])
+        {
+            task->modules[i] = module;
+            module->idx = i;
+            break;
+        }
+    }
+    if (i ==  BCMOS_MAX_MODULES_PER_TASK)
+    {
+        bcmos_free(module);
+        BCMOS_TRACE_RETURN(BCM_ERR_TOO_MANY, "module_id %d\n", module_id);
+    }
+
+    bcmos_modules[module_id] = module;
+
+    /* Init module */
+    if (parm->init)
+    {
+        rc = parm->init(parm->data);
+        if (rc)
+            bcmos_module_destroy(module_id);
+    }
+
+    return rc;
+}
+
+/* Un-register module */
+bcmos_errno bcmos_module_destroy(bcmos_module_id module_id)
+{
+    bcmos_module *module = _bcmos_module_get(module_id);
+    bcmos_task *task;
+    long lock_flags, q_lock_flags;
+    bcmos_msg_list msgl_urg, msgl;
+
+    if (!module)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "module_id %d\n", module_id);
+
+    task = module->my_task;
+    lock_flags = bcmos_fastlock_lock(&task->active_lock);
+    task->modules[module->idx] = NULL;
+    task->active_modules &= ~(1 << module->idx);
+
+    /* Because we are not allowed to free memory (via bcmos_free()) when interrupts are locked, we only empty the linked list (via SLIST_INIT()) and the free comes outside the locked
+     * section. */
+    q_lock_flags = bcmos_fastlock_lock(&module->msgq.lock);
+    msgl_urg = module->msgq.msgl_urg;
+    msgl = module->msgq.msgl;
+    STAILQ_INIT(&module->msgq.msgl_urg);
+    STAILQ_INIT(&module->msgq.msgl);
+    bcmos_fastlock_unlock(&module->msgq.lock, q_lock_flags);
+    bcmos_fastlock_unlock(&task->active_lock, lock_flags);
+
+    bcmos_msg_list_destroy(&msgl_urg);
+    bcmos_msg_list_destroy(&msgl);
+
+    if (module->parm.exit)
+        module->parm.exit(module->parm.data);
+    bcmos_modules[module_id] = NULL;
+    bcmos_free(module);
+
+    return BCM_ERR_OK;
+}
+
+/* Get current module id in the current task */
+bcmos_module_id bcmos_module_current(void)
+{
+    bcmos_task *task = bcmos_task_current();
+
+    if (!task)
+        return BCMOS_MODULE_ID_NONE;
+    return task->current_module;
+}
+
+/* Get module context set by bcmos_module_context_set() */
+void *bcmos_module_context(bcmos_module_id module_id)
+{
+    bcmos_module *module = _bcmos_module_get(module_id);
+    if (!module)
+        return NULL;
+    return module->context;
+}
+
+/* Set module context */
+bcmos_errno bcmos_module_context_set(bcmos_module_id module_id, void *context)
+{
+    bcmos_module *module = _bcmos_module_get(module_id);
+
+    if (!module)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "module_id %d\n", module_id);
+    module->context = context;
+    return BCM_ERR_OK;
+}
+
+/* Query module info */
+bcmos_errno bcmos_module_query(bcmos_module_id module_id, const bcmos_task **task, bcmos_msg_queue_info *info)
+{
+    bcmos_module *module = _bcmos_module_get(module_id);
+
+    if (!module)
+    {
+        return BCM_ERR_NOENT;
+    }
+    if (task)
+    {
+        *task = module->my_task;
+    }
+    if (info)
+    {
+        info->parm = module->parm.qparm;
+        info->stat = module->msgq.stat;
+    }
+    return BCM_ERR_OK;
+}
+
+/*
+ * Events
+ */
+
+/* This function handles event arrival in module context */
+static void _bcmos_ev_in_module_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+    bcmos_event *ev = _bcmos_msg_to_event(msg);
+    uint32_t active_bits;
+    long lock_flags;
+
+    active_bits = ev->active_bits & ev->parm.mask;
+    ev->parm.handler(ev->id, active_bits);
+
+    lock_flags = bcmos_fastlock_lock(&ev->lock);
+    ev->active_bits &= ~active_bits;
+    ev->is_waiting = BCMOS_TRUE;
+    bcmos_fastlock_unlock(&ev->lock, lock_flags);
+}
+
+/* Release event message. Only called in exceptional situations,
+ * such as module queue destroy. Do nothing.
+ */
+static void _bcmos_ev_msg_release(bcmos_msg *msg)
+{
+}
+
+/* Create event set */
+bcmos_errno bcmos_event_create(bcmos_event_id event_id, bcmos_event_parm *parm)
+{
+    bcmos_event *ev;
+    bcmos_module *module = NULL;
+    bcmos_errno rc;
+
+    if ((unsigned)event_id >= (unsigned)BCMOS_EVENT_ID__NUM_OF)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "event_id %d\n", event_id);
+
+    if (_bcmos_event_get(event_id))
+        BCMOS_TRACE_RETURN(BCM_ERR_ALREADY, "event_id %d\n", event_id);
+
+    if (parm && parm->module_id != BCMOS_MODULE_ID_NONE)
+    {
+        module = _bcmos_module_get(parm->module_id);
+        if (!module)
+            BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "module_id %d\n", parm->module_id);
+        if (!parm->handler || !parm->mask)
+            BCMOS_TRACE_RETURN(BCM_ERR_PARM, "event_id %d, handler %p, mask %x\n", event_id, parm->handler, parm->mask);
+    }
+
+    ev = bcmos_calloc(sizeof(bcmos_event));
+    if (!ev)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "event_id %d\n", event_id);
+
+    ev->id = event_id;
+    if (parm)
+        ev->parm = *parm;
+    bcmos_fastlock_init(&ev->lock, ev->parm.flags);
+    {
+        rc = bcmos_sem_create(&ev->m, 0, ev->parm.flags, ev->parm.name);
+        if (rc)
+        {
+            bcmos_free(ev);
+            return rc;
+        }
+    }
+
+    /* Initialize event message in integration mode */
+    if (ev->parm.module_id != BCMOS_MODULE_ID_NONE)
+    {
+        ev->msg.handler = _bcmos_ev_in_module_handler;
+        ev->msg.release = _bcmos_ev_msg_release;
+        ev->msg.sender = BCMOS_MODULE_ID_NONE;
+        ev->msg.type = BCMOS_MSG_ID_INTERNAL_EVENT;
+        ev->is_waiting = BCMOS_TRUE;
+    }
+
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (ev->parm.name)
+    {
+        strncpy(ev->name, ev->parm.name, sizeof(ev->name) - 1);
+        ev->parm.name = ev->name;
+    }
+
+    bcmos_events[event_id] = ev;
+
+    return BCM_ERR_OK;
+}
+
+/* Destroy event set created by bcmos_event_create() */
+bcmos_errno bcmos_event_destroy(bcmos_event_id event_id)
+{
+    return BCM_ERR_NOT_SUPPORTED;
+}
+
+/* Raise event */
+bcmos_errno bcmos_event_raise(bcmos_event_id event_id, uint32_t active_bits)
+{
+    bcmos_event *ev = _bcmos_event_get(event_id);
+    long lock_flags;
+
+    if (!ev)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "event_id %d\n", event_id);
+
+    lock_flags = bcmos_fastlock_lock(&ev->lock);
+    ev->active_bits |= active_bits;
+    if (ev->is_waiting && (ev->active_bits & ev->parm.mask))
+    {
+        ev->is_waiting = BCMOS_FALSE;
+        bcmos_fastlock_unlock(&ev->lock, lock_flags);
+        if (ev->parm.module_id != BCMOS_MODULE_ID_NONE)
+            bcmos_msg_send_to_module(ev->parm.module_id, &ev->msg, BCMOS_MSG_SEND_URGENT | BCMOS_MSG_SEND_NOLIMIT);
+        else
+            bcmos_sem_post(&ev->m);
+    }
+    else
+    {
+        bcmos_fastlock_unlock(&ev->lock, lock_flags);
+    }
+
+    return BCM_ERR_OK;
+}
+
+/* Wait for event */
+bcmos_errno bcmos_event_recv(bcmos_event_id event_id, uint32_t mask,
+    uint32_t timeout, uint32_t *active_bits)
+{
+    bcmos_event *ev = _bcmos_event_get(event_id);
+    long lock_flags;
+
+    BUG_ON(!active_bits);
+    if (!ev)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "event_id %d is not registered\n", event_id);
+
+    lock_flags = bcmos_fastlock_lock(&ev->lock);
+    *active_bits = ev->active_bits & mask;
+    if (*active_bits)
+    {
+        ev->active_bits &= ~ *active_bits;
+        bcmos_fastlock_unlock(&ev->lock, lock_flags);
+        return BCM_ERR_OK;
+    }
+    if (!timeout)
+    {
+        bcmos_fastlock_unlock(&ev->lock, lock_flags);
+        return BCM_ERR_NOENT;
+    }
+
+    /* recv with wait */
+    ev->is_waiting = BCMOS_TRUE;
+    bcmos_fastlock_unlock(&ev->lock, lock_flags);
+
+    /* wait for it */
+    bcmos_sem_wait(&ev->m, timeout);
+    /* Either got event or timeout */
+    lock_flags = bcmos_fastlock_lock(&ev->lock);
+    *active_bits = ev->active_bits & mask;
+    ev->active_bits &= ~ *active_bits;
+    ev->is_waiting = BCMOS_FALSE;
+    bcmos_fastlock_unlock(&ev->lock, lock_flags);
+    /* If we wait forever and we got an event that does not match the mask we wait on (this is the only possible reason getting here if waiting forever), then we
+     * want to avoid returning BCM_ERR_TIMEOUT - it's not an error. */
+    if (timeout != BCMOS_WAIT_FOREVER && !*active_bits)
+        return BCM_ERR_TIMEOUT;
+    return BCM_ERR_OK;
+}
+
+/*
+ * Timer
+ */
+
+/* compare timestamps minding wrap-around
+ * returns delta >= 0 if ts1 >= ts2
+ */
+static inline int32_t _bcmos_timer_ts_delta(uint32_t ts1, uint32_t ts2)
+{
+    int32_t delta = (int)(ts1 - ts2);
+    return delta;
+}
+
+static int32_t _bcmos_timer_compare(struct bcmos_timer *t1, struct bcmos_timer *t2)
+{
+    int32_t delta = _bcmos_timer_ts_delta(t1->expire_at, t2->expire_at);
+#if defined(BCMOS_TIMER_RB_TREE) && !defined(BCMOS_TIMER_RB_TREE_LIST)
+    /* FreeBSD RB tree implementation doesn't support 2 nodes with the same key */
+    if (!delta)
+        delta = 1;
+#endif
+    return delta;
+}
+
+static inline void _bcmos_start_system_timer(bcmos_timer *head)
+{
+    if (head)
+    {
+        int32_t delay = _bcmos_timer_ts_delta(head->expire_at, bcmos_timestamp());
+        /* Handle rare race condition when next timer expired while we were fiddling
+         * with the pool. Just give it 1 more "tick". System handler handles all timers
+         * expired (<now .. now + PRECISION/2)
+         */
+        if (delay <= 0)
+        {
+            delay = BCMOS_TIMER_PRECISION_US / 2;
+        }
+        bcmos_sys_timer_start(&tmr_pool.sys_timer, delay);
+    }
+    else
+    {
+        bcmos_sys_timer_stop(&tmr_pool.sys_timer);
+    }
+}
+
+/*
+ * Timer pool: RB tree or TAILQ-based implementation
+ */
+static void _bcmos_timer_pool_insert(bcmos_timer *timer, uint32_t delay, bcmos_bool start_sys_timer)
+{
+    long flags;
+    bcmos_timer *head;
+
+    flags = bcmos_fastlock_lock(&tmr_pool.lock);
+    if (BCMOS_TIMER_IS_RUNNING(timer))
+    {
+        bcmos_fastlock_unlock(&tmr_pool.lock, flags);
+        return;
+    }
+    timer->period = timer->parm.periodic ? delay : 0;
+    timer->expire_at = BCMOS_ROUND_UP(bcmos_timestamp() + delay, BCMOS_TIMER_PRECISION_US / 2);
+    TMR_POOL_INSERT(&tmr_pool, timer);
+    timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+    timer->flags |= BCMOS_TIMER_FLAG_RUNNING;
+
+    /* If new timer is at the top - kick system timer */
+    if (start_sys_timer)
+    {
+        head = TMR_POOL_FIRST(&tmr_pool);
+        if (timer == head)
+        {
+            _bcmos_start_system_timer(head);
+        }
+    }
+    bcmos_fastlock_unlock(&tmr_pool.lock, flags);
+}
+
+static void _bcmos_timer_stop(bcmos_timer *timer)
+{
+    long flags;
+    bcmos_bool was_top;
+    bcmos_msg_queue_nw *queue;
+
+    /* First take running timer out of the active pool */
+    flags = bcmos_fastlock_lock(&tmr_pool.lock);
+    timer->period = 0; /* Prevent periodic timer restart */
+    if (BCMOS_TIMER_IS_RUNNING(timer))
+    {
+        timer->flags &= ~BCMOS_TIMER_FLAG_RUNNING;
+        was_top = (timer == TMR_POOL_FIRST(&tmr_pool));
+        TMR_POOL_REMOVE(&tmr_pool, timer);
+
+        /* If timer was the top - stop/restart system timer */
+        if (was_top)
+        {
+            _bcmos_start_system_timer(TMR_POOL_FIRST(&tmr_pool));
+        }
+    }
+    bcmos_fastlock_unlock(&tmr_pool.lock, flags);
+
+    /* Now timer is not in the active pool. Perhaps it is already in
+     * destination module's queue. Take it out if yes.
+     */
+    queue = timer->queue;
+    if (queue)
+    {
+        flags = bcmos_fastlock_lock(&queue->lock);
+        /* Check queue again because the previous check was unprotected */
+        if (timer->queue)
+        {
+            bcmos_msg_list *msg_list = ((timer->parm.flags & BCMOS_TIMER_PARM_FLAGS_NON_URGENT))
+                ? &queue->msgl : &queue->msgl_urg;
+            if (STAILQ_REMOVE_SAFE(msg_list, &timer->msg, bcmos_msg, next) != NULL)
+            {
+                _bcmos_msgq_stat_dec(queue);
+            }
+            timer->queue = NULL;
+        }
+        timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+        bcmos_fastlock_unlock(&queue->lock, flags);
+    }
+
+    /* If timer has already expired and we weren't able to stop it -
+     * wait for expiration callback to finish before leaving _bcmos_timer_stop()
+     */
+    if (BCMOS_TIMER_IS_EXPIRED(timer))
+    {
+        bcmos_task *t = bcmos_task_current();
+
+        /* Skip wait if timer is being stopped / restarted from inside the handler */
+        if (t != timer->task)
+        {
+            while (BCMOS_TIMER_IS_EXPIRED(timer) && BCMOS_TIMER_IS_VALID(timer))
+            {
+                bcmos_usleep(1000);
+            }
+            timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+        }
+    }
+}
+
+
+/* System timer expiration handler.
+ * Execute all timers that expired and restart system timer
+ */
+static void _sys_timer_handler(void *data)
+{
+    bcmos_timer_pool *pool = (bcmos_timer_pool *)data;
+    bcmos_timer *timer;
+    bcmos_timer_rc rc;
+    long flags;
+
+    BUG_ON(pool != &tmr_pool);
+    flags = bcmos_fastlock_lock(&pool->lock);
+    while ((timer=TMR_POOL_FIRST(pool)) != NULL)
+    {
+        /* Stop when reached timer that hasn't expired yet */
+        if (_bcmos_timer_ts_delta(timer->expire_at, bcmos_timestamp()) > BCMOS_TIMER_PRECISION_US / 2)
+            break;
+        timer->flags |= BCMOS_TIMER_FLAG_EXPIRED;
+        timer->flags &= ~BCMOS_TIMER_FLAG_RUNNING;
+        /* IT: Barrier here ? */
+        TMR_POOL_REMOVE(pool, timer);
+
+        /* Execute handler. Unlock first and re-lock in the end
+         * It is safe to unlock here because the top loop starts from MIN every time
+         */
+        bcmos_fastlock_unlock(&pool->lock, flags);
+        rc = timer->handler(timer, timer->parm.data);
+        if (!timer->parm.owner)
+        {
+            if (rc == BCMOS_TIMER_OK && timer->period)
+            {
+                uint32_t interval = timer->period;
+                timer->period = 0;
+                _bcmos_timer_pool_insert(timer, interval, BCMOS_FALSE);
+            }
+            else
+            {
+                timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+            }
+        }
+        flags = bcmos_fastlock_lock(&pool->lock);
+    }
+    /* Finally kick system timer */
+    _bcmos_start_system_timer(timer);
+    bcmos_fastlock_unlock(&pool->lock, flags);
+}
+
+/* Send timer expiration to the target module as urgent message.
+ * _bcmos_timer_in_module_handler() will get called in the module context
+ */
+static bcmos_timer_rc _bcmos_timer_send_to_module_handler(bcmos_timer *timer, long data)
+{
+    bcmos_errno rc;
+    bcmos_module *module = _bcmos_module_get(timer->parm.owner);
+    bcmos_msg_send_flags send_flags;
+    if (!module)
+    {
+        /* Shouldn't happen, unless the module was destroyed */
+        BCMOS_TRACE_ERR("_bcmos_timer_send_to_module_handler() -- no module=%u (timer->parm.handler=0x%p)\n", timer->parm.owner, timer->parm.handler);
+        timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+        return BCMOS_TIMER_STOP;      /* will restart in module context if necessary */
+    }
+    timer->queue = &module->msgq;
+    send_flags = BCMOS_MSG_SEND_NOLIMIT;
+    if (!((timer->parm.flags & BCMOS_TIMER_PARM_FLAGS_NON_URGENT)))
+        send_flags |= BCMOS_MSG_SEND_URGENT;
+    rc = bcmos_msg_send_to_module(timer->parm.owner, &timer->msg, send_flags);
+    if (rc)
+    {
+        /* Shouldn't happen, unless the module was destroyed. Very short race condition here */
+        timer->queue = NULL;
+        timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+        BCMOS_TRACE_ERR("_bcmos_timer_send_to_module_handler() --> %d\n", rc);
+    }
+    return BCMOS_TIMER_STOP; /* will restart in module context if necessary */
+}
+
+/* This function handles timer expiration in module context */
+static void _bcmos_timer_in_module_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+    bcmos_timer *timer = _bcmos_msg_to_timer(msg);
+    bcmos_module *module = _bcmos_module_get(timer->parm.owner);
+    bcmos_timer_rc rc;
+
+    /* Call timer's callback function and restart the timer if necessary */
+    timer->queue = NULL;
+    /* module can't be NULL here. it is checked anyway to keep static code analyzer happy */
+    timer->task = module ? module->my_task : (bcmos_task*)NULL;
+    rc = timer->parm.handler(timer, timer->parm.data);
+    timer->task = NULL;
+    if (rc == BCMOS_TIMER_OK && timer->period)
+        _bcmos_timer_pool_insert(timer, timer->period, BCMOS_TRUE);
+    else
+        timer->flags &= ~BCMOS_TIMER_FLAG_EXPIRED;
+}
+
+/* Release timer message. Only called in exceptional situations,
+ * such as module queue destroy. Do nothing
+ */
+static void _bcmos_timer_msg_release(bcmos_msg *msg)
+{
+}
+
+/* Create timer */
+bcmos_errno bcmos_timer_create(bcmos_timer *timer, bcmos_timer_parm *parm)
+{
+    if (!timer || !parm || !parm->handler)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "timer %p, parm %p handler %p\n", timer, parm, parm ? parm->handler : NULL);
+    if (parm->owner != BCMOS_MODULE_ID_NONE && _bcmos_module_get(parm->owner) == NULL)
+        BCMOS_TRACE_RETURN(BCM_ERR_NOENT, "module_id %d\n", parm->owner);
+    memset(timer, 0, sizeof(bcmos_timer));
+    timer->parm = *parm;
+    if (parm->owner == BCMOS_MODULE_ID_NONE)
+        timer->handler = parm->handler;
+    else
+    {
+        timer->handler = _bcmos_timer_send_to_module_handler;
+        timer->msg.handler = _bcmos_timer_in_module_handler;
+        timer->msg.release = _bcmos_timer_msg_release;
+        timer->msg.sender = BCMOS_MODULE_ID_NONE;
+        timer->msg.type = BCMOS_MSG_ID_INTERNAL_TIMER;
+    }
+    timer->flags |= BCMOS_TIMER_FLAG_VALID;
+    return BCM_ERR_OK;
+}
+
+/* Destroy timer */
+void bcmos_timer_destroy(bcmos_timer *timer)
+{
+    BUG_ON(!timer);
+    bcmos_timer_stop(timer);
+    timer->flags &= ~BCMOS_TIMER_FLAG_VALID;
+}
+
+/* (Re)start timer */
+void bcmos_timer_start(bcmos_timer *timer, uint32_t delay)
+{
+    BUG_ON(!timer);
+    BUG_ON(!BCMOS_TIMER_IS_VALID(timer));
+    if ((int32_t)delay < 0)
+    {
+        BCMOS_TRACE_ERR("Attempt to start timer (%s) for period longer than 2^31-1. Reduced to 2^31-1\n",
+            timer->parm.name ? timer->parm.name : "*unnamed*");
+        delay = 0x7fffffff;
+    }
+
+    if (BCMOS_TIMER_IS_RUNNING(timer) || BCMOS_TIMER_IS_EXPIRED(timer))
+    {
+        _bcmos_timer_stop(timer);
+    }
+    _bcmos_timer_pool_insert(timer, delay, BCMOS_TRUE);
+}
+
+/* Stop timer if running */
+void bcmos_timer_stop(bcmos_timer *timer)
+{
+    BUG_ON(!timer);
+    _bcmos_timer_stop(timer);
+}
+
+/** Set timer handler */
+bcmos_errno bcmos_timer_handler_set(bcmos_timer *timer, F_bcmos_timer_handler handler, long data)
+{
+    BUG_ON(!timer);
+    BUG_ON(!handler);
+    timer->parm.handler = handler;
+    timer->parm.data = data;
+    if (timer->parm.owner == BCMOS_MODULE_ID_NONE)
+        timer->handler = handler;
+    return BCM_ERR_OK;
+}
+
+/*
+ * Block memory pool
+ */
+
+/* Memory block structure:
+ * - bcmos_memblk
+ * - blk_size bytes of user data
+ * - [magic - for block overflow-corruption check]
+ * - [padding to align to pointer size]
+ */
+
+struct bcmos_memblk
+{
+    STAILQ_ENTRY(bcmos_memblk) next; /**< Next block pointer */
+    bcmos_blk_pool *pool;       /** pool that owns the block */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /** magic number */
+#define BCMOS_MEM_MAGIC_ALLOC   (('m'<<24) | ('b' << 16) | ('l' << 8) | 'k')
+#define BCMOS_MEM_MAGIC_FREE    (('m'<<24) | ('b' << 16) | ('l' << 8) | '~')
+#define BCMOS_MEM_MAGIC_SUFFIX  (('m'<<24) | ('b' << 16) | ('l' << 8) | 's')
+    uint32_t lineno;            /** line number where the block was allocated/released. FFU */
+#endif
+};
+
+/* Create byte memory pool */
+bcmos_errno bcmos_blk_pool_create(bcmos_blk_pool *pool, const bcmos_blk_pool_parm *parm)
+{
+    uint32_t blk_size;
+
+    if (!pool || !parm || !parm->blk_size)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool %p, parm %p, blk_size=%u, num_blks=%u\n",
+            pool, parm, parm ? parm->blk_size : 0, parm ? parm->num_blks : 0);
+    }
+    if (parm->num_blks & parm->pool_size)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "One and only one of num_blks (%u) and pool_size (%u) must be set\n",
+            parm->num_blks, parm->pool_size);
+    }
+    if (parm->num_blks && parm->start != NULL)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "num_blks!=0 can't be used with start!=NULL. Use byte size instead\n");
+    }
+
+    BCM_MEMZERO_STRUCT(pool);
+    pool->parm = *parm;
+
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (pool->parm.name)
+    {
+        strncpy(pool->name, pool->parm.name, sizeof(pool->name) - 1);
+        pool->parm.name = pool->name;
+    }
+
+    /*
+     * Calculate total block size in bytes, including overheads
+     */
+    /* Round up block size to the nearest 32-bit word to make MAGIC check cheaper.
+     * It doesn't affect the actual overhead size because of the final
+     * rounding up to pointer size.
+     */
+    pool->parm.blk_size = BCMOS_ROUND_UP(pool->parm.blk_size, sizeof(uint32_t));
+    blk_size = pool->parm.blk_size + sizeof(bcmos_memblk);
+#ifdef BCMOS_MEM_DEBUG
+    blk_size += sizeof(uint32_t); /* room for magic after user data block */
+#endif
+    blk_size = BCMOS_ROUND_UP(blk_size, sizeof(void *));
+
+    /* Derive num_blks / pool_size from one another */
+    if (pool->parm.num_blks)
+    {
+        pool->parm.pool_size = parm->num_blks * blk_size;
+    }
+    else
+    {
+        pool->parm.num_blks = pool->parm.pool_size / blk_size;
+        if (!pool->parm.num_blks)
+        {
+            BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool_size (%u) is too small\n", parm->pool_size);
+        }
+    }
+
+    /* Allocate memory for the pool if "start" is not set */
+    pool->start = pool->parm.start;
+    if (!pool->start)
+    {
+        pool->start = bcmos_alloc(pool->parm.pool_size);
+        if (!pool->start)
+        {
+            BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "Can't allocate memory for block pool %s\n", parm->name);
+        }
+    }
+
+    bcmos_fastlock_init(&pool->lock, parm->flags);
+
+    /* Put all blocks on free list */
+    bcmos_blk_pool_reset(pool);
+
+    pool->magic = BCMOS_BLK_POOL_VALID;
+    if (!(pool->parm.flags & BCMOS_BLK_POOL_FLAG_MSG_POOL))
+    {
+        bcmos_mutex_lock(&bcmos_res_lock);
+        STAILQ_INSERT_TAIL(&blk_pool_list, pool, list);
+        bcmos_total_blk_pool_size += pool->parm.pool_size;
+        bcmos_mutex_unlock(&bcmos_res_lock);
+    }
+
+    return BCM_ERR_OK;
+}
+
+/* Destroy memory pool */
+bcmos_errno bcmos_blk_pool_destroy(bcmos_blk_pool *pool)
+{
+    if (!pool || pool->magic != BCMOS_BLK_POOL_VALID)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool handle is invalid\n");
+    }
+    if (pool->stat.free < pool->parm.num_blks)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_STATE, "%i blocks are still allocated from the pool %s\n",
+            pool->parm.num_blks - pool->stat.free, pool->parm.name);
+    }
+    if (!(pool->parm.flags & BCMOS_BLK_POOL_FLAG_MSG_POOL))
+    {
+        bcmos_mutex_lock(&bcmos_res_lock);
+        STAILQ_REMOVE(&blk_pool_list, pool, bcmos_blk_pool, list);
+        bcmos_total_blk_pool_size -= pool->parm.pool_size;
+        bcmos_mutex_unlock(&bcmos_res_lock);
+    }
+    if (!pool->parm.start && pool->start)
+    {
+        bcmos_free(pool->start);
+    }
+    pool->magic = BCMOS_BLK_POOL_DELETED;
+    return BCM_ERR_OK;
+}
+
+/** Release all blocks in memory pool . Block content is not affected */
+void bcmos_blk_pool_reset(bcmos_blk_pool *pool)
+{
+    uint32_t blk_size;
+    bcmos_memblk *blk;
+    uint32_t i;
+
+    STAILQ_INIT(&pool->free_list);
+
+    blk_size = pool->parm.blk_size + sizeof(bcmos_memblk);
+#ifdef BCMOS_MEM_DEBUG
+    blk_size += sizeof(uint32_t); /* room for magic after user data block */
+#endif
+    blk_size = BCMOS_ROUND_UP(blk_size, sizeof(void *));
+
+    /* Put all blocks on free list */
+    blk = (bcmos_memblk *)pool->start;
+    for (i = 0; i < pool->parm.num_blks; i++)
+    {
+        blk->pool = pool;
+        STAILQ_INSERT_TAIL(&pool->free_list, blk, next);
+#ifdef BCMOS_MEM_DEBUG
+        *(uint32_t*)((long)blk + sizeof(bcmos_memblk) + pool->parm.blk_size) = BCMOS_MEM_MAGIC_SUFFIX;
+        blk->lineno = 0;
+        blk->magic = BCMOS_MEM_MAGIC_FREE;
+#endif
+        blk = (bcmos_memblk *)((long)blk + blk_size);
+    }
+
+    /* Init statistics */
+    memset(&pool->stat, 0, sizeof(pool->stat));
+    pool->stat.free = pool->parm.num_blks;
+}
+
+/* Allocate block from block memory pool */
+void *bcmos_blk_pool_alloc(bcmos_blk_pool *pool)
+{
+    bcmos_memblk *blk;
+    long flags;
+
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(!pool);
+    BUG_ON(pool->magic != BCMOS_BLK_POOL_VALID);
+#endif
+    flags = bcmos_fastlock_lock(&pool->lock);
+    blk = STAILQ_FIRST(&pool->free_list);
+    if (blk)
+    {
+        STAILQ_REMOVE_HEAD(&pool->free_list, next);
+        ++pool->stat.allocated;
+#ifdef BCMOS_MEM_DEBUG
+        blk->magic = BCMOS_MEM_MAGIC_ALLOC;
+#endif
+        bcmos_fastlock_unlock(&pool->lock, flags);
+        return (void *)(blk + 1);
+    }
+
+    /* No memory */
+    ++pool->stat.alloc_failed;
+    bcmos_fastlock_unlock(&pool->lock, flags);
+    return NULL;
+}
+
+/* Allocate block from block memory pool and zero the block */
+void *bcmos_blk_pool_calloc(bcmos_blk_pool *pool)
+{
+    void *ptr = bcmos_blk_pool_alloc(pool);
+    if (ptr)
+    {
+        memset(ptr, 0, pool->parm.blk_size);
+    }
+    return ptr;
+}
+
+/* Release memory allocated using bcmos_pool_byte_alloc() or bcmos_pool_blk_alloc() */
+void bcmos_blk_pool_free(void *ptr)
+{
+    bcmos_memblk *blk;
+    bcmos_blk_pool *pool;
+    long flags;
+
+    blk = (bcmos_memblk *)((long)ptr - sizeof(bcmos_memblk));
+    pool = blk->pool;
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(blk->magic != BCMOS_MEM_MAGIC_ALLOC);
+    BUG_ON(pool == NULL);
+    BUG_ON(pool->magic != BCMOS_BLK_POOL_VALID);
+    BUG_ON(*(uint32_t *)((long)ptr + pool->parm.blk_size) != BCMOS_MEM_MAGIC_SUFFIX);
+    blk->magic = BCMOS_MEM_MAGIC_FREE;
+#endif
+    flags = bcmos_fastlock_lock(&pool->lock);
+    STAILQ_INSERT_HEAD(&pool->free_list, blk, next);
+    ++pool->stat.released;
+    bcmos_fastlock_unlock(&pool->lock, flags);
+}
+
+/* Get pool info */
+bcmos_errno bcmos_blk_pool_query(const bcmos_blk_pool *pool, bcmos_blk_pool_info *info)
+{
+    if (!pool || !info)
+    {
+        return BCM_ERR_PARM;
+    }
+    info->parm = pool->parm;
+    info->stat = pool->stat;
+    info->stat.free = pool->parm.num_blks - (info->stat.allocated - info->stat.released);
+    return BCM_ERR_OK;
+}
+
+/* Block pool iterator */
+bcmos_errno bcmos_blk_pool_get_next(const bcmos_blk_pool **prev)
+{
+    const bcmos_blk_pool *pool;
+
+    if (prev == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    pool = *prev;
+    if (pool && pool->magic != BCMOS_BLK_POOL_VALID)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (pool)
+    {
+        pool = STAILQ_NEXT(pool, list);
+    }
+    else
+    {
+        pool = STAILQ_FIRST(&blk_pool_list);
+    }
+    *prev = pool;
+    if (!pool)
+    {
+        return BCM_ERR_NO_MORE;
+    }
+    return BCM_ERR_OK;
+}
+
+/*
+ * Message pool
+ */
+
+/* release message callback */
+static void _bcmos_msg_pool_release(bcmos_msg *msg)
+{
+    if (msg->data_release)
+        msg->data_release(msg);
+    bcmos_blk_pool_free(msg);
+}
+
+/* Create message pool */
+bcmos_errno bcmos_msg_pool_create(bcmos_msg_pool *pool, const bcmos_msg_pool_parm *parm)
+{
+    bcmos_blk_pool_parm pool_parm = {};
+    bcmos_memblk *blk;
+    bcmos_errno err;
+
+    if (!pool || !parm || !parm->size)
+    {
+        return BCM_ERR_PARM;
+    }
+    BCM_MEMZERO_STRUCT(pool);
+    pool->parm = *parm;
+    pool_parm.num_blks = parm->size;
+    pool_parm.blk_size = parm->data_size + sizeof(bcmos_msg);
+    pool_parm.flags = parm->flags | BCMOS_BLK_POOL_FLAG_MSG_POOL;
+    pool_parm.name = parm->name;
+
+    /* Create underlying block pool */
+    err = bcmos_blk_pool_create(&pool->blk_pool, &pool_parm);
+    if (err)
+    {
+        return err;
+    }
+    pool->parm.name = pool->blk_pool.name;
+
+    /* Pre-initialize all messages */
+    STAILQ_FOREACH(blk, &pool->blk_pool.free_list, next)
+    {
+        bcmos_msg *msg = (bcmos_msg *)(blk + 1);
+        msg->data = (void *)(msg + 1);
+        msg->size = pool->parm.data_size;
+        msg->release = _bcmos_msg_pool_release;
+        msg->data_release = parm->data_release;
+    }
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&msg_pool_list, &pool->blk_pool, list);
+    bcmos_total_msg_pool_size += pool->blk_pool.parm.pool_size;
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    return BCM_ERR_OK;
+}
+
+/** Destroy message pool */
+bcmos_errno bcmos_msg_pool_destroy(bcmos_msg_pool *pool)
+{
+    bcmos_errno rc;
+
+    rc = bcmos_blk_pool_destroy(&pool->blk_pool);
+    if (rc)
+        return rc;
+
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&msg_pool_list, &pool->blk_pool, bcmos_blk_pool, list);
+    bcmos_total_msg_pool_size -= pool->blk_pool.parm.pool_size;
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    pool->parm.size = pool->parm.data_size = 0;
+    return BCM_ERR_OK;
+}
+
+/* Allocate message from pool */
+bcmos_msg *bcmos_msg_pool_alloc(bcmos_msg_pool *pool)
+{
+    return bcmos_blk_pool_alloc(&pool->blk_pool);
+}
+
+/* Get pool info */
+bcmos_errno bcmos_msg_pool_query(const bcmos_msg_pool *pool, bcmos_msg_pool_info *info)
+{
+    bcmos_blk_pool_info pool_info;
+    bcmos_errno err;
+
+    if (!pool || !info)
+    {
+        return BCM_ERR_PARM;
+    }
+    err = bcmos_blk_pool_query(&pool->blk_pool, &pool_info);
+    if (err)
+    {
+        return err;
+    }
+    info->parm = pool->parm;
+    info->stat = pool_info.stat;
+    return BCM_ERR_OK;
+}
+
+/* Block pool iterator */
+bcmos_errno bcmos_msg_pool_get_next(const bcmos_msg_pool **prev)
+{
+    const bcmos_msg_pool *pool;
+
+    if (prev == NULL)
+    {
+        return BCM_ERR_PARM;
+    }
+    pool = *prev;
+    if (pool && pool->blk_pool.magic != BCMOS_BLK_POOL_VALID)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (pool)
+    {
+        pool = container_of(STAILQ_NEXT(&pool->blk_pool, list), bcmos_msg_pool, blk_pool);
+    }
+    else
+    {
+        pool = container_of(STAILQ_FIRST(&msg_pool_list), bcmos_msg_pool, blk_pool);
+    }
+    *prev = pool;
+    if (!pool)
+    {
+        return BCM_ERR_NO_MORE;
+    }
+    return BCM_ERR_OK;
+}
+
+/** Set up print redirection/cloning
+ * \param[in]   mode    redirection/cloning mode
+ * \param[in]   cb      redirection callback
+ * \param[in]   data    opaque data to be passed to cb
+ */
+bcmos_errno bcmos_print_redirect(bcmos_print_redirect_mode mode, bcmos_print_redirect_cb cb, void *data)
+{
+    if (mode != BCMOS_PRINT_REDIRECT_MODE_NONE && cb == NULL)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Redirection callback must be set\n");
+    }
+    print_redirect_mode = mode;
+    if (mode == BCMOS_PRINT_REDIRECT_MODE_NONE)
+    {
+        print_redirect_cb = NULL;
+        print_redirect_cb_data = NULL;
+    }
+    else
+    {
+        print_redirect_cb = cb;
+        print_redirect_cb_data = data;
+    }
+    return BCM_ERR_OK;
+}
+
+/* Print on the console with optional cloning / redirection */
+/*lint -e{454}*/
+int bcmos_vprintf(const char *format, va_list ap)
+{
+    int rc = 0;
+    bcmos_bool protected_section = is_irq_mode() || is_irq_disabled();
+
+    /* Only protect if in task context */
+    if (!protected_section)
+    {
+        bcmos_mutex_lock(&bcmos_print_lock);
+    }
+    if (print_redirect_mode != BCMOS_PRINT_REDIRECT_MODE_REDIRECT)
+    {
+        rc = bcmos_sys_vprintf(format, ap);
+    }
+    if (print_redirect_mode != BCMOS_PRINT_REDIRECT_MODE_NONE)
+    {
+        rc = print_redirect_cb(print_redirect_cb_data, format, ap);
+    }
+    if (!protected_section)
+    {
+        bcmos_mutex_unlock(&bcmos_print_lock);
+    }
+
+    return rc;
+}
+/*lint -e{454}*/
+
+/* Print on the console with optional cloning / redirection */
+int bcmos_printf(const char *format, ...)
+{
+    va_list args;
+    int rc;
+
+    va_start(args, format);
+    rc = bcmos_vprintf(format, args);
+    va_end(args);
+    return rc;
+}
+
+#ifndef BCMOS_PUTCHAR_INLINE
+/*lint -e{454}*/
+void bcmos_putchar(int c)
+{
+    bcmos_bool protected_section = is_irq_mode() || is_irq_disabled();
+
+    /* Only protect if in task context */
+    if (!protected_section)
+    {
+        bcmos_mutex_lock(&bcmos_print_lock);
+    }
+    putchar(c);
+    fflush(stdout);
+    if (!protected_section)
+    {
+        bcmos_mutex_unlock(&bcmos_print_lock);
+    }
+}
+/*lint +e{454}*/
+#endif
+
+#ifndef BCMOS_BUF_OS_SPECIFIC
+
+/*
+ * Buffer allocation/release
+ */
+
+#ifdef BCMOS_BUF_POOL_SIZE
+/** Create buffer pool
+ * \param[in]   num     Number of buffers
+ * \param[in]   size    Buffer size
+ * \param[in]   align   Buffer alignment
+ * \returns o=OK or error <0
+ */
+static bcmos_errno bcmos_buf_pool_create(void)
+{
+    bcmos_blk_pool_parm pool_parm =
+    {
+        .name = "sysbuf"
+    };
+    bcmos_errno rc;
+
+#ifndef BCMOS_BUF_POOL_BUF_SIZE
+#error BCMOS_BUF_POOL_BUF_SIZE must be defined
+#endif
+
+    /* If buffer memory should be allocated by bcmos_dma_alloc - allocate
+     * memory for the whole pool here */
+    pool_parm.blk_size = BCMOS_BUF_POOL_BUF_SIZE + sizeof(bcmos_buf) + BCMTR_BUF_EXTRA_HEADROOM +
+        2*BCMOS_BUF_DATA_ALIGNMENT + BCMOS_BUF_DATA_GUARD;
+
+#ifdef BCMOS_BUF_IN_DMA_MEM
+    pool_parm.pool_size = (pool_parm.blk_size + sizeof(bcmos_memblk)) * BCMOS_BUF_POOL_SIZE;
+    pool_parm.start = bcmos_dma_alloc(0, pool_parm.pool_size);
+    if (!pool_parm.start)
+        return BCM_ERR_NOMEM;
+#else
+    pool_parm.num_blks = BCMOS_BUF_POOL_SIZE;
+#endif
+
+    rc = bcmos_blk_pool_create(&sys_buf_pool, &pool_parm);
+    if (rc)
+    {
+        if (pool_parm.start)
+            bcmos_dma_free(0, pool_parm.start);
+    }
+
+    return rc;
+}
+#endif
+
+/* Allocate buffer */
+bcmos_buf *bcmos_buf_alloc(uint32_t size)
+{
+    /* Allocate extra 2 * BCMOS_BUF_DATA_ALIGNMENT to make sure that neither data start nor end
+     * end up in the middle of cache line
+     */
+    bcmos_buf *buf;
+
+/* Allocate from the pool  */
+#ifdef BCMOS_BUF_POOL_SIZE
+
+    if (size > BCMOS_BUF_POOL_BUF_SIZE)
+    {
+        BCMOS_TRACE_ERR("Attempt to allocate buffer bigger than buffer pool block size. %u > %u\n",
+            size, BCMOS_BUF_POOL_BUF_SIZE);
+        return NULL;
+    }
+    buf = bcmos_blk_pool_alloc(&sys_buf_pool);
+
+#else /* else of #if BCMOS_BUF_POOL_SIZE */
+    {
+        uint32_t alloc_size = sizeof(bcmos_buf) + size + BCMTR_BUF_EXTRA_HEADROOM +
+            2*BCMOS_BUF_DATA_ALIGNMENT - 1 + BCMOS_BUF_DATA_GUARD;
+#ifdef BCMOS_BUF_DATA_UNIT_SIZE
+#if BCMOS_BUF_DATA_UNIT_SIZE & (BCMOS_BUF_DATA_UNIT_SIZE - 1)
+#error BCMOS_BUF_DATA_UNIT_SIZE must be a power of 2
+#endif
+        alloc_size = BCMOS_ROUND_UP(alloc_size, BCMOS_BUF_DATA_UNIT_SIZE);
+#endif
+#ifdef BCMOS_BUF_IN_DMA_MEM
+        buf = bcmos_dma_alloc(0, alloc_size);
+#else
+        buf = bcmos_alloc(alloc_size);
+#endif
+    }
+#endif /* end of #if BCMOS_BUF_POOL_SIZE */
+
+    if (!buf)
+        return NULL;
+    buf->start = (uint8_t *)(buf + 1) + BCMOS_BUF_DATA_GUARD;
+    buf->data = (uint8_t *)(BCMOS_ROUND_UP((long)buf->start + BCMTR_BUF_EXTRA_HEADROOM, BCMOS_BUF_DATA_ALIGNMENT));
+    buf->size = size + (buf->data - buf->start);
+    buf->len = 0;
+#ifdef BCMOS_BUF_POOL_SIZE
+    buf->pool = &sys_buf_pool;
+#else
+    buf->pool = NULL;
+#endif
+    return buf;
+}
+
+/* Release buffer */
+void bcmos_buf_free(bcmos_buf *buf)
+{
+
+#ifdef BCMOS_BUF_POOL_SIZE
+    /* Buffer might have been allocated from the system pool */
+    if (buf->pool)
+    {
+        bcmos_blk_pool_free(buf);
+        return;
+    }
+#endif
+
+#ifdef BCMOS_BUF_IN_DMA_MEM
+    bcmos_dma_free(0, buf);
+#else
+    bcmos_free(buf);
+#endif
+}
+
+#endif
+
+EXPORT_SYMBOL(bcmos_init);
+
+EXPORT_SYMBOL(bcmos_msg_queue_create);
+EXPORT_SYMBOL(bcmos_msg_queue_destroy);
+EXPORT_SYMBOL(bcmos_msg_queue_query);
+EXPORT_SYMBOL(bcmos_msg_queue_get_next);
+EXPORT_SYMBOL(bcmos_msg_send);
+EXPORT_SYMBOL(bcmos_msg_send_to_module);
+EXPORT_SYMBOL(bcmos_msg_recv);
+EXPORT_SYMBOL(bcmos_msg_register);
+EXPORT_SYMBOL(bcmos_msg_unregister);
+EXPORT_SYMBOL(bcmos_msg_dispatch);
+
+EXPORT_SYMBOL(bcmos_msg_qgroup_create);
+EXPORT_SYMBOL(bcmos_msg_qgroup_destroy);
+EXPORT_SYMBOL(bcmos_msg_qgroup_query);
+EXPORT_SYMBOL(bcmos_msg_recv_from_qgroup);
+EXPORT_SYMBOL(bcmos_msg_send_to_qgroup);
+
+EXPORT_SYMBOL(bcmos_task_timeout_set);
+EXPORT_SYMBOL(bcmos_task_get_next);
+
+EXPORT_SYMBOL(bcmos_module_create);
+EXPORT_SYMBOL(bcmos_module_destroy);
+EXPORT_SYMBOL(bcmos_module_current);
+EXPORT_SYMBOL(bcmos_module_context);
+EXPORT_SYMBOL(bcmos_module_context_set);
+EXPORT_SYMBOL(bcmos_module_query);
+
+EXPORT_SYMBOL(bcmos_event_create);
+EXPORT_SYMBOL(bcmos_event_destroy);
+EXPORT_SYMBOL(bcmos_event_raise);
+EXPORT_SYMBOL(bcmos_event_recv);
+
+EXPORT_SYMBOL(bcmos_timer_create);
+EXPORT_SYMBOL(bcmos_timer_destroy);
+EXPORT_SYMBOL(bcmos_timer_start);
+EXPORT_SYMBOL(bcmos_timer_stop);
+EXPORT_SYMBOL(bcmos_timer_handler_set);
+
+EXPORT_SYMBOL(bcmos_blk_pool_create);
+EXPORT_SYMBOL(bcmos_blk_pool_destroy);
+EXPORT_SYMBOL(bcmos_blk_pool_reset);
+EXPORT_SYMBOL(bcmos_blk_pool_alloc);
+EXPORT_SYMBOL(bcmos_blk_pool_calloc);
+EXPORT_SYMBOL(bcmos_blk_pool_free);
+EXPORT_SYMBOL(bcmos_blk_pool_query);
+EXPORT_SYMBOL(bcmos_blk_pool_get_next);
+
+EXPORT_SYMBOL(bcmos_msg_pool_create);
+EXPORT_SYMBOL(bcmos_msg_pool_alloc);
+EXPORT_SYMBOL(bcmos_msg_pool_query);
+EXPORT_SYMBOL(bcmos_msg_pool_destroy);
+EXPORT_SYMBOL(bcmos_msg_pool_get_next);
+
+EXPORT_SYMBOL(bcmos_print_redirect);
+EXPORT_SYMBOL(bcmos_printf);
+EXPORT_SYMBOL(bcmos_vprintf);
+
+#ifndef BCMOS_BUF_OS_SPECIFIC
+EXPORT_SYMBOL(bcmos_buf_alloc);
+EXPORT_SYMBOL(bcmos_buf_free);
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.h
new file mode 100644
index 0000000..da09c1c
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common.h
@@ -0,0 +1,1479 @@
+/*
+<: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 BCMOS_COMMON_H_
+#define BCMOS_COMMON_H_
+
+#ifndef BCMOS_SYSTEM_H_
+#error Please do not include bcmos_common.h directly. Include bcmos_system.h
+#endif
+
+#include "bcmos_errno.h"
+#include "bcmos_types.h"
+#include "bcmos_queue.h"
+#include "bcmos_tree.h"
+/* Get constants, such as task, module, event id lists */
+#include "bcmos_platform.h"
+#include "bcmos_pack.h"
+#include "bcmos_sysif.h"
+
+#define MAX_TASK_NAME_SIZE          64
+#define MAX_MODULE_NAME_SIZE        64
+#define MAX_MSG_QUEUE_NAME_SIZE     64
+#define MAX_TIMER_NAME_SIZE         64
+#define MAX_POOL_NAME_SIZE          64
+#define MAX_EVENT_NAME_SIZE         64
+#define MAX_MUTEX_NAME_SIZE         64
+#define BCMOS_MSG_POOL_DEFAULT_SIZE 512
+
+/* Define bcmos_bool - the boolean type for bcmos - based on C99 standard boolean type */
+#ifndef BCMOS_BOOLEAN
+typedef _Bool bcmos_bool;
+#define BCMOS_FALSE 0
+#define BCMOS_TRUE 1
+#endif
+
+#define BCM_SIZEOFARRAY(arr) (sizeof(arr)/sizeof(*arr))
+#define BCM_SIZEOFFIELD(s, f) (sizeof(((s*)NULL)->f))
+#define BCM_MEMZERO_STRUCT(ptr) memset(ptr, 0, sizeof(*(ptr)))
+#define BCM_MEMCPY_ARRAY(dst, src) memcpy(dst, src, sizeof(dst))
+#define TAB "  "
+#define TAB2 TAB TAB
+#define TAB3 TAB2 TAB
+#define TAB4 TAB2 TAB2
+
+#define CHIP_REVISION_A0 0xA0
+#define CHIP_REVISION_B0 0xB0
+
+#ifdef SIMULATION_BUILD
+#define GET_CHIP_REVISION CHIP_REVISION_A0
+#else
+extern uint32_t chip_revision;
+#define GET_CHIP_REVISION (chip_revision != 0 ? chip_revision : (chip_revision = get_chip_revision()))
+#endif
+
+typedef void (*f_bcmolt_sw_error_handler)(uint8_t pon_id, const char *file_name, uint32_t line_number);
+
+/* Similar to BUG_ON(), with the following features:
+ * 1. The condition is checked against BCM_ERR_OK.
+ * 2. In case on an error, the macro returns from the calling function with the error code. */
+#define BUG_ON_ERR_RET(f) \
+    do \
+    { \
+        bcmos_errno _err; \
+        _err = f; \
+        BUG_ON(_err != BCM_ERR_OK); \
+        return _err; \
+    } \
+    while (0)
+
+/** \addtogroup system_init
+ * @{
+ */
+
+/** Initialize system library
+ * Must be called before any other system function
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_init(void);
+
+/** Cleanup system library
+ */
+void bcmos_exit(void);
+
+/** @} system_init */
+
+/** \addtogroup system_mem
+ * @{
+ */
+
+#ifndef BCMOS_MALLOC_FREE_INLINE
+
+/** \defgroup system_heap Default Heap
+ * @{
+ */
+
+/** Allocate memory from the main heap
+ * \param[in]   size
+ * \returns memory block pointer or NULL
+ */
+void *bcmos_alloc(uint32_t size);
+
+/** Release memory to the main pool
+ * \param[in]   ptr
+ */
+void bcmos_free(void *ptr);
+
+/** @} system_heap */
+
+#endif /* #ifndef BCMOS_MALLOC_FREE_INLINE */
+
+/** \defgroup blk_pool Block Memory Pool
+ * \ingroup system_mem
+ * @{
+ */
+
+/** Block memory pool parameters */
+typedef struct
+{
+    const char *name;   /**< Pool name */
+    uint32_t blk_size;  /**< Memory block size > 0 */
+    uint32_t num_blks;  /**< Number of blocks in the pool. If not set - it is derived from pool_size */
+    void *start;        /**< Start address. Can be NULL */
+    uint32_t pool_size; /**< Total pool size in bytes. Only 1 of pool_size, num_blks must be set */
+    uint32_t flags;     /**< TBD flags */
+#define BCMOS_BLK_POOL_FLAG_MSG_POOL  0x80000000 /* Used by message pool */
+} bcmos_blk_pool_parm;
+
+/** Block memory pool statistics */
+typedef struct bcmos_blk_pool_stat
+{
+    uint32_t allocated;     /**< Number of blocks allocated */
+    uint32_t released;      /**< Number of blocks released */
+    uint32_t free;          /**< Number of free blocks in the pool */
+    uint32_t alloc_failed;  /**< Number of allocation failures */
+} bcmos_blk_pool_stat;
+
+/** Block memory pool info */
+typedef struct bcmos_blk_pool_info
+{
+    bcmos_blk_pool_parm parm;   /**< Pool parameters */
+    bcmos_blk_pool_stat stat;   /**< Pool statistics */
+} bcmos_blk_pool_info;
+
+/** Block memory pool control block */
+typedef struct bcmos_blk_pool bcmos_blk_pool;
+
+/** Create block memory pool
+ * \param[in,out]       pool    pool control block
+ * \param[in]           parm    pool parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_blk_pool_create(bcmos_blk_pool *pool, const bcmos_blk_pool_parm *parm);
+
+/** Destroy block memory pool
+ * \param[in]   pool    pool handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_blk_pool_destroy(bcmos_blk_pool *pool);
+
+/** Allocate block from block memory pool
+ *
+ * This allocates a single unit (unit_size bytes)
+ * \param[in]   pool    Pool handle
+ * \return memory block pointer or NULL.
+ * It is guaranteed that the returned pointer is aligned to pointer size
+ */
+void *bcmos_blk_pool_alloc(bcmos_blk_pool *pool);
+
+/** Allocate block from block memory pool and zero the block
+ *
+ * This allocates a single unit (unit_size bytes)
+ * \param[in]   pool    Pool handle
+ * \return memory block pointer or NULL.
+ * It is guaranteed that the returned pointer is aligned to pointer size
+ */
+void *bcmos_blk_pool_calloc(bcmos_blk_pool *pool);
+
+/** Release memory allocated using bcmos_blk_pool_alloc()
+ *
+ * \param[in]   ptr     pointer
+ */
+void bcmos_blk_pool_free(void *ptr);
+
+/** Release all blocks in memory pool. Block content is not affected
+ * This function is useful when application wants to pre-initialize
+ * some portion of each memory block at init time
+ *
+ * \param[in]   pool    Pool handle
+ */
+void bcmos_blk_pool_reset(bcmos_blk_pool *pool);
+
+/** Get pool info
+ *
+ * The pool must be created using bcmos_blk_pool_create()
+ * \param[in]   pool    Block memory pool handle
+ * \param[out]  info    Block memory pool info
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_blk_pool_query(const bcmos_blk_pool *pool, bcmos_blk_pool_info *info);
+
+/** Block pool iterator
+ * \param[in] prev      Previous block pool. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_blk_pool_get_next(const bcmos_blk_pool **prev);
+
+/** @} blk_pool */
+
+/** \defgroup byte_pool Byte Memory Pool
+ * \ingroup system_mem
+ * @{
+ */
+
+/** Byte memory pool parameters */
+typedef struct
+{
+    const char *name;   /**< Pool name */
+    uint32_t size;      /**< Pool size (bytes) */
+    void *start;        /**< Start address. Can be NULL */
+} bcmos_byte_pool_parm;
+
+/** Byte memory pool control block */
+typedef struct bcmos_byte_pool bcmos_byte_pool;
+
+/** Create byte memory pool
+ * \param[in,out]       pool    pool control block
+ * \param[in]           parm    pool parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_byte_pool_create(bcmos_byte_pool *pool, const bcmos_byte_pool_parm *parm);
+
+/** Destroy byte memory pool
+ * \param[in]   pool    pool handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_byte_pool_destroy(bcmos_byte_pool *pool);
+
+#ifndef BCMOS_BYTE_POOL_ALLOC_FREE_INLINE
+/** Allocate memory from byte memory pool
+ *
+ * This function can only be used with byte memory pools created
+ * with unit_size==1
+ * \param[in]   pool    Pool handle
+ * \param[in]   size    Block size (bytes)
+ * \return memory block pointer or NULL
+ */
+void *bcmos_byte_pool_alloc(bcmos_byte_pool *pool, uint32_t size);
+
+/** Release memory allocated using bcmos_pool_byte_alloc()
+ *
+ * \param[in]   ptr     pointer
+ */
+void bcmos_byte_pool_free(void *ptr);
+
+#endif /* BCMOS_BYTE_POOL_ALLOC_FREE_INLINE */
+
+/** @} byte_pool */
+
+/** @} system_mem */
+
+/** \addtogroup system_task
+ * @{
+ */
+#ifndef BCMOS_WAIT_FOREVER
+#define BCMOS_WAIT_FOREVER        0xFFFFFFFF  /**< Wait timeout. Wait forever */
+#endif
+#ifndef BCMOS_NO_WAIT
+#define BCMOS_NO_WAIT             0 /**< Wait timeout. Don't wait */
+#endif
+#define BCMOS_MICROSECONDS_IN_SECONDS   (1000000)
+
+/** Task priority */
+typedef enum
+{
+    BCMOS_TASK_PRIORITY_0, /**< Priority 0 - highest */
+    BCMOS_TASK_PRIORITY_1, /**< Priority 1 */
+    BCMOS_TASK_PRIORITY_2, /**< Priority 2 */
+    BCMOS_TASK_PRIORITY_3, /**< Priority 3 */
+    BCMOS_TASK_PRIORITY_4, /**< Priority 4 */
+    BCMOS_TASK_PRIORITY_5, /**< Priority 5 */
+    BCMOS_TASK_PRIORITY_6, /**< Priority 6 */
+    BCMOS_TASK_PRIORITY_7, /**< Priority 7 */
+    BCMOS_TASK_PRIORITY_8, /**< Priority 8 */
+    BCMOS_TASK_PRIORITY_9, /**< Priority 9 */
+    BCMOS_TASK_PRIORITY_10,/**< Priority 10 */
+    BCMOS_TASK_PRIORITY_11,/**< Priority 11 */
+    BCMOS_TASK_PRIORITY_12,/**< Priority 12 */
+    BCMOS_TASK_PRIORITY_13,/**< Priority 13 */
+    BCMOS_TASK_PRIORITY_14,/**< Priority 14 */
+    BCMOS_TASK_PRIORITY_15,/**< Priority 15 */
+    BCMOS_TASK_PRIORITY_16,/**< Priority 16 */
+    BCMOS_TASK_PRIORITY_17,/**< Priority 17 */
+    BCMOS_TASK_PRIORITY_18,/**< Priority 18 */
+    BCMOS_TASK_PRIORITY_19,/**< Priority 19 */
+    BCMOS_TASK_PRIORITY_20,/**< Priority 20 */
+    BCMOS_TASK_PRIORITY_21,/**< Priority 21 */
+    BCMOS_TASK_PRIORITY_22,/**< Priority 22 */
+    BCMOS_TASK_PRIORITY_23,/**< Priority 23 */
+    BCMOS_TASK_PRIORITY_24,/**< Priority 24 */
+    BCMOS_TASK_PRIORITY_25,/**< Priority 25 */
+    BCMOS_TASK_PRIORITY_26,/**< Priority 26 */
+    BCMOS_TASK_PRIORITY_27,/**< Priority 27 */
+    BCMOS_TASK_PRIORITY_28,/**< Priority 28 */
+    BCMOS_TASK_PRIORITY_29,/**< Priority 29 */
+    BCMOS_TASK_PRIORITY_30,/**< Priority 30 */
+    BCMOS_TASK_PRIORITY_31,/**< Priority 31 - lowest */
+} bcmos_task_priority;
+
+/** Task handler */
+typedef int (*F_bcmos_task_handler)(long data);
+
+/* Default task handler */
+extern int bcmos_dft_task_handler(long data);
+
+/* This flags determines whether a task is to be suspended upon OOPS condition. */
+#define BCMOS_TASK_FLAG_NO_SUSPEND_ON_OOPS (1 << 0)
+
+/** Task parameters */
+typedef struct
+{
+    const char *name;                   /**< Task name */
+    bcmos_task_priority priority;       /**< Task priority */
+    bcmos_core core;                    /**< CPU core the task is locked to */
+    uint32_t stack_size;                /**< Task stack size */
+    void *stack;                        /**< Stack location. NULL=allocate automatically */
+    F_bcmos_task_handler init_handler;  /**< Optional "init" handler. Called once in the task context when it is created.
+                                             This callback is only supported in integration mode (handler==NULL).
+                                             init_handler returns bcmos_errno. If it returns value other than BCM_ERR_OK,
+                                             the task is destroyed */
+    F_bcmos_task_handler handler;       /**< Task handler. NULL=default (integration mode) */
+    F_bcmos_task_handler timeout_handler;/**< This function is used only in integration mode (handler==NULL) if
+                                              msg_wait_timeout is > 0. It is called if there were no messages for the task
+                                              for longer than msg_wait_timeout us.
+                                              If timeout handler returns value other than BCM_ERR_OK, task terminates.
+                                        */
+    uint32_t msg_wait_timeout;          /**< This parameter is used only in integration mode (handler==NULL) together with
+                                             timeout_handler. If > 0 and there were no messages for longer than
+                                             msg_wait_timeout us, timeout_handler is called.
+                                        */
+    long data;                          /**< Data passed to the task handler */
+    uint32_t flags;                     /**< flags */
+} bcmos_task_parm;
+
+/** Task control block */
+typedef struct bcmos_task bcmos_task;
+
+/** Create a new task
+ *
+ * \param[in,out]  task    Task control block
+ * \param[in]      parm    Task parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_task_create(bcmos_task *task, const bcmos_task_parm *parm);
+
+/** Set task timeout
+ *
+ * This function is only used in integration mode (handler==NULL).
+ * It sets max time the default task handler waits for message directed to one of the
+ * task's modules.
+ *
+ * \param[in,out]  task                 Task control block
+ * \param[in]      timeout              Max time (us) to wait for messages. 0=FOREVER
+ *                                      Changing timeout from infinite to finite only takes effect
+ *                                      after message is received by any task module.
+ * \param[in]      timeout_handler      Handler to be called upon timeout. Must be != NULL if timeout > 0.
+ *                                      If the handler returns error (!= BCM_ERR_OK), task terminates.
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_task_timeout_set(bcmos_task *task, uint32_t timeout, F_bcmos_task_handler timeout_handler);
+
+/** Destroy task
+ *
+ * \param[in]   task            Task handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_task_destroy(bcmos_task *task);
+
+/** Get current task
+ * \returns task handle or NULL if not in task context
+ */
+bcmos_task *bcmos_task_current(void);
+
+/** Query task info
+ * \param[in]  task    Task control block
+ * \param[out] parm    Task parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_task_query(const bcmos_task *task, bcmos_task_parm *parm);
+
+/** Task iterator
+ * \param[in] prev      Previous task. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_task_get_next(bcmos_task **prev);
+
+
+/** @} system_task */
+
+/** \addtogroup system_msg
+ * @{
+ */
+
+/** Message header */
+typedef struct bcmos_msg bcmos_msg;
+
+/** Message queue control block */
+typedef struct bcmos_msg_queue bcmos_msg_queue;
+
+/** Message queue group control block */
+typedef struct bcmos_msg_qgroup bcmos_msg_qgroup;
+
+#if defined(BCMOS_MSG_QUEUE_DOMAIN_SOCKET) || defined(BCMOS_MSG_QUEUE_UDP_SOCKET) || defined(BCMOS_MSG_QUEUE_USER_DEFINED)
+#define BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+#endif
+
+/** Message queue endpoint type */
+typedef enum
+{
+    BCMOS_MSG_QUEUE_EP_LOCAL,           /**< Local endpoint (inter-thread communication) */
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+    BCMOS_MSG_QUEUE_EP_DOMAIN_SOCKET,   /**< Domain-socket based endpoint */
+#endif
+#ifdef BCMOS_MSG_QUEUE_UDP_SOCKET
+    BCMOS_MSG_QUEUE_EP_UDP_SOCKET,      /**< UDP socket-based endpoint */
+#endif
+#ifdef BCMOS_MSG_QUEUE_USER_DEFINED
+    BCMOS_MSG_QUEUE_EP_USER_DEFINED     /**< User-defined endpoint */
+#endif
+} bcmos_msg_queue_ep_type;
+
+
+/** Message queue parameters */
+typedef struct
+{
+    const char *name;           /**< Queue name (for logging and debugging) */
+    uint32_t size;              /**< Max queue size. 0=unlimited */
+    uint32_t high_wm;           /**< Optional high water mark. Log is generated when queue occupancy exceeds hwm */
+    uint32_t low_wm;            /**< Optional low water mark. Log is generated when queue occupancy drops below lwm */
+    uint32_t flags;             /**< TBD flags. For example, single-core, m-core */
+    void (*notify)(bcmos_msg_queue *q, const char *txt); /***< Called when queue congestion state changes */
+    bcmos_msg_queue_ep_type ep_type; /**< Queue endpoint type */
+
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    /* Remote message queue support allows queue endpoints to be located in
+     * different processes or even processors.
+     */
+    const char *local_ep_address;       /**< Queue local endpoint address */
+    const char *remote_ep_address;      /**< Queue local endpoint address */
+
+    uint32_t max_mtu;                   /**< Max MTU size */
+#define BCMOS_MSG_QUEUE_DEFAULT_MAX_MTU         (64*1024)
+
+    /** Optional "pack" callback. Not needed if 2 processes are on the same core. */
+    bcmos_errno (*pack)(bcmos_msg_queue *queue, bcmos_msg *msg, uint8_t **buf, uint32_t *buf_length);
+
+    /** Optional "unpack" callback. Not needed if 2 processes are on the same core. */
+    bcmos_errno (*unpack)(bcmos_msg_queue *queue, uint8_t *buf, uint32_t buf_length, bcmos_msg **msg);
+
+    /** Optional callback that releases packed buffer */
+    void (*free_packed)(bcmos_msg_queue *queue, uint8_t *buf);
+
+    /** Optional "open" callback. Must be set for user-defined queue, NULL otherwise */
+    bcmos_errno (*open)(bcmos_msg_queue *queue);
+
+    /** Optional "close" callback. Must be set for user-defined queue, NULL otherwise */
+    bcmos_errno (*close)(bcmos_msg_queue *queue);
+
+    /** Optional "send" callback. Must be set for user-defined queue, NULL otherwise */
+    bcmos_errno (*send)(bcmos_msg_queue *queue, uint8_t *buf, uint32_t buf_length);
+
+    /** Optional "recv" callback. Must be set for user-defined queue, NULL otherwise */
+    bcmos_errno (*recv)(bcmos_msg_queue *queue, uint32_t timeout, uint8_t **buf, uint32_t *buf_length);
+#endif
+
+} bcmos_msg_queue_parm;
+
+/** Message queue statistics */
+typedef struct
+{
+    uint32_t msg_in;            /**< Number of messages currently in the queue */
+    uint32_t msg_sent;          /**< Number of messages successfully submitted into the queue */
+    uint32_t msg_received;      /**< Number of messages received from the queue */
+    uint32_t msg_discarded;     /**< Number of messages discarded because of queue overflow */
+    uint32_t msg_almost_full;   /**< Number of messages submitted to queue when it was above high water mark */
+    bcmos_bool is_congested;    /**< True=the queue is currently congested */
+} bcmos_msg_queue_stat;
+
+/** Message queue info */
+typedef struct
+{
+    bcmos_msg_queue_parm parm;    /**< Queue parameters */
+    bcmos_msg_queue_stat stat;    /**< Queue statistics */
+} bcmos_msg_queue_info;
+
+/** Message priority in queue group */
+typedef uint32_t bcmos_qgroup_prty;
+
+/** Message queue group parameters */
+typedef struct
+{
+    const char *name;           /**< Queue group name (for logging and debugging) */
+    bcmos_qgroup_prty nqueues;  /**< Number of queues in the group */
+    uint32_t size;              /**< Total number of messages that can be stored in queue group. 0=unlimited */
+    uint32_t high_wm;           /**< Optional high water mark. Log is generated when queue occupancy exceeds hwm */
+    uint32_t low_wm;            /**< Optional low water mark. Log is generated when queue occupancy drops below lwm */
+    uint32_t flags;             /**< TBD flags. For example, single-core, m-core */
+    void (*notify)(bcmos_msg_qgroup *qgrp, const char *txt); /***< Called when queue group congestion state changes */
+} bcmos_msg_qgroup_parm;
+
+/** Message queue group info */
+typedef struct
+{
+    bcmos_msg_qgroup_parm parm; /**< Queue group parameters */
+    bcmos_msg_queue_stat  stat; /**< Queue group statistics */
+} bcmos_msg_qgroup_info;
+
+/** Message recipient instance (e.g., optical link id) */
+typedef uint16_t bcmos_msg_instance;
+
+/** Message send flags */
+typedef enum
+{
+    BCMOS_MSG_SEND_AUTO_FREE = 0x00000000,      /**< Automatically release message in case of error. This is the default behaviour */
+    BCMOS_MSG_SEND_NO_FREE_ON_ERROR =0x00000001,/**< Do NOT free message in case of transmit error */
+    BCMOS_MSG_SEND_URGENT    = 0x00000002,      /**< Urgent message */
+    BCMOS_MSG_SEND_NOLIMIT   = 0x00000004,      /**< Ignore destination queue size limit */
+} bcmos_msg_send_flags;
+
+/** Registered message handler */
+typedef void (*F_bcmos_msg_handler)(bcmos_module_id module_id, bcmos_msg *msg);
+typedef bcmos_errno (*F_bcmos_module_init)(long data);
+typedef void (*F_bcmos_module_exit)(long data);
+
+/** Message header */
+struct bcmos_msg
+{
+    bcmos_msg_id   type;        /**< Message type */
+    bcmos_msg_instance instance;/**< Message recipient instance (e.g., optical link id) */
+    F_bcmos_msg_handler handler;/**< Message handler. Can be set by the sender or message dispatcher */
+    bcmos_module_id sender;     /**< Sender module */
+    STAILQ_ENTRY(bcmos_msg) next; /**< Next message pointer */
+    void *data;                 /**< Message data pointer */
+    void *start;                /**< Message data block start (for release) */
+    uint32_t size;              /**< Message data size */
+    bcmos_msg_send_flags send_flags;    /**< Flags the message was sent with */
+#define BCMOS_MSG_QUEUE_SIZE_UNLIMITED    0xFFFFFFFF      /**< Unlimited queue */
+    void (*release)(bcmos_msg *);       /**< Release callback */
+    void (*data_release)(bcmos_msg *);  /**< Data release callback. Used when message is released to message pool */
+};
+
+/* Helper functions that pack / unpack message header for IPC */
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+
+/** Size of message header on the line for IPC */
+#define BCMOS_MSG_HDR_SIZE      8
+
+void bcmos_msg_hdr_pack(const bcmos_msg *msg, uint8_t *buf, uint32_t data_size);
+void bcmos_msg_hdr_unpack(const uint8_t *buf, bcmos_msg *msg);
+
+#endif
+
+/** Create message queue.
+ *
+ * This function can be called explicitly in "traditional" mode
+ * or implicitly by bcmos_module_create().
+ * \param[in,out]  queue        Queue control block
+ * \param[in]      parm         Queue parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_queue_create(bcmos_msg_queue *queue, const bcmos_msg_queue_parm *parm);
+
+/** Destroy queue
+ *
+ * \param[in]   queue           Queue handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_queue_destroy(bcmos_msg_queue *queue);
+
+/** Get queue info
+ *
+ * \param[in]   queue           Queue handle
+ * \param[out]  info            Queue information
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_queue_query(const bcmos_msg_queue *queue, bcmos_msg_queue_info *info);
+
+/** Message queue iterator
+ * \param[in] prev      Previous queue. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_msg_queue_get_next(const bcmos_msg_queue **prev);
+
+/** Create message queue group.
+ *
+ * Queue group contains configurable number of queues. The queues are drained
+ * in strict priority. Priority 0 is the highest.
+ *
+ * \param[in,out]  qgroup       Queue group control block
+ * \param[in]      parm         Queue group parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_qgroup_create(bcmos_msg_qgroup *qgroup, const bcmos_msg_qgroup_parm *parm);
+
+/** Destroy queue group
+ *
+ * \param[in]   qgroup       Queue group handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_qgroup_destroy(bcmos_msg_qgroup *qgroup);
+
+/** Get queue group info
+ *
+ * \param[in]   qgroup       Queue group handle
+ * \param[out]  info         Queue group information
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_qgroup_query(const bcmos_msg_qgroup *qgroup, bcmos_msg_qgroup_info *info);
+
+/** Message queue group iterator
+ * \param[in] prev      Previous queue group. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_msg_qgroup_get_next(const bcmos_msg_qgroup **prev);
+
+/** Send message to queue
+ *
+ * \param[in]   queue           Queue handle
+ * \param[in]   msg             Message
+ * \param[in]   flags           flags. Combination of \ref bcmos_msg_send_flags bits
+ *
+ * msg is released automatically regardless of bcmos_msg_send() outcome, unless
+ * BCMOS_MSG_SEND_NO_FREE_ON_ERROR flag is set.
+ *
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_send(bcmos_msg_queue *queue, bcmos_msg *msg, bcmos_msg_send_flags flags);
+
+/** Send message to module
+ *
+ * For module to be able to receive the message, it must be registered
+ * using bcmos_msg_register()
+ *
+ * \param[in]   module_id       Module id
+ * \param[in]   msg             Message. msg->handler must be set
+ * \param[in]   flags           flags. Combination of \ref bcmos_msg_send_flags bits
+ *
+ * msg is released automatically regardless of bcmos_msg_send_to_module() outcome, unless
+ * BCMOS_MSG_SEND_NO_FREE_ON_ERROR flag is set.
+ *
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_send_to_module(bcmos_module_id module_id, bcmos_msg *msg, bcmos_msg_send_flags flags);
+
+/** Send message to queue group
+ *
+ * \param[in]   qgroup          Queue group handle
+ * \param[in]   msg             Message
+ * \param[in]   prty            Message priority in range 0-nqueues_in_group-1.
+ *                              0 priority is the highest. If MAX number of messages are already queues
+ *                              in the queue group, sending message can leave to discard of the head message
+ *                              queued at lower priority
+ * \param[in]   flags           BCMOS_MSG_SEND_AUTO_FREE or BCMOS_MSG_SEND_NO_FREE_ON_ERROR flag
+ *
+ *
+ * msg is released automatically regardless of bcmos_msg_send_to_qgroup() outcome, unless
+ * BCMOS_MSG_SEND_NO_FREE_ON_ERROR flag is set.
+ *
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_send_to_qgroup(bcmos_msg_qgroup *qgroup, bcmos_msg *msg, bcmos_qgroup_prty prty,
+    bcmos_msg_send_flags flags);
+
+/** Get message from the head of message queue
+ *
+ * The function can lead to the calling task being suspended for a period
+ * of time or indefinitely, until message is submitted to the queue.\n
+ * The function is only used in "traditional tasks" (see \ref system_model).
+ *
+ * \param[in]   queue           Queue handle
+ * \param[in]   timeout         timeout. can be 0, time in us or \ref BCMOS_WAIT_FOREVER
+ * \param[out]  msg             Message handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_recv(bcmos_msg_queue *queue, uint32_t timeout, bcmos_msg **msg);
+
+/** Get highest priority message from queue group
+ *
+ * The function can lead to the calling task being suspended for a period
+ * of time or indefinitely, until message is submitted to the queue group.\n
+ * The function is only used in "traditional tasks" (see \ref system_model).
+ *
+ * \param[in]   qgroup          Queue group handle
+ * \param[in]   timeout         timeout. can be 0, time in us or \ref BCMOS_WAIT_FOREVER
+ * \param[out]  msg             Message handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_recv_from_qgroup(bcmos_msg_qgroup *qgroup, uint32_t timeout, bcmos_msg **msg);
+
+/** Dispatch message. Send to module that registered for it.
+ *
+ * The message must be registered using bcmos_msg_register()
+ *
+ * This function should be used if the message sender doesn't know the target module and/or
+ * message handling callback.
+ *
+ * \param[in]   msg             Message handle
+ * \param[in]   flags           flags. Combination of \ref bcmos_msg_send_flags bits
+ *
+ * msg is released automatically regardless of bcmos_msg_dispatch() outcome, unless
+ * BCMOS_MSG_SEND_NO_FREE_ON_ERROR flag is set.
+ *
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_dispatch(bcmos_msg *msg, bcmos_msg_send_flags flags);
+
+/** Register message for "push-mode" delivery.
+ *
+ * When registered message is sent to the target module and
+ * the module's task wakes up, message handler is called in the module's context.
+ *
+ * \param[in]   msg_type        Message type
+ * \param[in]   instance        Message type instance
+ * \param[in]   module_id       Target module id
+ * \param[in]   handler         Message handler
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_register(bcmos_msg_id msg_type, bcmos_msg_instance instance,
+    bcmos_module_id module_id, F_bcmos_msg_handler handler);
+
+/** Un-register message registered by bcmos_msg_register()
+ *
+ * \param[in]   msg_type        Message type
+ * \param[in]   instance        Message type instance
+ * \param[in]   module_id       Target module id
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_unregister(bcmos_msg_id msg_type, bcmos_msg_instance instance,
+    bcmos_module_id module_id);
+
+/** Put the OS message infrastructure in "shutdown mode".
+ *
+ * When in shutdown mode, bcmos_msg_dispatch() will return BCM_ERR_OK instead of BCM_ERR_NOENT when a handler is not
+ * found for the message. Additionally, bcmos_msg_dispatch() becomes safe to call concurrently with
+ * bcmos_msg_unregister() (this is not true in normal operation).
+ *
+ * \param[in]   shutdown_mode   Whether or not to enable shutdown mode
+ */
+void bcmos_msg_shutdown_mode_set(bcmos_bool shutdown_mode);
+
+/** Gets whether or not the OS message infrastructure is currently in "shutdown mode".
+ * \returns BCMOS_TRUE if we are in shutdown mode, BCMOS_FALSE otherwise
+ */
+bcmos_bool bcmos_msg_shutdown_mode_get(void);
+
+/** Helper type for storing message types alongside their handlers. */
+typedef struct
+{
+    bcmos_msg_id msg_type;
+    F_bcmos_msg_handler handler;
+} bcmos_msg_id2handler;
+
+/** Message pool */
+typedef struct bcmos_msg_pool bcmos_msg_pool;
+
+/** Message pool parameters */
+typedef struct bcmos_msg_pool_parm
+{
+    const char *name;           /**< Pool name */
+    uint32_t size;              /**< Number of messages in the pool */
+    uint32_t data_size;         /**< Message data size */
+    uint32_t flags;             /**< TBD flags */
+    void (*data_release)(bcmos_msg *msg); /**< Optional data release callback. Called when message is released to the pool */
+} bcmos_msg_pool_parm;
+
+/** Message pool statistics */
+typedef bcmos_blk_pool_stat bcmos_msg_pool_stat;
+
+/** Message pool info */
+typedef struct bcmos_msg_pool_info
+{
+    bcmos_msg_pool_parm parm;   /**< Pool parameters */
+    bcmos_msg_pool_stat stat;   /**< Pool statistics */
+} bcmos_msg_pool_info;
+
+/** Create message pool
+ *
+ * Create pool containing pre-allocated messages with specified data size
+ * \param[in]   pool    Message pool handle
+ * \param[in]   parm    Message pool parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_pool_create(bcmos_msg_pool *pool, const bcmos_msg_pool_parm *parm);
+
+/** Destroy message pool
+ *
+ * All messages must be released to the pool before it can be destroyed.
+ *
+ * \param[in]   pool    Message pool handle
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_pool_destroy(bcmos_msg_pool *pool);
+
+/** Allocate message from pool
+ *
+ * The pool must be created using bcmos_pool_create()
+ * \param[in]   pool    Message pool handle
+ * \returns     msg pointer or NULL if the pool is empty.
+ * "data" and "release" fields in the returned message are pre-set
+ * Once no longer needed, the message must be released using bcmos_msg_free()
+ */
+bcmos_msg *bcmos_msg_pool_alloc(bcmos_msg_pool *pool);
+
+/** Allocate message from pool and clear data
+ *
+ * The pool must be created using bcmos_pool_create()
+ * \param[in]   pool    Message pool handle
+ * \returns     msg pointer or NULL if the pool is empty.
+ * "data" and "release" fields in the returned message are pre-set
+ * Once no longer needed, the message must be released using bcmos_msg_free()
+ */
+static inline bcmos_msg *bcmos_msg_pool_calloc(bcmos_msg_pool *pool)
+{
+    bcmos_msg *msg = bcmos_msg_pool_alloc(pool);
+    if (msg)
+    {
+        memset(msg->data, 0, msg->size);
+    }
+    return msg;
+}
+
+/** Get pool info
+ *
+ * The pool must be created using bcmos_pool_create()
+ * \param[in]   pool    Message pool handle
+ * \param[out]  info    Message pool info
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_msg_pool_query(const bcmos_msg_pool *pool, bcmos_msg_pool_info *info);
+
+/** Message pool iterator
+ * \param[in] prev      Previous message pool. *prev==NULL - get first
+ * \return: BCM_ERR_OK, BCM_ERR_NOENT, BCM_ERR_NO_MORE
+ */
+bcmos_errno bcmos_msg_pool_get_next(const bcmos_msg_pool **prev);
+
+/** @} system_msg */
+
+/** \addtogroup system_module
+ * @{
+ */
+
+/** Max number of modules per task. Must be <= 32 */
+#define BCMOS_MAX_MODULES_PER_TASK        8
+
+/** Module parameters */
+typedef struct
+{
+    bcmos_msg_queue_parm qparm;  /**< Message queue paramaters */
+    F_bcmos_module_init init;    /**< Init callback */
+    F_bcmos_module_exit exit;    /**< Exit callback */
+    long data;                   /**< Module context initial value. Also passed to init and exit callbacks */
+} bcmos_module_parm;
+
+/** Module control block */
+typedef struct bcmos_module bcmos_module;
+
+/** Register module
+ *
+ * \param[in]   module_id       Module id
+ * \param[in]   task            Owner task ID
+ * \param[in]   parm            Module parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_module_create(bcmos_module_id module_id, bcmos_task *task, bcmos_module_parm *parm);
+
+/** Un-register module
+ *
+ * \param[in]   module_id       Module id
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_module_destroy(bcmos_module_id module_id);
+
+/** Get current module id in the current task
+ *
+ * \returns module_id
+ */
+bcmos_module_id bcmos_module_current(void);
+
+/** Get module context
+ *
+ * Module context is initialized as module_parm.data and can be modified using
+ * bcmos_module_context_set()
+ *
+ * \param[in]   module_id       Module_id
+ * \returns context pointer set by bcmos_module_context_set() or
+ *
+ * NULL if module_id is invalid or context is not set.
+ */
+void *bcmos_module_context(bcmos_module_id module_id);
+
+/** Set module context
+ *
+ * Context is an arbitrary structure used to store module-specific data.
+ * Usually this function is called from module init() callback
+ *
+ * \param[in]   module_id       Module_id
+ * \param[in]   context         Module context pointer
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_module_context_set(bcmos_module_id module_id, void *context);
+
+/* module control blocks */
+extern bcmos_module *bcmos_modules[BCMOS_MODULE_ID__NUM_OF];
+
+static inline bcmos_module *_bcmos_module_get(bcmos_module_id module_id)
+{
+    bcmos_module *module = bcmos_modules[module_id];
+    if ((unsigned)module_id >= BCMOS_MODULE_ID__NUM_OF)
+        return NULL;
+    return module;
+}
+
+/** Query module
+ *
+ * \param[in]   module_id       Module_id
+ * \param[out]  task            Task that owns the module
+ * \param[out]  info            Module queue info
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_module_query(bcmos_module_id module_id, const bcmos_task **task, bcmos_msg_queue_info *info);
+
+/** @} system_module */
+
+/** \addtogroup system_event
+ * @{
+ */
+
+/** Registered event handler */
+typedef void (*F_bcmos_event_handler)(bcmos_event_id event_id, uint32_t active_bits);
+
+/** Event parameters */
+typedef struct
+{
+    const char *name;                   /**< Event set name */
+    bcmos_module_id module_id;          /**< Module id. The module must be registered */
+    uint32_t mask;                      /**< Event bits module is interested in */
+    F_bcmos_event_handler handler;      /**< Event handler. Called in module's context */
+    uint32_t flags;                     /**< TBD flags. E.g., inter-core */
+} bcmos_event_parm;
+
+/** Event control block */
+typedef struct bcmos_event bcmos_event;
+
+/** Create event set
+ *
+ * \param[in]   event_id        Event set id
+ * \param[in]   parm            Event parameters. Used in "integration" mode. NULL in "traditional" mode
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_event_create(bcmos_event_id event_id, bcmos_event_parm *parm);
+
+/** Destroy event set created by bcmos_event_create()
+ *
+ * \param[in]   event_id        Event set id
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_event_destroy(bcmos_event_id event_id);
+
+/** Raise event
+ *
+ * Raised event is delivered to module(s) that registered for it
+ * using bcmos_event_register() or to the task waiting for event
+ * using bcmos_event_recv()
+ *
+ * \param[in]   event_id        Event set id
+ * \param[in]   active_bits     Active bit mask
+ * \returns 0=OK or error code <0. Can only fail if event is not registered
+ */
+bcmos_errno bcmos_event_raise(bcmos_event_id event_id, uint32_t active_bits);
+
+/** Wait for event
+ *
+ * This function is used in "traditional" mode.\n
+ * The caller can block for a time or indefinitely
+ *
+ * \param[in]   event_id        Event set id
+ * \param[in]   mask            Interesting bits. The functions returns when
+ *                              - timeout expires
+ *                              - event with (active_bits & mask) != 0 is raised
+ * \param[in]   timeout         timeout. can be 0, time in us or \ref BCMOS_WAIT_FOREVER
+ * \param[out]  active_bits     active bits in the event set. valid only if the function returns 0
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_event_recv(bcmos_event_id event_id, uint32_t mask,
+    uint32_t timeout, uint32_t *active_bits);
+
+/* Event set array */
+extern bcmos_event *bcmos_events[BCMOS_EVENT_ID__NUM_OF];
+
+/* Get event givern the event id */
+static inline bcmos_event *_bcmos_event_get(bcmos_event_id event_id)
+{
+    bcmos_event *ev = bcmos_events[event_id];
+    if ((unsigned)event_id >= BCMOS_EVENT_ID__NUM_OF)
+        return NULL;
+    return ev;
+}
+
+/** @} system_event */
+
+/** \addtogroup system_timer
+ * @{
+ */
+
+/** Max timer duration (us) */
+#define BCMOS_MAX_TIMER_DURATION   0x80000000
+
+/** Timer control block */
+typedef struct bcmos_timer bcmos_timer;
+
+/** Timer handler completion code */
+typedef enum
+{
+    BCMOS_TIMER_OK,             /**< Restart timer if periodic or keep stopped if not */
+    BCMOS_TIMER_STOP            /**< Do not restart periodic timer */
+} bcmos_timer_rc;
+
+/** Timer handler
+ * \param[in]   timer   Expired timer handle
+ * \param[in]   data    User data supplied at timer creation time
+ * \returns \ref bcmos_timer_rc
+ */
+typedef bcmos_timer_rc (*F_bcmos_timer_handler)(bcmos_timer *timer, long data);
+
+typedef enum
+{
+    BCMOS_TIMER_PARM_FLAGS_URGENT     = 0,       /**< Default behavior. If the timer owner is set, timer expiration
+                                                      will be delivered as an urgent message. */
+    BCMOS_TIMER_PARM_FLAGS_NON_URGENT = 1 << 0,  /**< If the timer owner is set, timer expiration will be delivered as
+                                                      a normal (non-urgent) message. */
+} bcmos_timer_parm_flags;
+
+/** Timer parameters */
+typedef struct
+{
+    const char *name;                   /**< Timer name */
+    bcmos_module_id owner;              /**< Timer owner. If set, timer expiration is delivered to the module
+                                             as a message */
+    bcmos_bool periodic;                /**< TRUE=periodic */
+    F_bcmos_timer_handler handler;      /**< Timer handler. Called in context of owner module
+                                             if set or timer ISR if owner==BCMOS_MODULE_ID_NONE */
+    long data;                          /**< data to pass to the handler */
+    bcmos_timer_parm_flags flags;       /**< Flags to change the behavior of the timer */
+} bcmos_timer_parm;
+
+#ifndef BCMOS_TIMESTAMP_INLINE
+
+/** Get current timestamp
+ * \returns the current system timestamp (us)
+ */
+uint32_t bcmos_timestamp(void);
+
+/** Get current 64 bit timestamp
+ * \returns the current system timestamp (us)
+ * \note There is no guarantee that all 64 bit carry information.
+ *       However, it is guaranteed that the timestamp wraps around
+ *       not oftener than every 50 days (ms resolution)
+ */
+uint64_t bcmos_timestamp64(void);
+
+#endif /* #ifndef BCMOS_TIMESTAMP_INLINE */
+
+/** Create timer
+ *
+ * \param[in,out]       timer   timer control block
+ * \param[in]           parm    timer parameters
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_timer_create(bcmos_timer *timer, bcmos_timer_parm *parm);
+
+/** Destroy timer
+ * The timer is stopped if running and destroyed
+ * \param[in]   timer   timer handle
+ */
+void bcmos_timer_destroy(bcmos_timer *timer);
+
+/** Set timer handler
+ *
+ * \param[in,out]       timer   timer control block
+ * \param[in]           handler timer handler
+ * \param[in]           data    data to be passed to the handler
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_timer_handler_set(bcmos_timer *timer, F_bcmos_timer_handler handler, long data);
+
+/** (Re)start timer
+ * Stop timer if running and start it.
+ *
+ * \param[in]   timer   timer handle
+ * \param[in]   delay   delay in us
+ */
+void bcmos_timer_start(bcmos_timer *timer, uint32_t delay);
+
+/** Stop timer if running
+ *
+ * \param[in]   timer   timer handle
+ */
+void bcmos_timer_stop(bcmos_timer *timer);
+
+/** Suspend current task for a time
+ *
+ * \param[in]   us      sleep time (us)
+ */
+#ifndef BCMOS_USLEEP_INLINE
+void bcmos_usleep(uint32_t us);
+#endif /* #ifndef BCMOS_USLEEP_INLINE */
+
+/** @} system_timer */
+
+/** \addtogroup system_fastlock
+ * @{
+ */
+
+/** Fast lock control block */
+typedef struct bcmos_fastlock bcmos_fastlock;
+
+#ifndef BCMOS_FASTLOCK_INLINE
+
+/** Init fastlock
+ * \param[in, out]      lock    fast lock control block
+ * \param[in]           flags   flags - TBD. E.g., single core / SMP
+ */
+void bcmos_fastlock_init(bcmos_fastlock *lock, uint32_t flags);
+
+/** Take fast lock
+ * \param[in]   lock    fast lock
+ * \returns value of interrupt flags that should be used in unlock
+ */
+long bcmos_fastlock_lock(bcmos_fastlock *lock);
+
+/** Release fast lock
+ * \param[in]   lock    fast lock
+ * \param[in]   flags   interrupt flags
+ */
+void bcmos_fastlock_unlock(bcmos_fastlock *lock, long flags);
+
+#endif /* #ifndef BCMOS_FASTLOCK_INLINE */
+
+/** @} system_fastlock */
+
+/** \addtogroup system_mutex
+ * @{
+ */
+
+/** Mutex control block */
+typedef struct bcmos_mutex bcmos_mutex;
+
+#ifdef BCMOS_MUTEX_INLINE
+#define BCMOS_MUTEX_CREATE_DESTROY_INLINE
+#define BCMOS_MUTEX_LOCK_UNLOCK_INLINE
+#endif
+
+#ifndef BCMOS_MUTEX_CREATE_DESTROY_INLINE
+
+/** Create recursive mutex
+ * \param[in, out]      mutex   Mutex control block
+ * \param[in]           flags   flags - TBD. E.g., single core / SMP
+ * \param[in]           name name of the mutex (if OS supports), NULL means it will be auto-generated
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_mutex_create(bcmos_mutex *mutex, uint32_t flags, const char *name);
+
+/** Destroy mutex
+ * \param[in]   mutex   Mutex control block
+ */
+void bcmos_mutex_destroy(bcmos_mutex *mutex);
+
+#endif /* BCMOS_MUTEX_CREATE_DESTROY_INLINE */
+
+
+#ifndef BCMOS_MUTEX_LOCK_UNLOCK_INLINE
+
+/** Lock mutex
+ * \param[in]   mutex   Mutex control block
+ */
+void bcmos_mutex_lock(bcmos_mutex *mutex);
+
+/** Release mutex
+ * \param[in]   mutex   Mutex control block
+ */
+void bcmos_mutex_unlock(bcmos_mutex *mutex);
+
+#endif /* #ifndef BCMOS_MUTEX_LOCK_UNLOCK_INLINE */
+
+/** @} system_mutex */
+
+/** \addtogroup system_sem
+ * @{
+ */
+
+/** Semaphore control block */
+typedef struct bcmos_sem bcmos_sem;
+
+#ifdef BCMOS_SEM_INLINE
+#define BCMOS_SEM_CREATE_DESTROY_INLINE
+#define BCMOS_SEM_WAIT_INLINE
+#define BCMOS_SEM_POST_INLINE
+#endif
+
+#ifndef BCMOS_SEM_CREATE_DESTROY_INLINE
+
+/** Create semaphore
+ * \param[in, out]    sem   semaphore control block
+ * \param[in]         count initial value of semaphore counter
+ * \param[in]         flags flags - TBD. E.g., single core / SMP
+ * \param[in]         name name of the semaphore (if OS supports), NULL means it will be auto-generated
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_sem_create(bcmos_sem *sem, uint32_t count, uint32_t flags, const char *name);
+
+/** Destroy semaphore
+ * \param[in]   sem   semaphore control block
+ */
+void bcmos_sem_destroy(bcmos_sem *sem);
+
+#endif /* BCMOS_SEM_CREATE_DESTROY_INLINE */
+
+#ifndef BCMOS_SEM_WAIT_INLINE
+
+/** Decrement semaphore counter. Wait if the counter is 0
+ *
+ * \param[in]   sem     semaphore control block
+ * \param[in]   timeout timeout. can be 0, time in us or \ref BCMOS_WAIT_FOREVER
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout);
+
+#endif /* #ifndef BCMOS_SEM_WAIT_INLINE */
+
+#ifndef BCMOS_SEM_POST_INLINE
+/** Increment semaphore counter
+ * \param[in]   sem   semaphore control block
+ */
+void bcmos_sem_post(bcmos_sem *sem);
+
+#endif /* #ifndef BCMOS_SEM_POST_INLINE */
+
+/** @} system_sem */
+
+/*
+ * print support
+ */
+
+/** Print cloning/redirection mode */
+typedef enum
+{
+    BCMOS_PRINT_REDIRECT_MODE_NONE,     /**< No cloning, redirection */
+    BCMOS_PRINT_REDIRECT_MODE_REDIRECT, /**< Redirect console output. Do not print on the serial console */
+    BCMOS_PRINT_REDIRECT_MODE_CLONE     /**< Clone console output to redirection callback */
+} bcmos_print_redirect_mode;
+
+/** Print re-direction/cloning callback */
+typedef int (*bcmos_print_redirect_cb)(void *data, const char *format, va_list ap);
+
+/** Set up print redirection/cloning
+ * \param[in]   mode    redirection/cloning mode
+ * \param[in]   cb      redirection callback
+ * \param[in]   data    opaque data to be passed to cb
+ * \returns 0=OK or error <0
+ */
+bcmos_errno bcmos_print_redirect(bcmos_print_redirect_mode mode, bcmos_print_redirect_cb cb, void *data);
+
+/* Print on the console with optional cloning / redirection
+ * \param[in]   format  printf format
+ * \param[in]   ap      argument list
+ * \returns number of characters printed >= 0 or error < 0
+ */
+int bcmos_vprintf(const char *format, va_list ap);
+
+/* Print on the console with optional cloning / redirection
+ * \param[in]   format  printf format
+ * \returns number of characters printed >= 0 or error < 0
+ */
+int bcmos_printf(const char *format, ...);
+
+
+/** \addtogroup system_trace
+ * @{
+ */
+
+/** Trace level */
+typedef enum
+{
+    BCMOS_TRACE_LEVEL_NONE,     /**< No trace output */
+    BCMOS_TRACE_LEVEL_ERROR,    /**< Trace errors */
+    BCMOS_TRACE_LEVEL_WARNING,  /**< Trace errors + warnings */
+    BCMOS_TRACE_LEVEL_INFO,     /**< Trace errors + warnings + info */
+    BCMOS_TRACE_LEVEL_VERBOSE,  /**< Trace errors + warnings + info + verbose info */
+    BCMOS_TRACE_LEVEL_DEBUG,    /**< Trace everything */
+} bcmos_trace_level;
+
+extern bcmos_trace_level bcmos_sys_trace_level;
+
+#ifdef BCMOS_TRACE_PRINTF
+#define BCMOS_TRACE_INLINE
+#endif
+
+#ifndef BCMOS_TRACE_INLINE
+/** Print trace
+ *
+ * \param[in]   level           Record trace at level
+ * \param[in]   format          printf-like format
+ */
+void bcmos_trace(bcmos_trace_level level, const char *format, ...);
+#endif
+
+
+/* Print trace */
+#ifdef BCMOS_TRACE_PRINTF
+#define bcmos_trace(level, fmt, args...)  bcmos_printf(fmt, ## args)
+#endif
+
+/** Set current trace level
+ * \param[in]   level           New trace level
+ * \returns old trace level
+ */
+static inline bcmos_trace_level bcmos_trace_level_set(bcmos_trace_level level)
+{
+    bcmos_trace_level old_level = bcmos_sys_trace_level;
+    bcmos_sys_trace_level = level;
+    return old_level;
+}
+
+/** Get current trace level
+ * \returns trace level
+ */
+static inline bcmos_trace_level bcmos_trace_level_get(void)
+{
+    return bcmos_sys_trace_level;
+}
+
+/** Print trace conditionally, depending on the current trace level
+ * \param[in]   level   Record trace at level
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ */
+#define BCMOS_TRACE(level, fmt, args...) \
+    do \
+    { \
+        if (level <= bcmos_sys_trace_level) \
+            bcmos_trace(level, "%s#%d> " fmt, __FUNCTION__, __LINE__, ## args); \
+    } while (0)
+
+/** Print error trace conditionally, depending on the current trace level
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ */
+
+extern f_bcmolt_sw_error_handler sw_error_handler;
+
+#define BCMOS_TRACE_ERR(fmt, args...) \
+    do \
+    { \
+        BCMOS_TRACE(BCMOS_TRACE_LEVEL_ERROR, "ERR: " fmt, ## args); \
+        if (sw_error_handler != NULL) \
+        { \
+            sw_error_handler(0xff, __FILE__, __LINE__); \
+        } \
+        _bcmos_backtrace(); \
+   } while (0)
+
+
+/** Print info trace conditionally, depending on the current trace level
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ */
+#define BCMOS_TRACE_INFO(fmt, args...)          \
+    BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "INF: " fmt, ## args)
+
+/** Print verbose info trace conditionally, depending on the current trace level
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ */
+#define BCMOS_TRACE_VERBOSE(fmt, args...)      \
+    BCMOS_TRACE(BCMOS_TRACE_LEVEL_VERBOSE, "VRB: " fmt, ## args)
+
+/** Print debug trace conditionally, depending on the current trace level
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ */
+#define BCMOS_TRACE_DEBUG(fmt, args...)        \
+    BCMOS_TRACE(BCMOS_TRACE_LEVEL_DEBUG, "DBG: " fmt, ## args)
+
+/** Print trace conditionally based on return code and return
+ * \param[in]   rc      return code
+ * \param[in]   fmt     printf-like format
+ * \param[in]   args    printf-like arguments
+ * \returns rc
+ */
+#define BCMOS_TRACE_RETURN(rc, fmt, args...)    \
+    do {                                        \
+        if (rc)                                 \
+            BCMOS_TRACE_ERR("status:%s :" fmt, bcmos_strerror(rc), ## args); \
+        else                                    \
+            BCMOS_TRACE_INFO("success: " fmt, ## args); \
+        return rc;                              \
+    } while (0)
+
+#define BCMOS_TRACE_CHECK_RETURN(cond,rc,fmt,args...)    \
+    do {                                        \
+        if (cond)                                 \
+        {\
+            BCMOS_TRACE_ERR( #cond ": status:%s :" fmt, bcmos_strerror(rc), ## args); \
+            return rc;                              \
+        }\
+    } while (0)
+#define BCMOS_CHECK_RETURN(cond,err,ret)    \
+    do {                                        \
+        if (cond)                                 \
+        {\
+            BCMOS_TRACE_ERR( #cond ": status:%s\n", bcmos_strerror(err)); \
+            return ret;                              \
+        }\
+    } while (0)
+#define BCMOS_CHECK_RETURN_ERROR(cond,err) BCMOS_CHECK_RETURN(cond,err,err)
+#define BCMOS_RETURN_ON_ERROR(err) BCMOS_CHECK_RETURN(BCM_ERR_OK != err, err, /*this space intentionally left blank*/)
+#define BCMOS_RETURN_IF_ERROR(err) BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err)
+
+/** @} system_trace */
+
+/*
+ * Low level services
+ */
+
+/** \addtogroup system_buf
+ * @{
+ */
+
+/** Transport/network buffer */
+typedef struct bcmos_buf bcmos_buf;
+
+/** @} system_buf */
+
+/** Round a number up to the specified power of 2 */
+#define BCMOS_ROUND_UP(n, m) (((n) + (m) - 1) & ~((m) - 1))
+
+/** Round a number up to the nearest word multiple */
+#define BCMOS_ROUND_TO_WORD(n) BCMOS_ROUND_UP(n, sizeof(size_t))
+
+/* BCMOS_DIVIDE_ROUND_UP(integer_dividend / integer_divisor) == (integer_dividend + integer_divisor - 1) / integer_divisor */
+#define BCMOS_DIVIDE_ROUND_UP(n, m) (((n) + (m) - 1) / (m))
+
+#endif /* BCMOS_SYSTEM_COMMON_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_common2.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common2.h
new file mode 100644
index 0000000..7317aac
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_common2.h
@@ -0,0 +1,676 @@
+/*
+<: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 BCMOS_COMMON2_H_
+#define BCMOS_COMMON2_H_
+
+#ifndef BCMOS_SYSTEM_H_
+#error Please do not include bcmos_common2.h directly. Include bcmos_system.h
+#endif
+
+#include "bcmos_endian.h"
+
+/* \addtogroup system
+ * @{
+ */
+
+#define BCMOS_MAX_NAME_LENGTH   48
+
+/** \addtogroup system_task
+ * @{
+ */
+
+/** Task control block */
+struct bcmos_task
+{
+    /* OS independent fields */
+    bcmos_task_parm parm;               /**< Task creation parameters */
+    bcmos_module *modules[BCMOS_MAX_MODULES_PER_TASK];
+    uint32_t active_modules;            /**< Bitmask of modules for which events are pending */
+    bcmos_sem active_sem;               /**< Semaphore used to wait for module activity */
+    bcmos_fastlock active_lock;         /**< Lock protecting active_modules */
+    bcmos_module_id current_module;     /**< Current module */
+    bcmos_bool destroy_request;         /**< Task destroy request pending */
+    bcmos_bool destroyed;               /**< Set by task handler before it terminates */
+    STAILQ_ENTRY(bcmos_task) list;      /**< Next task pointer */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Task name */
+    bcmos_sys_task sys_task;            /**< OS-specific task extension */
+    uint32_t magic;                     /* magic number */
+#define BCMOS_TASK_MAGIC                (('t' << 24) | ('a' << 16) | ('s' << 8) | 'k')
+#define BCMOS_TASK_MAGIC_DESTROYED      (('t' << 24) | ('a' << 16) | ('s' << 8) | '~')
+};
+
+/** \addtogroup system_mem
+ * @{
+ */
+
+#ifndef BCMOS_CALLOC_INLINE
+
+/** Allocate memory from the main heap and clear it
+ * \ingroup system_heap
+ * \param[in]   size
+ * \returns memory block pointer or NULL
+ */
+static inline void *bcmos_calloc(uint32_t size)
+{
+    void *ptr = bcmos_alloc(size);
+    if (ptr)
+        memset(ptr, 0, size);
+    return ptr;
+}
+#endif /* #ifndef BCMOS_CALLOC_INLINE */
+
+#ifndef BCMOS_DMA_ALLOC_FREE_INLINE
+
+/** Allocate DMA-able memory
+ * \param[in]   device  Device id
+ * \param[in]   size    Block size (bytes)
+ * \returns memory block pointer or NULL
+ */
+void *bcmos_dma_alloc(uint8_t device, uint32_t size);
+
+/** Release DMA-able memory
+ * \param[in]   device  Device id
+ * \param[in]   ptr     Block pointer
+ */
+void bcmos_dma_free(uint8_t device, void *ptr);
+
+#endif /* #ifndef BCMOS_DMA_ALLOC_FREE_INLINE */
+
+#ifndef BCMOS_VIRT_TO_PHYS_INLINE
+
+/** Convert virtual address to physical address
+ *
+ * \param[in]   va      Virtual address
+ * \returns - physical address va is mapped to
+ */
+unsigned long bcmos_virt_to_phys(void *va);
+
+#endif /* #ifndef BCMOS_VIRT_TO_PHYS_INLINE */
+
+/** @} */
+
+/** \addtogroup blk_pool
+ * @{
+ */
+
+/* Memory block header */
+typedef struct bcmos_memblk bcmos_memblk;
+
+/* Memory block list */
+typedef STAILQ_HEAD(, bcmos_memblk) bcmos_memblk_list;
+
+/* Block memory pool control block */
+struct bcmos_blk_pool
+{
+    bcmos_fastlock lock;        /**< Pool protection lock */
+    bcmos_memblk_list free_list;/**< Free block list */
+    bcmos_blk_pool_parm parm;   /**< Pool parameters */
+    bcmos_blk_pool_stat stat;   /**< Pool statistics */
+    void *start;                /**< Pool start pointer */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Pool name */
+    uint32_t magic;             /**< magic number */
+#define BCMOS_BLK_POOL_VALID            (('b'<<24) | ('l' << 16) | ('p' << 8) | 'o')
+#define BCMOS_BLK_POOL_DELETED          (('b'<<24) | ('l' << 16) | ('p' << 8) | '~')
+    STAILQ_ENTRY(bcmos_blk_pool) list; /* Pool list */
+};
+
+/* Total memory occupied by all block pools */
+extern uint32_t bcmos_total_blk_pool_size;
+
+/** @} blk_pool */
+
+/** \addtogroup system_msg
+ * @{
+ */
+
+/** Release message
+ * \param[in]   msg             Message handle
+ */
+static inline void bcmos_msg_free(bcmos_msg *msg)
+{
+    if (msg->release)
+    {
+        msg->release(msg);
+    }
+    else
+    {
+        bcmos_free(msg);
+    }
+}
+
+typedef STAILQ_HEAD(, bcmos_msg) bcmos_msg_list;
+
+/** Simple Message queue control block.
+ * Simple message queue doesn't support waiting on.
+ * It is used in module queue mechanisms.
+ */
+typedef struct bcmos_msg_queue_nw
+{
+    bcmos_msg_queue_parm parm;  /**< Queue parameters */
+    bcmos_msg_queue_stat stat;  /**< Queue statistics */
+    bcmos_fastlock lock;        /**< Queue protection lock */
+    bcmos_msg_list msgl;        /**< Message list */
+    bcmos_msg_list msgl_urg;    /**< Urgent message list */
+    uint32_t flags;             /**< Queue flags */
+} bcmos_msg_queue_nw;
+
+/** Message queue control block */
+struct bcmos_msg_queue
+{
+    bcmos_msg_queue_nw q;       /**< Queue control block */
+    bcmos_sem m;                /**< Mutex to suspend waiting task on */
+    bcmos_bool is_waiting;      /**< TRUE if task is waiting on queue */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Queue name */
+#ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT
+    long ep;                    /**< Endpoint handle (e.g., socket) */
+    void *ep_extra_data;        /**< Extra data - depending on ep type */
+    uint32_t ep_extra_data_size;/**< Extra data size */
+    uint8_t *send_buf;          /**< Send buffer */
+    uint8_t *recv_buf;          /**< Receive buffer */
+    bcmos_mutex send_lock;      /**< Mutex that protects send_buf */
+#endif
+    uint32_t magic;             /**< magic number */
+#define BCMOS_MSG_QUEUE_VALID           (('m'<<24) | ('q' << 16) | ('u' << 8) | 'e')
+#define BCMOS_MSG_QUEUE_DELETED         (('m'<<24) | ('q' << 16) | ('u' << 8) | '~')
+    STAILQ_ENTRY(bcmos_msg_queue) list; /* Queue list */
+};
+
+/** Message queue group control block */
+struct bcmos_msg_qgroup
+{
+    bcmos_msg_qgroup_parm parm; /**< Queue group parameters */
+    bcmos_msg_list *msgl;       /**< Array of parm.nqueues message lists */
+    bcmos_msg_queue_stat stat;  /**< Queue group statistics */
+    bcmos_sem m;                /**< Mutex to suspend waiting task on */
+    bcmos_fastlock lock;        /**< Queue group protection lock */
+    uint32_t active_mask;       /**< Bitmask of queues containing messages */
+    bcmos_bool is_waiting;      /**< TRUE if task is waiting on queue group */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Queue group name */
+    uint32_t magic;             /**< magic number */
+#define BCMOS_MSG_QGROUP_VALID           (('m'<<24) | ('q' << 16) | ('g' << 8) | 'r')
+#define BCMOS_MSG_QGROUP_DELETED         (('m'<<24) | ('q' << 16) | ('g' << 8) | '~')
+    STAILQ_ENTRY(bcmos_msg_qgroup) list; /* Queue group list */
+};
+
+/** Message pool control block */
+struct bcmos_msg_pool
+{
+    bcmos_blk_pool blk_pool;    /**< Underlying block memory pool */
+    bcmos_msg_pool_parm parm;   /**< Pool parameters */
+};
+
+/* Total memory occupied by all message pools */
+extern uint32_t bcmos_total_msg_pool_size;
+
+/** @} system_msg */
+
+/** \addtogroup system_timer */
+
+/* Timer precision. Must be a multiple of 2.
+ * Timed expiration timestamp is rounded up to the nearest multiple of timer precision
+ */
+#define BCMOS_TIMER_PRECISION_US        32
+#if (BCMOS_TIMER_PRECISION_US & (BCMOS_TIMER_PRECISION_US - 1))
+    #error BCMOS_TIMER_PRECISION_US must be a multiple of 2
+#endif
+
+/* There are 2 timer implementations
+ * - DLIST-based - works well when most of active timers have the same duration
+ * - RB-tree based - more expensive in simple case, but scales better for large number of timers
+ *                   with arbitrary durations
+ */
+#define BCMOS_TIMER_RB_TREE
+
+/** Timer control block */
+struct bcmos_timer
+{
+    bcmos_msg msg;                      /**< Timer message */
+    bcmos_timer_parm parm;              /**< Timer parameters */
+    F_bcmos_timer_handler handler;      /**< Timer handler */
+    uint32_t period;                    /**< Timer period (us) if periodic */
+    uint32_t expire_at;                 /**< Timestamp when timer should expire */
+    uint32_t flags;                     /*   Internal flags */
+#define BCMOS_TIMER_FLAG_RUNNING        0x00000001      /* Timer is running */
+#define BCMOS_TIMER_FLAG_EXPIRED        0x00000002      /* Timer has expired, but not yet handled */
+#define BCMOS_TIMER_FLAG_ACTIVE         (BCMOS_TIMER_FLAG_RUNNING | BCMOS_TIMER_FLAG_EXPIRED)
+#define BCMOS_TIMER_FLAG_VALID          0x00000004
+    bcmos_msg_queue_nw *queue;          /**< Queue expired timer is on */
+    bcmos_task *task;                   /**< Task that executes timer handler */
+#ifdef BCMOS_TIMER_RB_TREE
+    RB_ENTRY(bcmos_timer) entry;        /**< Timer pool entry */
+#else
+    TAILQ_ENTRY(bcmos_timer) entry;
+#endif
+};
+
+/** Check if timer is running
+ * \param[in]   timer   Timer handle
+ * \returns TRUE if timer is running
+ */
+static inline bcmos_bool bcmos_timer_is_running(const bcmos_timer *timer)
+{
+    bcmos_bool running = ((timer->flags & BCMOS_TIMER_FLAG_RUNNING) != 0) ||
+        (timer->parm.periodic && ((timer->flags & BCMOS_TIMER_FLAG_EXPIRED) != 0));
+    return running;
+}
+
+static inline bcmos_timer *_bcmos_msg_to_timer(bcmos_msg *msg)
+{
+    BUG_ON(msg->type != BCMOS_MSG_ID_INTERNAL_TIMER);
+    return (bcmos_timer *)msg;
+}
+
+/** @} */
+
+/** \addtogroup system_module
+ * @{
+ */
+
+/** Module control block */
+struct bcmos_module
+{
+    bcmos_module_parm parm;     /**< Module parameters */
+    bcmos_module_id id;         /**< Module id */
+    int idx;                    /**< Module index in task control block */
+    bcmos_msg_queue_nw msgq;    /**< Message queue */
+    bcmos_task *my_task;        /**< Task the module is associated with */
+    void *context;              /**< User-defined context */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Module name */
+};
+
+/** @} system_module */
+
+/** \addtogroup system_event
+ * @{
+ */
+
+/** Event control block */
+struct bcmos_event
+{
+    bcmos_msg msg;              /**< Message header. Used to deliver event to module's queue */
+    bcmos_event_id id;          /**< Event set id */
+    bcmos_event_parm parm;        /**< Event parameters */
+    bcmos_fastlock lock;        /**< Protects event control block */
+    uint32_t active_bits;       /**< Active event bits */
+
+    bcmos_sem m;                /**< Mutex to suspend task on. Traditional mode only */
+    bcmos_bool is_waiting;      /**< TRUE if task is waiting for event */
+    char name[BCMOS_MAX_NAME_LENGTH];   /**< Event name */
+};
+
+
+static inline bcmos_event *_bcmos_msg_to_event(bcmos_msg *msg)
+{
+    BUG_ON(msg->type != BCMOS_MSG_ID_INTERNAL_EVENT);
+    return (bcmos_event *)msg;
+}
+
+/*
+ * Low level services
+ */
+
+/** \addtogroup system_buf
+ * @{
+ */
+
+#ifndef BCMOS_BUF_OS_SPECIFIC
+#define BCMOS_BUF_DATA_INLINE
+#endif
+
+#ifdef BCMOS_BUF_INLINE
+#define BCMOS_BUF_ALLOC_FREE_INLINE
+#define BCMOS_BUF_DATA_INLINE
+#endif
+
+#ifndef BCMOS_BUF_DATA_GUARD
+#define BCMOS_BUF_DATA_GUARD            0
+#endif
+
+#ifndef BCMOS_BUF_DATA_ALIGNMENT
+#define BCMOS_BUF_DATA_ALIGNMENT        64
+#endif
+
+#ifndef BCMOS_BUF_ALLOC_FREE_INLINE
+
+/** Allocate transport buffer.
+ * The buffer can accommodate up to size bytes of data.
+ * In addition it reserves BCMTR_BUF_EXTRA_HEADROOM headroom bytes
+ * for extra headers.
+ *
+ * \param[in]   size    Data size
+ * \returns buffer pointer or NULL if no memory
+ */
+bcmos_buf *bcmos_buf_alloc(uint32_t size);
+
+ /** Release transport buffer allocated by bcmos_buf_alloc()
+  *
+  * \param[in]   buf    Buffer to be released
+  */
+void bcmos_buf_free(bcmos_buf *buf);
+
+#endif /* BCMOS_BUF_ALLOC_FREE_INLINE */
+
+#ifndef BCMOS_BUF_DATA_INLINE
+
+/** Get data length
+ *
+ * \param[in]   buf     Buffer
+ * \returns data length
+ */
+uint32_t bcmos_buf_length(bcmos_buf *buf);
+
+/** Set data length
+ *
+ * \param[in]   buf     Buffer
+ * \param[in]   length  Data length
+ * \returns 0=OK, or BCM_ERR_OVERFLOW if length exceeds size
+ */
+bcmos_errno bcmos_buf_length_set(bcmos_buf *buf, uint32_t length);
+
+/** Get buffer data pointer.
+ * \param[in]   buf     Buffer
+ * \returns data pointer
+ */
+uint8_t *bcmos_buf_data(bcmos_buf *buf);
+
+#endif /* BCMOS_BUF_DATA_INLINE */
+
+#ifndef BCMOS_BUF_OS_SPECIFIC
+
+#ifndef unlikely
+#define unlikely(x)     (x)
+#endif
+
+/* Generic (not os-specific) sysb implementation */
+
+/*
+ * Network / transport buffer
+ */
+
+
+/* Memory block list */
+typedef STAILQ_HEAD(, bcmos_buf) bcmos_buf_list_head;
+
+typedef struct
+{
+    bcmos_buf_list_head head;           /**< Buffer list head */
+} bcmos_buf_queue;
+
+/* System buffer. We probably can use mbuf as well.  */
+struct bcmos_buf
+{
+    uint8_t *start;
+    uint8_t *data;
+    bcmos_blk_pool *pool;
+    uint32_t size;
+    uint32_t len;
+    STAILQ_ENTRY(bcmos_buf) list;      /**< Next buffer pointer */
+    uint8_t channel;
+};
+
+
+#ifndef BCMTR_BUF_EXTRA_HEADROOM
+#define BCMTR_BUF_EXTRA_HEADROOM 0
+#endif
+
+
+/** Initialize buffer queue
+ * \param[in]   q       Buffer queue
+ */
+static inline void bcmos_buf_queue_init(bcmos_buf_queue *q)
+{
+    STAILQ_INIT(&q->head);
+}
+
+/* Check if buffer queue is empty
+ * \param[in]   q       Buffer queue
+ * \returns TRUE if the queue is empty
+ */
+static inline bcmos_bool bcmos_buf_queue_is_empty(bcmos_buf_queue *q)
+{
+    return (bcmos_bool)STAILQ_EMPTY(&q->head);
+}
+
+/** Enqueue buffer
+ *
+ * Must be called under lock, e.g., q->lock
+ *
+ * \param[in]   q       Buffer queue
+ * \param[in]   buf     Buffer
+ */
+static inline void bcmos_buf_queue_put(bcmos_buf_queue *q, bcmos_buf *buf)
+{
+    STAILQ_INSERT_TAIL(&q->head, buf, list);
+}
+
+/* Dequeue buffer
+ *
+ * Must be called under lock, e.g., q->lock
+ *
+ * Remove and return the 1st queued buffer.
+ * \param[in]   q       Buffer queue
+ * \returns the  buffer pointer
+ */
+static inline bcmos_buf *bcmos_buf_queue_get(bcmos_buf_queue *q)
+{
+    bcmos_buf *buf;
+    buf = STAILQ_FIRST(&q->head);
+    if (buf)
+        STAILQ_REMOVE_HEAD(&q->head, list);
+    return buf;
+}
+
+/* Peek into queue and return the 1st buffer without dequeing it
+ *
+ * Must be called under lock, e.g., q->lock
+ * \param[in]   q       Buffer queue
+ * \returns the  buffer pointer
+ */
+static inline bcmos_buf *bcmos_buf_queue_peek(bcmos_buf_queue *q)
+{
+    return STAILQ_FIRST(&q->head);
+}
+
+/* Initialize buffer */
+static inline bcmos_buf *bcmos_buf_init(bcmos_buf *buf, uint8_t *start,
+    uint8_t *data, uint32_t size, uint32_t len)
+{
+    BUG_ON((void *)(buf +1) != start);
+    buf->start = start;
+    buf->data = data;
+    buf->size = size;
+    buf->len = len;
+    buf->pool = NULL;
+    return buf;
+}
+
+/* Get data length */
+static inline uint32_t bcmos_buf_length(bcmos_buf *buf)
+{
+    return buf->len;
+}
+
+/* Set data length */
+static inline bcmos_errno bcmos_buf_length_set(bcmos_buf *buf, uint32_t length)
+{
+    if (unlikely(length > buf->size - (buf->data - buf->start)))
+    {
+        BCMOS_TRACE_ERR("!!!%s: length=%u size=%u data=%p start=%p data-start=%u\n",
+            __FUNCTION__, length, buf->size, buf->data, buf->start, (uint32_t)(buf->data - buf->start));
+        return BCM_ERR_OVERFLOW;
+    }
+    buf->len = length;
+    return BCM_ERR_OK;
+}
+
+/* Get buffer data pointer. */
+static inline uint8_t *bcmos_buf_data(bcmos_buf *buf)
+{
+    return buf->data;
+}
+
+/* Get buffer channel. */
+static inline uint8_t bcmos_buf_channel(bcmos_buf *buf)
+{
+    return buf->channel;
+}
+
+/* Set buffer channel. */
+static inline void bcmos_buf_channel_set(bcmos_buf *buf, uint8_t channel)
+{
+    buf->channel = channel;
+}
+
+#endif /* #ifndef BCMOS_BUF_OS_SPECIFIC */
+
+/** @} bcmos_buf */
+
+/** \addtogroup system_cache
+ * @{
+ */
+
+#ifndef BCMOS_CACHE_INLINE
+
+/** Invalidate address area in data cache. Dirty cache lines content is discarded.
+ * \param[in]   start   Address area start
+ * \param[in]   size    Address area size
+ */
+void bcmos_dcache_inv(void *start, uint32_t size);
+
+/** Flush address area in data cache. Dirty cache lines are committed to memory.
+ * \param[in]   start   Address area start
+ * \param[in]   size    Address area size
+ */
+void bcmos_dcache_flush(void *start, uint32_t size);
+
+#endif /* BCMOS_CACHE_INLINE */
+
+/** Prepare for DMA write.
+ * On h/w platforms that support DMA-cache coherency, this function should
+ * perform write barrier.
+ * On platforms that don't support DMA cache coherency this function should
+ * flush the relevant dcache area
+ *
+ * \param[in]   start   DMA buffer start address
+ * \param[in]   size    DMA buffer size
+ */
+static inline void bcmos_prepare_for_dma_write(void *start, uint32_t size)
+{
+#ifdef BCMOS_DMA_CACHE_COHERENCY
+    bcmos_barrier();
+#else
+    bcmos_dcache_flush(start, size);
+#endif
+}
+
+/** Prepare for DMA read.
+ * On h/w platforms that support DMA-cache coherency, this function should
+ * perform write barrier.
+ * On platforms that don't support DMA cache coherency this function should
+ * invalidate the relevant dcache area
+ *
+ * \param[in]   start   DMA buffer start address
+ * \param[in]   size    DMA buffer size
+ */
+static inline void bcmos_prepare_for_dma_read(void *start, uint32_t size)
+{
+#ifdef BCMOS_DMA_CACHE_COHERENCY
+    bcmos_barrier();
+#else
+    bcmos_dcache_inv(start, size);
+#endif
+}
+
+/** @} system_cache */
+
+/** \addtogroup system_interrupt
+ * @{
+ */
+
+#ifdef BCMOS_INTERRUPT_INLINE
+#define BCMOS_INTERRUPT_CONNECT_DISCONNECT_INLINE
+#define BCMOS_INTERRUPT_ENABLE_DISABLE_INLINE
+#endif
+
+#ifndef BCMOS_INTERRUPT_CONNECT_DISCONNECT_INLINE
+/** Connect system interrupt
+ * \param[in]   irq     IRQ number
+ * \param[in]   cpu     CPU number (for SMP)
+ * \param[in]   flags   IRQ flags
+ * \param[in]   isr     ISR
+ * \param[in]   name    device name
+ * \param[in]   priv    Private cookie
+ * \returns 0=OK, <0- error
+ */
+int bcmos_int_connect(int irq, int cpu, int flags,
+    int (*isr)(int irq, void *priv), const char *name, void *priv);
+
+/** Disconnect system interrupt
+ * \param[in]   irq     IRQ number
+ * \param[in]   priv    Private cookie passed in bcmos_int_connect()
+ * \returns 0=OK, <0- error
+ */
+void bcmos_int_disconnect(int irq, void *priv);
+#endif
+
+#ifndef BCMOS_INTERRUPT_ENABLE_DISABLE_INLINE
+/** Unmask IRQ
+ * \param[in]   irq IRQ
+ */
+void bcmos_int_enable(int irq);
+
+/** Mask IRQ
+ * \param[in]   irq IRQ
+ */
+void bcmos_int_disable(int irq);
+#endif
+
+/** @} */
+
+/* Get char, put char support */
+#ifndef BCMOS_GETCHAR_INLINE
+static inline int bcmos_getchar(void)
+{
+    return getchar();
+}
+#endif
+
+#ifndef BCMOS_PUTCHAR_INLINE
+void bcmos_putchar(int c);
+#endif
+
+#ifndef BCMOS_SEM_POST_IS_ALLOWED_INLINE
+static inline bcmos_bool bcmos_sem_post_is_allowed(void)
+{
+    return BCMOS_TRUE;
+}
+#endif
+
+#endif /* BCMOS_COMMON2_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_endian.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_endian.h
new file mode 100644
index 0000000..ece41dc
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_endian.h
@@ -0,0 +1,130 @@
+/*
+<: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 BCMOS_ENDIAN_H_
+#define BCMOS_ENDIAN_H_
+
+#ifndef BCMOS_SYSTEM_H_
+#error Please do not include bcmos_endian.h directly. Include bcmos_system.h
+#endif
+
+
+
+/** @} system_event */
+
+/** \addtogroup system_endian
+ * @{
+ */
+#ifndef BCMOS_ARCH_ENDIAN_SWAP
+
+/** Swaps the endianness of a 16-bit integer
+ * \param[in] n the original number
+ * \return number with swapped endianness
+ */
+static inline uint16_t bcmos_endian_swap_u16(uint16_t n)
+{
+    return ((n << 8 ) & 0xFF00U)|((n >> 8) & 0x00FFU);
+}
+
+/** Swaps the endianness of a 24-bit integer
+ * \param[in] n the original number
+ * \return number with swapped endianness
+ */
+static inline uint24_t bcmos_endian_swap_u24(uint24_t n)
+{
+    return (uint24_t){ .u8 = { n.u8[2], n.u8[1], n.u8[0] } };
+}
+
+/** Swaps the endianness of a 32-bit integer
+ * \param[in] n the original number
+ * \return number with swapped endianness
+ */
+static inline uint32_t bcmos_endian_swap_u32(uint32_t n)
+{
+    return ((n << 24) & 0xFF000000U)|((n << 8 ) & 0x00FF0000U)|((n >> 8) & 0x0000FF00U)|((n >> 24) & 0x000000FFU);
+}
+
+/** Swaps the endianness of a 64-bit integer
+ * \param[in] n the original number
+ * \return number with swapped endianness
+ */
+static inline uint64_t bcmos_endian_swap_u64(uint64_t n)
+{
+    return (((uint64_t)bcmos_endian_swap_u32(n & 0xFFFFFFFFU) << 32) | bcmos_endian_swap_u32((n >> 32) & 0xFFFFFFFFU));
+}
+
+#endif /* BCMOS_ARCH_ENDIAN_SWAP */
+
+#if (BCM_CPU_ENDIAN == BCMOS_ENDIAN_BIG)
+
+#define BCMOS_ENDIAN_CPU_TO_BIG_U16(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_BIG_U24(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_BIG_U32(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_BIG_U64(n) (n)
+#define BCMOS_ENDIAN_BIG_TO_CPU_U16(n) (n)
+#define BCMOS_ENDIAN_BIG_TO_CPU_U24(n) (n)
+#define BCMOS_ENDIAN_BIG_TO_CPU_U32(n) (n)
+#define BCMOS_ENDIAN_BIG_TO_CPU_U64(n) (n)
+
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U16(n) (bcmos_endian_swap_u16(n))
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U24(n) (bcmos_endian_swap_u24(n))
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U32(n) (bcmos_endian_swap_u32(n))
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U64(n) (bcmos_endian_swap_u64(n))
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U16(n) (bcmos_endian_swap_u16(n))
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U24(n) (bcmos_endian_swap_u24(n))
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U32(n) (bcmos_endian_swap_u32(n))
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U64(n) (bcmos_endian_swap_u64(n))
+
+#elif (BCM_CPU_ENDIAN == BCMOS_ENDIAN_LITTLE)
+
+#define BCMOS_ENDIAN_CPU_TO_BIG_U16(n) (bcmos_endian_swap_u16(n))
+#define BCMOS_ENDIAN_CPU_TO_BIG_U24(n) (bcmos_endian_swap_u24(n))
+#define BCMOS_ENDIAN_CPU_TO_BIG_U32(n) (bcmos_endian_swap_u32(n))
+#define BCMOS_ENDIAN_CPU_TO_BIG_U64(n) (bcmos_endian_swap_u64(n))
+#define BCMOS_ENDIAN_BIG_TO_CPU_U16(n) (bcmos_endian_swap_u16(n))
+#define BCMOS_ENDIAN_BIG_TO_CPU_U24(n) (bcmos_endian_swap_u24(n))
+#define BCMOS_ENDIAN_BIG_TO_CPU_U32(n) (bcmos_endian_swap_u32(n))
+#define BCMOS_ENDIAN_BIG_TO_CPU_U64(n) (bcmos_endian_swap_u64(n))
+
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U16(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U24(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U32(n) (n)
+#define BCMOS_ENDIAN_CPU_TO_LITTLE_U64(n) (n)
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U16(n) (n)
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U24(n) (n)
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U32(n) (n)
+#define BCMOS_ENDIAN_LITTLE_TO_CPU_U64(n) (n)
+
+#else
+#error BCM_CPU_ENDIAN must be BCMOS_ENDIAN_BIG or _LITTLE
+#endif
+
+/** @} system_endian */
+
+#endif /* BCMOS_COMMON2_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.c b/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.c
new file mode 100644
index 0000000..a2a0ff8
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.c
@@ -0,0 +1,86 @@
+/*
+<: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"
+
+/* Map error code to error string */
+const char *bcmos_strerror(bcmos_errno err)
+{
+    static const char *errstr[] = {
+        [-BCM_ERR_OK]                        = "OK",
+        [-BCM_ERR_IN_PROGRESS]               = "In progress",
+        [-BCM_ERR_PARM]                      = "Error in parameters",
+        [-BCM_ERR_NOMEM]                     = "No memory",
+        [-BCM_ERR_NORES]                     = "No resources",
+        [-BCM_ERR_INTERNAL]                  = "Internal error",
+        [-BCM_ERR_NOENT]                     = "Entry doesn't exist",
+        [-BCM_ERR_NODEV]                     = "Device doesn't exist",
+        [-BCM_ERR_ALREADY]                   = "Entry already exists",
+        [-BCM_ERR_RANGE]                     = "Out of range",
+        [-BCM_ERR_PERM]                      = "No permission to perform an operation",
+        [-BCM_ERR_NOT_SUPPORTED]             = "Operation is not supported",
+        [-BCM_ERR_PARSE]                     = "Parsing error",
+        [-BCM_ERR_INVALID_OP]                = "Invalid operation",
+        [-BCM_ERR_IO]                        = "I/O error",
+        [-BCM_ERR_STATE]                     = "Object is in bad state",
+        [-BCM_ERR_DELETED]                   = "Object is deleted",
+        [-BCM_ERR_TOO_MANY]                  = "Too many objects",
+        [-BCM_ERR_NO_MORE]                   = "No more entries",
+        [-BCM_ERR_OVERFLOW]                  = "Buffer overflow",
+        [-BCM_ERR_COMM_FAIL]                 = "Communication failure",
+        [-BCM_ERR_NOT_CONNECTED]             = "No connection with the target system",
+        [-BCM_ERR_SYSCALL_ERR]               = "System call returned error",
+        [-BCM_ERR_MSG_ERROR]                 = "Received message is insane",
+        [-BCM_ERR_TOO_MANY_REQS]             = "Too many outstanding requests",
+        [-BCM_ERR_TIMEOUT]                   = "Operation timed out",
+        [-BCM_ERR_TOO_MANY_FRAGS]            = "Too many fragments",
+        [-BCM_ERR_NULL]                      = "Got NULL pointer",
+        [-BCM_ERR_READ_ONLY]                 = "Attempt to set read-only parameter",
+        [-BCM_ERR_ONU_ERR_RESP]              = "ONU returned an error response",
+        [-BCM_ERR_MANDATORY_PARM_IS_MISSING] = "Mandatory parameter is missing",
+        [-BCM_ERR_KEY_RANGE]                 = "Key field out of range",
+        [-BCM_ERR_QUEUE_EMPTY]               = "Rx of PCIe empty",
+        [-BCM_ERR_QUEUE_FULL]                = "Tx of PCIe full",
+        [-BCM_ERR_TOO_LONG]                  = "Processing is taking too long, but will finish eventually",
+        [-BCM_ERR_INSUFFICIENT_LIST_MEM]     = "Insufficient list memory provided",
+
+        [-BCM_ERR_OUT_OF_SYNC]               = "Sequence number or operation step was out of sync",
+        [-BCM_ERR_CHECKSUM]                  = "Checksum error",
+        [-BCM_ERR_IMAGE_TYPE]                = "Unsupported file/image type",
+        [-BCM_ERR_INCOMPLETE_TERMINATION]    = "Incomplete premature termination",
+    };
+    static const char *unknown = "*unknown*";
+
+    if ((unsigned)(-err) >= sizeof(errstr)/sizeof(errstr[0]) || !errstr[-err])
+        return unknown;
+    return errstr[-err];
+}
+
+#ifdef __KERNEL__
+EXPORT_SYMBOL(bcmos_strerror);
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.h
new file mode 100644
index 0000000..f5e892a
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_errno.h
@@ -0,0 +1,91 @@
+/*
+<: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 BCMOS_ERRNO_H_
+#define BCMOS_ERRNO_H_
+
+/** \defgroup system_errno Error Codes
+ * @{
+ */
+
+/** Error codes */
+typedef enum
+{
+    BCM_ERR_OK                                 =  0,   /**< OK */
+    BCM_ERR_IN_PROGRESS                        = -1,   /**< Operation is in progress */
+    BCM_ERR_PARM                               = -2,   /**< Error in parameters */
+    BCM_ERR_NOMEM                              = -3,   /**< No memory */
+    BCM_ERR_NORES                              = -4,   /**< No resources */
+    BCM_ERR_INTERNAL                           = -5,   /**< Internal error */
+    BCM_ERR_NOENT                              = -6,   /**< Entry doesn't exist */
+    BCM_ERR_NODEV                              = -7,   /**< Device doesn't exist */
+    BCM_ERR_ALREADY                            = -8,   /**< Entry already exists */
+    BCM_ERR_RANGE                              = -9,   /**< Out of range */
+    BCM_ERR_PERM                               = -10,  /**< No permission to perform an operation */
+    BCM_ERR_NOT_SUPPORTED                      = -11,  /**< Operation is not supported */
+    BCM_ERR_PARSE                              = -12,  /**< Parsing error */
+    BCM_ERR_INVALID_OP                         = -13,  /**< Invalid operation */
+    BCM_ERR_IO                                 = -14,  /**< I/O error */
+    BCM_ERR_STATE                              = -15,  /**< Object is in bad state */
+    BCM_ERR_DELETED                            = -16,  /**< Object is deleted */
+    BCM_ERR_TOO_MANY                           = -17,  /**< Too many objects */
+    BCM_ERR_NO_MORE                            = -18,  /**< No more entries */
+    BCM_ERR_OVERFLOW                           = -19,  /**< Buffer overflow */
+    BCM_ERR_COMM_FAIL                          = -20,  /**< Communication failure */
+    BCM_ERR_NOT_CONNECTED                      = -21,  /**< No connection with the target system */
+    BCM_ERR_SYSCALL_ERR                        = -22,  /**< System call returned error */
+    BCM_ERR_MSG_ERROR                          = -23,  /**< Received message is insane */
+    BCM_ERR_TOO_MANY_REQS                      = -24,  /**< Too many outstanding requests */
+    BCM_ERR_TIMEOUT                            = -25,  /**< Operation timed out */
+    BCM_ERR_TOO_MANY_FRAGS                     = -26,  /**< Too many fragments */
+    BCM_ERR_NULL                               = -27,  /**< Got NULL pointer */
+    BCM_ERR_READ_ONLY                          = -28,  /**< Attempt to set read-only parameter */
+    BCM_ERR_ONU_ERR_RESP                       = -29,  /**< ONU returned an error response */
+    BCM_ERR_MANDATORY_PARM_IS_MISSING          = -30,  /**< Mandatory parameter is missing */
+    BCM_ERR_KEY_RANGE                          = -31,  /**< Key field was out of range */
+    BCM_ERR_QUEUE_EMPTY                        = -32,  /**< Rx PCIe queue empty */
+    BCM_ERR_QUEUE_FULL                         = -33,  /**< Tx PCIe queue full */
+    BCM_ERR_TOO_LONG                           = -34,  /**< Processing is taking too long, but will finish eventually */
+    BCM_ERR_INSUFFICIENT_LIST_MEM              = -35,  /**< Not enough memory was provided for variable-length lists */
+
+    BCM_ERR_OUT_OF_SYNC                        = -36,  /**< Sequence number or operation step was out of sync. */
+    BCM_ERR_CHECKSUM                           = -37,  /**< Checksum error */
+    BCM_ERR_IMAGE_TYPE                         = -38,  /**< Unsupported file/image type */
+    BCM_ERR_INCOMPLETE_TERMINATION             = -39,  /**< Incomplete premature termination */
+} bcmos_errno;
+
+/** Map error code to error string
+ * \param[in]   err     Error code
+ * \returns Error string
+ */
+const char *bcmos_strerror(bcmos_errno err);
+
+/** @} system_errno */
+
+#endif /* BCMOS_ERRNO_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.c b/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.c
new file mode 100644
index 0000000..12e1962
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.c
@@ -0,0 +1,467 @@
+/*
+<: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_hash_table.h"
+
+#define ht_overhead     sizeof(void *)
+
+/** Create a hash table using a block pool
+ *  \param[in] pool_parm            pointer to block pool parameters
+ *  \param[in] max_data_entries     Maximum entries the hash table needs to hold
+ *  \param[in] entry_size           Size of each entry in bytes
+ *  \param[in] key_size             Size of each key in bytes
+ *  \return pointer to newly created hash table
+ */
+static hash_table *hash_table_create_in_pool(bcmos_blk_pool_parm *pool_parm,
+                                             uint32_t max_data_entries,
+                                             uint16_t entry_size,
+                                             uint8_t key_size)
+{
+    uint32_t lookup_table_entries = max_data_entries + (max_data_entries / 4);
+    hash_table *ht;
+    bcmos_errno err;
+
+    if (pool_parm == NULL)
+    {
+        BUG();
+        return NULL;
+    }
+
+    entry_size += key_size;
+
+    ht = bcmos_alloc(sizeof(hash_table));
+    if (ht == NULL)
+    {
+        BUG();
+        return NULL;
+    }
+
+    ht->obj_len = entry_size;
+    ht->key_len = key_size;
+    ht->data_offset = ht_overhead;
+    ht->ht_lookup_tbl_entries = lookup_table_entries;
+    ht->ht_max_data_entries = max_data_entries;
+    ht->look_up_entries_tbl = bcmos_alloc(lookup_table_entries * sizeof(ht_block));
+
+    if (ht->look_up_entries_tbl == NULL)
+    {
+        bcmos_free(ht);
+        BUG();
+        return NULL;
+    }
+
+    ht->ht_cur_entries = 0;
+    err = bcmos_blk_pool_create(&ht->key_data_pool, pool_parm);
+
+    if (err != BCM_ERR_OK)
+    {
+        bcmos_free(ht->look_up_entries_tbl);
+        bcmos_free(ht);
+        BUG();
+        return NULL;
+    }
+
+    if (ht->ht_max_data_entries > ht->ht_lookup_tbl_entries)
+    {
+        BUG();
+    }
+
+    ht->obj_len -= ht->key_len;
+
+    memset(ht->look_up_entries_tbl, 0, lookup_table_entries * sizeof(ht_block));
+    return ht;
+}
+
+hash_table *hash_table_create(uint32_t max_data_entries,
+                              uint16_t entry_size,
+                              uint8_t key_size,
+                              char *pool_name)
+{
+    bcmos_blk_pool_parm parm = {0};
+
+    parm.name = pool_name;
+    parm.blk_size = entry_size + key_size + ht_overhead;
+    parm.num_blks = max_data_entries;
+
+    return hash_table_create_in_pool(&parm, max_data_entries, entry_size, key_size);
+}
+
+/** Hash a length of bytes into a uint32_t
+ *  \param[in] key      Bytes to hash
+ *  \param[in] len      Number of bytes in key
+ *  \return The hash as a uint32_t
+ */
+static uint32_t get_hash_for_key(const uint8_t *key, uint8_t len)
+{
+    uint32_t hash = 5381;
+    uint8_t i;
+    const uint8_t *tmp = key;
+    for (i = 0; i < len; tmp++, i++)
+    {
+        hash = ((hash << 5) + hash) + (*tmp);
+    }
+
+    return hash;
+}
+
+/** Gets a hash key used for the keyDataPool in the HashTable
+ *  \param[in] ht   Associated hashtable we are getting hash for key for
+ *  \param[in] key  Key we are getting hash for
+ *  \return An index into the keyDataPool
+ */
+static uint32_t get_hash_val_for_key(const hash_table *ht, const uint8_t *key)
+{
+    return get_hash_for_key(key, ht->key_len) % ht->ht_lookup_tbl_entries;
+}
+
+/** Returns the location of the key within an HtBlock
+ *  \param[in] ht       Hash table in question
+ *  \param[in] block    HtBlock in question
+ *  \return pointer to the data within the block
+ */
+static uint8_t *get_key_from_block_in_table(const hash_table *ht, ht_block *block)
+{
+    return(uint8_t *) block + ht->data_offset + ht->obj_len;
+}
+
+/** Gets and populates a HtBlock with all of its data
+ *  \param[in] next     Next block in this buckets chain
+ *  \param[in] ht       Hash table in question
+ *  \param[in] key      This blocks key
+ *  \param[in] val      This blocks data
+ *  \return The block that we allocated and returned
+ */
+static ht_block *fill_ht_block(ht_block *next,
+                               hash_table *ht,
+                               const uint8_t *key,
+                               const void *val)
+{
+    ht_block *dest_block = bcmos_blk_pool_alloc(&ht->key_data_pool);
+
+    if (dest_block != NULL)
+    {
+        /* storage is nextobj ptr, hash obj,
+	    key which keeps all uint32_t aligned. */
+        dest_block->next_chain = next;
+
+        if (val != NULL)
+        {
+            memcpy((uint8_t *) dest_block + ht->data_offset, val, ht->obj_len);
+        }
+        else
+        {
+            memset((uint8_t *) dest_block + ht->data_offset,0,ht->obj_len);
+        }
+
+        /* Need to put key in after obj */
+        memcpy(
+              (uint8_t *) dest_block + ht->data_offset + ht->obj_len,
+              key,
+              ht->key_len);
+    }
+
+    return dest_block;
+}
+
+/** Determine whether two keys in a particular hash table match
+ *  \param[in] ht       Hashtable
+ *  \param[in] key_a    first key to compare
+ *  \param[in] key_b    second key to compare
+ *  \return whether they are the same
+ */
+static bcmos_bool is_key_match(const hash_table *ht, const uint8_t *key_a, const uint8_t *key_b)
+{
+    return memcmp(key_a, key_b, ht->key_len) == 0;
+}
+
+/** Searches a chained bucket looking for an instance of the key.  If found returns the block if found the key in.
+ *  Prev guy is set to the block in the chain before the block we returned (except in the case * where there is no
+ *  block before the one we returned.
+ *  \param[in] ht           HashTable in question
+ *  \param[in] key_to_find  Key we wonder if exists
+ *  \param[in] chain_start  Where to start looking in the chain
+ *  \param[in] prev_block   The previous guy before the block we returned (if exists)
+ *  \return The block that matches doesExists (if exists)
+ */
+static ht_block *get_key_loc_in_chain(
+                                     const hash_table *ht,
+                                     const uint8_t *key_to_find,
+                                     ht_block *chain_start,
+                                     ht_block **prev_block)
+{
+    *prev_block = NULL;
+    while (chain_start != NULL)
+    {
+        if (is_key_match(ht, key_to_find, get_key_from_block_in_table(ht, chain_start)))
+        {
+            return chain_start;
+        }
+        *prev_block = chain_start;
+        chain_start = chain_start->next_chain;
+    }
+    return NULL;
+}
+
+bcmos_bool hash_table_remove(hash_table *ht, const uint8_t *key)
+{
+    uint32_t hash_val = get_hash_val_for_key(ht, key);
+    ht_block *prev_entry;
+    ht_block *entry = get_key_loc_in_chain(
+        ht,
+        key,
+        ht->look_up_entries_tbl[hash_val].next_chain,
+        &prev_entry);
+
+    if (entry == NULL)
+    {
+        /* No one to delete */
+        return BCMOS_FALSE;
+    }
+    else
+    {
+        ht->ht_cur_entries--;
+        if (prev_entry == NULL)
+        {
+            /* last entry */
+            ht->look_up_entries_tbl[hash_val].next_chain = entry->next_chain;
+        }
+        else
+        {
+            prev_entry->next_chain = entry->next_chain;
+        }
+        bcmos_blk_pool_free(entry);
+        return BCMOS_TRUE;
+    }
+}
+
+/** Returns a pointer to the data within the HT
+ *  \param[in] ht           Hashtable in question
+ *  \param[in] block_ptr    HtBlock that we wonder where its data is
+ */
+static void *get_ht_data_ptr(const hash_table *ht, ht_block *block_ptr)
+{
+    return(uint8_t*)block_ptr + ht->data_offset;
+}
+
+
+/** Get an entry in the hash table
+ *  \param[in] ht       pointer to hash table
+ *  \param[in] key      pointer to key data
+ *  \param[in] hash_val hash value of key
+ *  \return pointer to hash table entry
+ */
+static inline void *ht_get_internal(const hash_table *ht,
+                                    const uint8_t *key,
+                                    uint32_t hash_val)
+{
+    ht_block *tmp;
+    ht_block *ret;
+    ret = get_key_loc_in_chain(
+                              ht,
+                              key,
+                              ht->look_up_entries_tbl[hash_val].next_chain,
+                              &tmp);
+    if (ret != NULL)
+    {
+        return get_ht_data_ptr(ht,ret);
+    }
+    else
+    {
+        return ret;
+    }
+}
+
+void *hash_table_get(const hash_table *ht, const uint8_t *key)
+{
+    uint32_t hashVal = get_hash_val_for_key(ht, key);
+    return ht_get_internal(ht,key,hashVal);
+}
+
+void *hash_table_put(hash_table *ht, const uint8_t *key, const void *val)
+{
+    void *ret_block;
+    uint32_t hash_val;
+    if (ht->ht_cur_entries >= ht->ht_max_data_entries)
+    {
+        return NULL;
+    }
+    hash_val = get_hash_val_for_key(ht, key);
+
+    ret_block = ht_get_internal((const hash_table *) ht, key, hash_val);
+    if (ret_block != NULL)
+    {
+        /* replace existing value with new value */
+        if (val != NULL)
+        {
+            memcpy(ret_block, val, ht->obj_len);
+        }
+        else
+        {
+            memset(ret_block, 0, ht->obj_len);
+        }
+        return ret_block;
+    }
+    else
+    {
+        ht_block *new_block=fill_ht_block(
+                                         ht->look_up_entries_tbl[hash_val].next_chain, ht, key, val);
+        if (new_block != NULL)
+        {
+            ht->look_up_entries_tbl[hash_val].next_chain = new_block;
+            ht->ht_cur_entries++;
+            return get_ht_data_ptr(ht,new_block);
+        }
+        else
+        {
+            return NULL;
+        }
+    }
+
+}
+
+ht_iterator ht_iterator_get(const hash_table *ht)
+{
+    ht_iterator to_ret;
+    to_ret.ht = ht;
+    to_ret.cur_idx = 0;
+    to_ret.removed_at = BCMOS_FALSE;
+    to_ret.still_valid = BCMOS_TRUE;
+    to_ret.cur_block = NULL;
+    return to_ret;
+}
+
+ht_iterator ht_iterator_get_by_key(const hash_table *ht, const uint8_t *key)
+{
+    ht_block *tmp;
+    uint32_t hash_val = get_hash_val_for_key(ht, key);
+    ht_iterator to_ret = {};
+    to_ret.ht = ht;
+    to_ret.removed_at = BCMOS_FALSE;
+    to_ret.cur_block = get_key_loc_in_chain(ht, key, ht->look_up_entries_tbl[hash_val].next_chain, &tmp);
+    to_ret.still_valid = (to_ret.cur_block != NULL);
+    to_ret.cur_idx = hash_val;
+
+    return to_ret;
+}
+
+/** Advance linear scan iterator
+ *  \param[in] it   Iterator to advance
+ */
+static void ht_iterator_scan_adv(ht_iterator *it)
+{
+    if (it->cur_block != NULL)
+    {
+        it->cur_block = it->cur_block->next_chain;
+        if (it->cur_block != NULL)
+        {
+            it->still_valid = BCMOS_TRUE;
+            return;
+        }
+        else
+        {
+            it->cur_idx++;
+        }
+    }
+    /* find non null entry */
+    while (it->cur_idx < it->ht->ht_lookup_tbl_entries)
+    {
+        if (it->ht->look_up_entries_tbl[it->cur_idx].next_chain != NULL)
+        {
+            it->cur_block = it->ht->look_up_entries_tbl[it->cur_idx].next_chain;
+            it->still_valid = BCMOS_TRUE;
+            return;
+        }
+        else
+        {
+            it->cur_idx++;
+        }
+    }
+    it->still_valid = BCMOS_FALSE;
+}
+
+void ht_iterator_deref(const ht_iterator *hti, uint8_t **key, void **obj)
+{
+    if (!hti->still_valid)
+    {
+        BCMOS_TRACE_ERR("%s: Invalid deref\n", __FUNCTION__);
+    }
+    else
+    {
+        *key = get_key_from_block_in_table(hti->ht, hti->cur_block);
+        *obj = get_ht_data_ptr(hti->ht, hti->cur_block);    /* to data */
+    }
+}
+
+void ht_iterator_remove_at(hash_table *ht, ht_iterator *it)
+{
+    if (ht != it->ht)
+    {
+        BCMOS_TRACE_ERR("%s: Incorrect writeable hash table pointer\n", __FUNCTION__);
+    }
+    else if (it->removed_at)
+    {
+        BCMOS_TRACE_ERR("%s: No delete twice\n", __FUNCTION__);
+    }
+    else
+    {
+        uint8_t *key;
+        uint8_t *obj;
+        ht_iterator_deref(it, &key, (void **) &obj);
+        it->removed_at = BCMOS_TRUE;
+        it->still_valid = ht_iterator_next(it);
+        if (!hash_table_remove(ht, key))
+        {
+            BCMOS_TRACE_ERR("%s: Remove error\n", __FUNCTION__);
+        }
+    }
+}
+
+bcmos_bool ht_iterator_next(ht_iterator *it)
+{
+    if (it->still_valid)
+    {
+        if (it->removed_at)
+        {
+            it->removed_at = BCMOS_FALSE;
+        }
+        else
+        {
+            ht_iterator_scan_adv(it);
+        }
+    }
+    return it->still_valid;   /* No entry found */
+}
+
+void hash_table_clear(hash_table *ht)
+{
+    ht_iterator it = ht_iterator_get(ht);
+    while (ht_iterator_next(&it))
+    {
+        ht_iterator_remove_at(ht, &it);
+    }
+}
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.h
new file mode 100644
index 0000000..15618d6
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_hash_table.h
@@ -0,0 +1,137 @@
+/*
+<: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 BCMOS_HASH_TABLE_H_
+#define BCMOS_HASH_TABLE_H_
+
+#include "bcmos_system.h"
+
+typedef struct ht_block ht_block;
+struct ht_block
+{
+    ht_block *next_chain;
+};
+
+typedef struct
+{
+    uint16_t obj_len;
+    uint8_t key_len;
+    uint32_t data_offset;
+    uint32_t ht_lookup_tbl_entries;
+    uint32_t ht_max_data_entries;
+    bcmos_blk_pool key_data_pool;
+    ht_block *look_up_entries_tbl;
+    uint32_t ht_cur_entries;
+} hash_table;
+
+typedef struct
+{
+    const hash_table *ht;
+    uint32_t cur_idx;
+    ht_block *cur_block;
+    bcmos_bool removed_at;
+    bcmos_bool still_valid;
+} ht_iterator;
+
+/** Create a hash table
+ *  \param[in] max_data_entries     Maximum entries the hash table needs to hold
+ *  \param[in] entry_size           Size of each entry in bytes
+ *  \param[in] key_size             Size of each key in bytes
+ *  \param[in] pool_name            Friendly name to identify the hash table's memory pool
+ *  \return pointer to newly created hash table
+ */
+hash_table *hash_table_create(uint32_t max_data_entries,
+                              uint16_t entry_size,
+                              uint8_t key_size,
+                              char *pool_name);
+
+/** Removes all entries from a HashTable.
+ *  \param[in] ht   Hash table to remove all entries from
+ */
+void hash_table_clear(hash_table *ht);
+
+/** Gets a pointer to an entry within the hash table (if exists)
+ *  \param[in] ht   Hashtable in question
+ *  \param[in] key  Key to look for.
+ *  \return Non null if we found a data item associated with KEY.
+ */
+void *hash_table_get(const hash_table *ht, const uint8_t *key);
+
+/** Returns pointers to the key and value that an iterator is pointing at. Warning: key may not be uint32_t aligned.
+ *  DO NOT DELETE THE ELEMENT THE ITERATOR POINTS AT AND AND TRY TO USE THE ITERATOR SUBSEQUENTLY. If you need to do
+ *  this use ht_iterator_remove_at
+ *  \param[in] hti  Iterator
+ *  \param[in] key  Pointer to key to fill
+ *  \param[in] obj  Pointer to obj to fill.
+ */
+void ht_iterator_deref(const ht_iterator *hti, uint8_t **key, void **obj);
+
+/** Get an interator for traversing a hashtable.
+ *  \param[in] ht   Hashtable to traverse
+ *  \return The iterator.
+ */
+ht_iterator ht_iterator_get(const hash_table *ht);
+
+/** Get an interator for traversing a hashtable based on an entry's key.
+ *  \param[in] ht   Hashtable to traverse
+ *  \param[in] key  key of entry to return
+ *  \return The iterator.
+ */
+ht_iterator ht_iterator_get_by_key(const hash_table *ht, const uint8_t *key);
+
+/** Advances a HashTable iterator to the next location within the HashTable.
+ *  \param[in] it   Iterator to advance
+ *  \return TRUE if there was a next element
+ */
+bcmos_bool ht_iterator_next(ht_iterator *it);
+
+/** Deletes the entry where the iterator points to and advances the iterator returning whether the advance worked or
+ *  not.
+ *  \param[in] ht   Writable reference to the hash table (the iterator only has read permission)
+ *  \param[in] it   Itreator pointing at entry to delete.
+ */
+void ht_iterator_remove_at(hash_table *ht, ht_iterator *it);
+
+/** Attempts to associate key with val in the hash table. If key already exists overwrites what was at key with val.
+ *  Otherwise allocates an entry within the hashtable for key and copies val into it.
+ *  \param[in] ht   Hashtable to add or modify
+ *  \param[in] key  Key to try and associate with val.
+ *  \param[in] val  Val to associate
+ *  \return NULL if fail, else pointer to just added block.
+ */
+void *hash_table_put(hash_table *ht, const uint8_t *key, const void *val);
+
+/** Removes an entry (if exists) from the hash table.
+ *  \param[in] ht   HashTable to remove from.
+ *  \param[in] key  Key to remove
+ *  \return BCMOS_TRUE if anything was removed, otherwise BCMOS_FALSE.
+ */
+bcmos_bool hash_table_remove(hash_table *ht, const uint8_t *key);
+
+#endif /* Hash.h */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_pack.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_pack.h
new file mode 100644
index 0000000..2161045
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_pack.h
@@ -0,0 +1,67 @@
+/*
+<: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 BCMOS_PACK_H_
+#define BCMOS_PACK_H_
+
+
+/*
+ * Packing macros
+ *
+ * Usage:
+ * struct __PACKED_ATTR_START__ my_packed_struct
+ * {
+ *      ...
+ * } __PACKED_ATTR_END__ ;
+ *
+ */
+
+#ifdef __GNUC__
+
+#define __PACKED_ATTR_START__
+#define __PACKED_ATTR_END__ __attribute__ ((packed))
+
+#else
+
+#error define __PACKED_ATTR_START__,  __PACKED_ATTR_END__ for this compiler
+
+#endif
+
+/*
+ * Macros for bit-field manipulation
+ * For each field F requires 2 constants
+ * - F_S - field shift
+ * - F_W - field width
+ */
+#define BCM_FIELD_GET(_w, _f)           (((_w)>>_f ## _S) & ((1 << _f ## _W) - 1))
+#define BCM_FIELD(_f, _v)               ((_v & ((1 << _f ## _W) - 1)) << _f ## _S)
+#define BCM_FIELD_SET(_w, _f, _v)       (_w) |= BCM_FIELD(_f, _v)
+
+
+#endif /* BCMOS_PACK_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_platform.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_platform.h
new file mode 100644
index 0000000..7b40fb1
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_platform.h
@@ -0,0 +1,236 @@
+/*
+<: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 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
+
+/** BCM68620 CPU core
+ * \ingroup system_task */
+typedef enum
+{
+    BCMOS_CPU_CORE_ANY,                         /**< Any core */
+
+    BCMOS_CPU_CORE__NUM_OF = 1,                 /**< Number of cores */
+} bcmos_core;
+
+#define MAX_NUMBER_OF_PONS_ON_ALL_DEVICES (BCMTR_MAX_OLTS * BCMTR_MAX_INSTANCES)
+
+/** BCM68620 module
+ * \ingroup system_module
+ */
+typedef enum
+{
+    BCMOS_MODULE_ID_NONE,                       /**< no module */
+
+#ifdef BCMOS_SYS_UNITTEST
+    BCMOS_MODULE_ID_TEST1,
+    BCMOS_MODULE_ID_TEST2,
+#endif
+    /* Each Device (BCM6862X) must have its own dedicated Device Control Module at the host */
+    BCMOS_MODULE_ID_DEV_CTRL_DEV0,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV1,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV2,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV3,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV4,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV5,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV6,
+    BCMOS_MODULE_ID_DEV_CTRL_DEV7,
+
+    /* CLI over PCIe client */
+    BCMOS_MODULE_ID_CLI_OVER_PCIE,
+
+    /* Protection switching user application */
+    BCMOS_MODULE_ID_USER_APPL_PS,
+
+    /* Remote CLI */
+    BCMOS_MODULE_ID_REMOTE_CLI_DEV0,
+
+    /* Remote logger application (To support multiple devices need to add number of devices to previous value) */
+    BCMOS_MODULE_ID_USER_APPL_REMOTE_LOGGER_DEV0 = BCMOS_MODULE_ID_REMOTE_CLI_DEV0 + BCMTR_MAX_OLTS,
+
+    /* OMCI SW download user application (To support multiple devices need to add number of devices to previous value) */
+    BCMOS_MODULE_ID_USER_APPL_OMCI_SWDL_DEV0 = BCMOS_MODULE_ID_USER_APPL_REMOTE_LOGGER_DEV0 + BCMTR_MAX_OLTS,
+
+    /* GPON mac learning / aging user application (To support multiple devices need to add number of devices to previous value)*/
+    BCMOS_MODULE_ID_USER_APPL_GPON_MAC_LEARNING_DEV0 = BCMOS_MODULE_ID_USER_APPL_OMCI_SWDL_DEV0 + BCMTR_MAX_OLTS,
+
+    /* GPON stress user application (To support multiple devices need to add number of devices to previous value)*/
+    BCMOS_MODULE_ID_USER_APPL_GPON_STRESS_DEV0 = BCMOS_MODULE_ID_USER_APPL_GPON_MAC_LEARNING_DEV0 + BCMTR_MAX_OLTS,
+
+    /* GPON DS OMCI packets user application (To support multiple devices need to add number of devices to previous value)*/
+    BCMOS_MODULE_ID_USER_APPL_GPON_DS_OMCI0_DEV0 = BCMOS_MODULE_ID_USER_APPL_GPON_STRESS_DEV0 + BCMTR_MAX_OLTS,
+
+    /* GPON SN acquisition (To support multiple devices need to add number of devices multiply with max PON number to previous value)*/
+    BCMOS_MODULE_ID_USER_APPL_GPON_SN_ACQUISITION0_DEV0 = BCMOS_MODULE_ID_USER_APPL_GPON_DS_OMCI0_DEV0 + MAX_NUMBER_OF_PONS_ON_ALL_DEVICES,
+
+    /* GPON statistics (To support multiple devices need to add number of devices multiply with max PON number to previous value) */
+    BCMOS_MODULE_ID_USER_APPL_GPON_STATISTICS0_DEV0 = BCMOS_MODULE_ID_USER_APPL_GPON_SN_ACQUISITION0_DEV0 + MAX_NUMBER_OF_PONS_ON_ALL_DEVICES,
+
+    /* GPON RSSI user application (To support multiple devices need to add number of devices multiply with max PON number to previous value) */
+    BCMOS_MODULE_ID_USER_APPL_GPON_RSSI_DEV0 = BCMOS_MODULE_ID_USER_APPL_GPON_STATISTICS0_DEV0 + MAX_NUMBER_OF_PONS_ON_ALL_DEVICES,
+
+    /* EPON OAM negotiation application (To support multiple devices need to add number of devices to previous value)*/
+    BCMOS_MODULE_ID_USER_APPL_EON = BCMOS_MODULE_ID_USER_APPL_GPON_RSSI_DEV0 + BCMTR_MAX_OLTS,
+
+    /* EPON optical monitoring application */
+    BCMOS_MODULE_ID_USER_APPL_OMON = BCMOS_MODULE_ID_USER_APPL_EON + BCMTR_MAX_OLTS,
+
+    /* EPON Host driven encryption application */
+    BCMOS_MODULE_ID_USER_APPL_EPON_HDE,
+
+    BCMOS_MODULE_ID_USER_APPL_EPON_OAM,
+
+    BCMOS_MODULE_ID_USER_APPL_DPOE_SEC,
+
+    BCMOS_MODULE_ID_USER_APPL_IMAGE_TRANSFER0 = BCMOS_MODULE_ID_USER_APPL_DPOE_SEC + BCMTR_MAX_OLTS,
+    BCMOS_MODULE_ID_USER_APPL_IMAGE_TRANSFER1,
+
+	BCMOS_MODULE_ID_USER_APPL_ONU_TUNING_DEV0,
+	BCMOS_MODULE_ID_USER_APPL_ONU_TUNING_DEV1,
+
+    BCMOS_MODULE_ID__NUM_OF,                    /**< Number of modules */
+    BCMOS_MODULE_ID_INVALID = BCMOS_MODULE_ID_NONE
+} bcmos_module_id;
+
+/** BCM68620 event group. Each group supports up to 32 events.
+ * \ingroup system_event
+ */
+typedef enum
+{
+#ifdef BCMOS_SYS_UNITTEST
+    BCMOS_EVENT_ID_TEST1,
+    BCMOS_EVENT_ID_TEST2,
+#else
+    BCMOS_EVENT_ID_DUMMY,                       /* Currently OS s/w doesn't use events.
+                                                   Remove this constant when adding real events */
+#endif
+
+    BCMOS_EVENT_ID__NUM_OF,                     /**< Number of event groups */
+} bcmos_event_id;
+
+/** Message hash size
+ * \ingroup system_msg
+ */
+#define BCMOS_MSG_HASH_SIZE     512
+
+/** Maple OS message
+ * \ingroup system_msg
+ */
+typedef enum
+{
+    BCMOS_MSG_ID__BEGIN,
+
+    /* Internal messages */
+    BCMOS_MSG_ID_INTERNAL_TIMER = BCMOS_MSG_ID__BEGIN, /**< Internal "timer message" type */
+    BCMOS_MSG_ID_INTERNAL_EVENT,                       /**< Internal "event message" type */
+    BCMOS_MSG_ID_INTERNAL_IPC,
+
+    BCMOS_MSG_ID_INITIATE_RX_POWER,
+    BCMOS_MSG_ID_INITIATE_TRX_STATUS,
+    BCMOS_MSG_ID_INITIATE_ROGUE_SCAN,
+    BCMOS_MSG_ID_INITIATE_RSSI_READ,
+
+    BCMOS_MSG_ID_GPON_STRESS_START,
+    BCMOS_MSG_ID_GPON_STRESS_TIMEOUT,
+    BCMOS_MSG_ID_GPON_STRESS_ONU_DISCOVERED,
+    BCMOS_MSG_ID_GPON_STRESS_PON_DEACTIVATION_COMPLETED,
+    BCMOS_MSG_ID_GPON_STRESS_PON_ACTIVATION_COMPLETED,
+    BCMOS_MSG_ID_GPON_STRESS_ALL_ONUS_DEACTIVATION_COMPLETED,
+    BCMOS_MSG_ID_GPON_STRESS_ALL_ONUS_ACTIVATION_COMPLETED,
+    BCMOS_MSG_ID_GPON_STRESS_ONU_DEACTIVATION_COMPLETED,
+    BCMOS_MSG_ID_GPON_STRESS_ONU_ACTIVATION_COMPLETED,
+
+    BCMOS_MSG_ID_GPON_DS_OMCI_START,
+    BCMOS_MSG_ID_GPON_DS_OMCI_TIMEOUT,
+    BCMOS_MSG_ID_GPON_DS_OMCI_STOP,
+    BCMOS_MSG_ID_GPON_DS_OMCI_DEVICE_CONNECTED,
+    BCMOS_MSG_ID_GPON_DS_OMCI_DEVICE_DISCONNECTED,
+
+    BCMOS_MSG_ID_GPON_RSSI_START,
+
+    BCMOS_MSG_ID_GPON_STATISTICS_START,
+    BCMOS_MSG_ID_GPON_STATISTICS_TIMEOUT,
+    BCMOS_MSG_ID_GPON_STATISTICS_STOP,
+
+    BCMOS_MSG_ID_EON_START,
+    BCMOS_MSG_ID_EON_STOP,
+    BCMOS_MSG_ID_EON_PROXY_RX,
+
+    BCMOS_MSG_ID_EPON_OAM_PROXY_RX,
+    BCMOS_MSG_ID_EPON_OAM_TIMEOUT,
+
+    BCMOS_MSG_ID_DPOE_SEC_START,
+    BCMOS_MSG_ID_DPOE_SEC_RX_OAM,
+    BCMOS_MSG_ID_DPOE_SEC_RX_EAPOL,
+
+	BCMOS_MSG_ID_ONU_TUNING_START,
+	BCMOS_MSG_ID_ONU_TUNING_STOP,
+
+    BCMOS_MSG_ID__NONE,
+    BCMOS_MSG_ID__END,
+    BCMOS_MSG_ID__FORCE16 = 0x7fff
+} bcmos_msg_id;
+
+#define BCMOS_MSG_ID__NUM_OF (BCMOS_MSG_ID__END - BCMOS_MSG_ID__BEGIN)
+/*
+ * Task priorities
+ */
+
+#define TASK_PRIORITY_TRANSPORT_TX                  BCMOS_TASK_PRIORITY_3
+#define TASK_PRIORITY_TRANSPORT_RX                  BCMOS_TASK_PRIORITY_8
+#define TASK_PRIORITY_TRANSPORT_PROXY               BCMOS_TASK_PRIORITY_9
+#define TASK_PRIORITY_TRANSPORT_REMOTE_CLI          BCMOS_TASK_PRIORITY_9
+#define TASK_PRIORITY_DEVICE_CONTROL                BCMOS_TASK_PRIORITY_10
+#define TASK_PRIORITY_USER_APPL_PS                  BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_EON                 BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_OMON                BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_EPON_HDE            BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_DPOE_SEC            BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_MAC_LEARNING   BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_STRESS         BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_SN_ACQUISITION BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_DS_OMCI        BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_STATISTICS     BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_ONU_TUNING          BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_USER_APPL_GPON_RSSI           BCMOS_TASK_PRIORITY_12
+#define TASK_PRIORITY_CLI                           BCMOS_TASK_PRIORITY_15
+#define TASK_PRIORITY_USER_APPL_OMCI_SWDL           BCMOS_TASK_PRIORITY_17
+#define TASK_PRIORITY_USER_APPL_IMAGE_TRANSFER      BCMOS_TASK_PRIORITY_17
+#define TASK_PRIORITY_DEV_LOG_KERNEL                BCMOS_TASK_PRIORITY_20
+#define TASK_PRIORITY_DEV_LOG                       BCMOS_TASK_PRIORITY_30
+#define TASK_PRIORITY_USER_APPL_REMOTE_LOGGER       BCMOS_TASK_PRIORITY_30
+
+
+
+
+#endif /* BCMOS_PLATFORM_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_queue.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_queue.h
new file mode 100644
index 0000000..2172e4d
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_queue.h
@@ -0,0 +1,650 @@
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+/* #include <sys/cdefs.h> */
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *				SLIST	LIST	STAILQ	TAILQ
+ * _HEAD			+	+	+	+
+ * _HEAD_INITIALIZER		+	+	+	+
+ * _ENTRY			+	+	+	+
+ * _INIT			+	+	+	+
+ * _EMPTY			+	+	+	+
+ * _FIRST			+	+	+	+
+ * _NEXT			+	+	+	+
+ * _PREV			-	-	-	+
+ * _LAST			-	-	+	+
+ * _FOREACH			+	+	+	+
+ * _FOREACH_SAFE		+	+	+	+
+ * _FOREACH_REVERSE		-	-	-	+
+ * _FOREACH_REVERSE_SAFE	-	-	-	+
+ * _INSERT_HEAD			+	+	+	+
+ * _INSERT_BEFORE		-	+	-	+
+ * _INSERT_AFTER		+	+	+	+
+ * _INSERT_TAIL			-	-	+	+
+ * _CONCAT			-	-	+	+
+ * _REMOVE_AFTER		+	-	+	-
+ * _REMOVE_HEAD			+	-	+	-
+ * _REMOVE			+	+	+	+
+ *
+ */
+#ifdef QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+	char * lastfile;
+	int lastline;
+	char * prevfile;
+	int prevline;
+};
+
+#define	TRACEBUF	struct qm_trace trace;
+#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+
+#define	QMD_TRACE_HEAD(head) do {					\
+	(head)->trace.prevline = (head)->trace.lastline;		\
+	(head)->trace.prevfile = (head)->trace.lastfile;		\
+	(head)->trace.lastline = __LINE__;				\
+	(head)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#define	QMD_TRACE_ELEM(elem) do {					\
+	(elem)->trace.prevline = (elem)->trace.lastline;		\
+	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
+	(elem)->trace.lastline = __LINE__;				\
+	(elem)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#else
+#define	QMD_TRACE_ELEM(elem)
+#define	QMD_TRACE_HEAD(head)
+#define	TRACEBUF
+#define	TRASHIT(x)
+#endif	/* QUEUE_MACRO_DEBUG */
+
+/* Lint support requires types to be defined using typedefs.
+   No adding "struct" implicitly
+*/
+#ifdef USE_LINT
+#define _Q_TYPE_CAST(type)          (type *)
+#define _Q_TYPE_FIELD(type, field)  type field
+#else
+#define _Q_TYPE_CAST(type)          (struct type *)
+#define _Q_TYPE_FIELD(type, field)  struct type field
+#endif
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+    _Q_TYPE_FIELD(type, *slh_first);	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	SLIST_ENTRY(type)						\
+struct {								\
+    _Q_TYPE_FIELD(type, *sle_next);	/* next element */			\
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	SLIST_FIRST(head)	((head)->slh_first)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = SLIST_NEXT((var), field))
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
+	for ((varp) = &SLIST_FIRST((head));				\
+	    ((var) = *(varp)) != NULL;					\
+	    (varp) = &SLIST_NEXT((var), field))
+
+#define	SLIST_INIT(head) do {						\
+	SLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
+	SLIST_NEXT((slistelm), field) = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
+	SLIST_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	if (SLIST_FIRST((head)) == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+        _Q_TYPE_FIELD(type, *curelm) = SLIST_FIRST((head));		\
+		while (SLIST_NEXT(curelm, field) != (elm))		\
+			curelm = SLIST_NEXT(curelm, field);		\
+		SLIST_REMOVE_AFTER(curelm, field);			\
+	}								\
+	TRASHIT((elm)->field.sle_next);					\
+} while (0)
+
+#define SLIST_REMOVE_AFTER(elm, field) do {				\
+	SLIST_NEXT(elm, field) =					\
+	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+    _Q_TYPE_FIELD(type, *stqh_first);/* first element */			\
+    _Q_TYPE_FIELD(type, **stqh_last);/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+    _Q_TYPE_FIELD(type, *stqe_next);	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for((var) = STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = STAILQ_NEXT((var), field))
+
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST((head));				\
+	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;	                                \
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		_Q_TYPE_CAST(type)NULL :							\
+	        ((type *)(void *)				\
+		((char *)((head)->stqh_last) - offsetof(type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+        _Q_TYPE_FIELD(type, *curelm) = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		STAILQ_REMOVE_AFTER(head, curelm, field);		\
+	}								\
+	TRASHIT((elm)->field.stqe_next);				\
+} while (0)
+
+#define STAILQ_REMOVE_SAFE(head, elm, type, field) ({                   \
+        _Q_TYPE_FIELD(type, *curelm) = STAILQ_FIRST((head));            \
+        if (curelm == (elm)) {                                          \
+                STAILQ_REMOVE_HEAD((head), field);                      \
+        }                                                               \
+        else {                                                          \
+                while (curelm && STAILQ_NEXT(curelm, field) != (elm))   \
+                        curelm = STAILQ_NEXT(curelm, field);            \
+                if (curelm)                                             \
+                    STAILQ_REMOVE_AFTER(head, curelm, field);           \
+        };                                                              \
+        TRASHIT((elm)->field.stqe_next);                                \
+        curelm;                                                         \
+})
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
+	if ((STAILQ_NEXT(elm, field) =					\
+	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+} while (0)
+
+#define STAILQ_SWAP(head1, head2, type) do {				\
+    _Q_TYPE_FIELD(type, *swap_first) = STAILQ_FIRST(head1);			\
+    _Q_TYPE_FIELD(type, **swap_last) = (head1)->stqh_last;			\
+	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
+	(head1)->stqh_last = (head2)->stqh_last;			\
+	STAILQ_FIRST(head2) = swap_first;				\
+	(head2)->stqh_last = swap_last;					\
+	if (STAILQ_EMPTY(head1))					\
+		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
+	if (STAILQ_EMPTY(head2))					\
+		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
+} while (0)
+
+
+/*
+ * List declarations.
+ */
+#define	DLIST_HEAD(name, type)						\
+struct name {								\
+    _Q_TYPE_FIELD(type, *lh_first);	/* first element */			\
+}
+
+#define	DLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	DLIST_ENTRY(type)						\
+struct {								\
+    _Q_TYPE_FIELD(type, *le_next);	/* next element */			\
+    _Q_TYPE_FIELD(type, **le_prev);	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define	QMD_DLIST_CHECK_HEAD(head, field) do {				\
+	if (DLIST_FIRST((head)) != NULL &&				\
+	    DLIST_FIRST((head))->field.le_prev !=			\
+	     &DLIST_FIRST((head)))					\
+		panic("Bad list head %p first->prev != head", (head));	\
+} while (0)
+
+#define	QMD_DLIST_CHECK_NEXT(elm, field) do {				\
+	if (DLIST_NEXT((elm), field) != NULL &&				\
+	    DLIST_NEXT((elm), field)->field.le_prev !=			\
+	     &((elm)->field.le_next))					\
+	     	panic("Bad link elm %p next->prev != elm", (elm));	\
+} while (0)
+
+#define	QMD_DLIST_CHECK_PREV(elm, field) do {				\
+	if (*(elm)->field.le_prev != (elm))				\
+		panic("Bad link elm %p prev->next != elm", (elm));	\
+} while (0)
+#else
+#define	QMD_DLIST_CHECK_HEAD(head, field)
+#define	QMD_DLIST_CHECK_NEXT(elm, field)
+#define	QMD_DLIST_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define	DLIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	DLIST_FIRST(head)	((head)->lh_first)
+
+#define	DLIST_FOREACH(var, head, field)					\
+	for ((var) = DLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = DLIST_NEXT((var), field))
+
+#define	DLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = DLIST_FIRST((head));				\
+	    (var) && ((tvar) = DLIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	DLIST_INIT(head) do {						\
+	DLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	DLIST_INSERT_AFTER(listelm, elm, field) do {			\
+	QMD_DLIST_CHECK_NEXT(listelm, field);				\
+	if ((DLIST_NEXT((elm), field) = DLIST_NEXT((listelm), field)) != NULL)\
+		DLIST_NEXT((listelm), field)->field.le_prev =		\
+		    &DLIST_NEXT((elm), field);				\
+	DLIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &DLIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	DLIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	QMD_DLIST_CHECK_PREV(listelm, field);				\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	DLIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &DLIST_NEXT((elm), field);		\
+} while (0)
+
+#define	DLIST_INSERT_HEAD(head, elm, field) do {				\
+	QMD_DLIST_CHECK_HEAD((head), field);				\
+	if ((DLIST_NEXT((elm), field) = DLIST_FIRST((head))) != NULL)	\
+		DLIST_FIRST((head))->field.le_prev = &DLIST_NEXT((elm), field);\
+	DLIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &DLIST_FIRST((head));			\
+} while (0)
+
+#define	DLIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	DLIST_REMOVE(elm, field) do {				    \
+    if ((elm)->field.le_prev)  {                        \
+        QMD_DLIST_CHECK_NEXT(elm, field);				\
+        QMD_DLIST_CHECK_PREV(elm, field);				\
+        if (DLIST_NEXT((elm), field) != NULL)			\
+		    DLIST_NEXT((elm), field)->field.le_prev = 	\
+		        (elm)->field.le_prev;				    \
+		*(elm)->field.le_prev = DLIST_NEXT((elm), field);		\
+		TRASHIT((elm)->field.le_next);					\
+		TRASHIT((elm)->field.le_prev);					\
+    } \
+} while (0)
+
+#define DLIST_SWAP(head1, head2, type, field) do {			\
+    _Q_TYPE_FIELD(type, *swap_tmp) = DLIST_FIRST((head1));			\
+	DLIST_FIRST((head1)) = DLIST_FIRST((head2));			\
+	DLIST_FIRST((head2)) = swap_tmp;					\
+	if ((swap_tmp = DLIST_FIRST((head1))) != NULL)			\
+		swap_tmp->field.le_prev = &DLIST_FIRST((head1));		\
+	if ((swap_tmp = DLIST_FIRST((head2))) != NULL)			\
+		swap_tmp->field.le_prev = &DLIST_FIRST((head2));		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+    _Q_TYPE_FIELD(type, *tqh_first);	/* first element */			\
+    _Q_TYPE_FIELD(type, **tqh_last);	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+    _Q_TYPE_FIELD(type, *tqe_next);	    /* next element */			\
+    _Q_TYPE_FIELD(type, **tqe_prev);	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
+/*
+ * Tail queue functions.
+ */
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
+	if (!TAILQ_EMPTY(head) &&					\
+	    TAILQ_FIRST((head))->field.tqe_prev !=			\
+	     &TAILQ_FIRST((head)))					\
+		panic("Bad tailq head %p first->prev != head", (head));	\
+} while (0)
+
+#define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
+	if (*(head)->tqh_last != NULL)					\
+	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
+} while (0)
+
+#define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
+	if (TAILQ_NEXT((elm), field) != NULL &&				\
+	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
+	     &((elm)->field.tqe_next))					\
+		panic("Bad link elm %p next->prev != elm", (elm));	\
+} while (0)
+
+#define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
+	if (*(elm)->field.tqe_prev != (elm))				\
+		panic("Bad link elm %p prev->next != elm", (elm));	\
+} while (0)
+#else
+#define	QMD_TAILQ_CHECK_HEAD(head, field)
+#define	QMD_TAILQ_CHECK_TAIL(head, headname)
+#define	QMD_TAILQ_CHECK_NEXT(elm, field)
+#define	QMD_TAILQ_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+		QMD_TRACE_HEAD(head1);					\
+		QMD_TRACE_HEAD(head2);					\
+	}								\
+} while (0)
+
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    &TAILQ_NEXT((elm), field);				\
+	else {								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	QMD_TAILQ_CHECK_PREV(listelm, field);				\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	QMD_TAILQ_CHECK_HEAD(head, field);				\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	QMD_TAILQ_CHECK_TAIL(head, field);				\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	QMD_TAILQ_CHECK_NEXT(elm, field);				\
+	QMD_TAILQ_CHECK_PREV(elm, field);				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT((elm)->field.tqe_next);					\
+	TRASHIT((elm)->field.tqe_prev);					\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define TAILQ_SWAP(head1, head2, type, field) do {			\
+    _Q_TYPE_FIELD(type, *swap_first) = (head1)->tqh_first;			\
+    _Q_TYPE_FIELD(type, **swap_last) = (head1)->tqh_last;			\
+	(head1)->tqh_first = (head2)->tqh_first;			\
+	(head1)->tqh_last = (head2)->tqh_last;				\
+	(head2)->tqh_first = swap_first;				\
+	(head2)->tqh_last = swap_last;					\
+	if ((swap_first = (head1)->tqh_first) != NULL)			\
+		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
+	else								\
+		(head1)->tqh_last = &(head1)->tqh_first;		\
+	if ((swap_first = (head2)->tqh_first) != NULL)			\
+		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
+	else								\
+		(head2)->tqh_last = &(head2)->tqh_first;		\
+} while (0)
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.c b/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.c
new file mode 100644
index 0000000..27eb5e0
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.c
@@ -0,0 +1,124 @@
+/*
+<: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_rw_lock.h"
+
+struct bcmos_rw_lock
+{
+    /* the actual lock, held by the writer, used by the reader to safely obtain a read lock, but not held to allow
+     * multiple readers */
+    bcmos_mutex lock;
+    /* used by the writer to prevent new readers from obtaining read locks while a writer is waiting */
+    bcmos_mutex read_lock;
+    /* used by readers to signal waiting writers that they have finished reading */
+    bcmos_sem write_lock;
+    /* current number of readers */
+    uint32_t readers;
+};
+
+bcmos_errno bcmos_rw_lock_create(bcmos_rw_lock **lock)
+{
+    bcmos_errno err;
+    *lock = (bcmos_rw_lock*)bcmos_calloc(sizeof(bcmos_rw_lock));
+    if (*lock == NULL)
+    {
+        BUG();
+        return BCM_ERR_NOMEM;
+    }
+    if (BCM_ERR_OK != (err = bcmos_mutex_create(&(*lock)->lock, 0, "bcmos_rw_lock_create_lock")))
+    {
+        BUG();
+        return err;
+    }
+    if (BCM_ERR_OK != (err = bcmos_mutex_create(&(*lock)->read_lock, 0, "bcmos_rw_lock_create_rw_lock")))
+    {
+        BUG();
+        return err;
+    }
+    (*lock)->readers = 0;
+    if (BCM_ERR_OK != (err = bcmos_sem_create(&(*lock)->write_lock, 1, 0, "bcmos_rw_lock_create_write_lock")))
+    {
+        BUG();
+        return err;
+    }
+    return err;
+}
+
+/*lint -e{455} suppress "thread mutex has not been locked" */
+void bcmos_rw_write_lock(bcmos_rw_lock* lock)
+{
+    /* prevent any new readers from trying to obtain a read lock */
+    bcmos_mutex_lock(&lock->read_lock);
+    /* lock the actual lock */
+    bcmos_mutex_lock(&lock->lock);
+    while (lock->readers != 0)
+    {
+        /* there are still readers holding read locks, release the lock */
+        bcmos_mutex_unlock(&lock->lock);
+        /* wait for the signal from the last reader before trying again */
+        bcmos_sem_wait(&lock->write_lock, BCMOS_WAIT_FOREVER);
+        /* lock the actual lock and check for readers again */
+        bcmos_mutex_lock(&lock->lock);
+    }
+    /* no more readers, allow new readers to wait on the lock */
+    bcmos_mutex_unlock(&lock->read_lock);
+}
+/*lint +e{454} suppress "thread mutex has not been locked" */
+
+void bcmos_rw_write_release(bcmos_rw_lock* lock)
+{
+    /*lint --e{455} suppress "thread mutex has not been locked" */
+    bcmos_mutex_unlock(&lock->lock);
+}
+
+void bcmos_rw_read_lock(bcmos_rw_lock* lock)
+{
+    /* wait for anyone trying to get a write lock */
+    bcmos_mutex_lock(&lock->read_lock);
+    /* wait for the lock to be released */
+    bcmos_mutex_lock(&lock->lock);
+    lock->readers++;
+    /* reset the signal to the writers */
+    bcmos_sem_wait(&lock->write_lock, BCMOS_NO_WAIT);
+    /* all done, release everything so other readers can get a read lock */
+    bcmos_mutex_unlock(&lock->lock);
+    bcmos_mutex_unlock(&lock->read_lock);
+}
+
+void bcmos_rw_read_release(bcmos_rw_lock* lock)
+{
+    /* get a lock to prevent interruptions */
+    bcmos_mutex_lock(&lock->lock);
+    if (--lock->readers == 0)
+    {
+        /* if we're the last reader, signal that the lock is available for a writer */
+        bcmos_sem_post(&lock->write_lock);
+    }
+    bcmos_mutex_unlock(&lock->lock);
+}
+
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.h
new file mode 100644
index 0000000..b12d533
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_rw_lock.h
@@ -0,0 +1,66 @@
+/*
+<: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.
+
+:>
+ */
+
+/** A write-biased readers-writer lock
+ *  NOTE: DO NOT attempt to obtain a write lock on a thread that is already holding a read lock or vice versa - this
+ *  will result in a deadlock. Multiple read locks from the same thread are safe, multiple write locks are NOT.
+ */
+#ifndef BCMOS_RW_LOCK_H_
+#define BCMOS_RW_LOCK_H_
+#include "bcmos_system.h"
+
+typedef struct bcmos_rw_lock bcmos_rw_lock;
+
+/** Initialize a lock
+ *  \param[out] lock    the newly created lock
+ *  \return error code
+ */
+bcmos_errno bcmos_rw_lock_create(bcmos_rw_lock **lock);
+
+/** Obtain a write lock
+ *  \param[in] lock     the lock to operate on
+ */
+void bcmos_rw_write_lock(bcmos_rw_lock* lock);
+
+/** Release a write lock
+ *  \param[in] lock     the lock to operate on
+ */
+void bcmos_rw_write_release(bcmos_rw_lock* lock);
+
+/** Obtain a read lock
+ *  \param[in] lock     the lock to operate on
+ */
+void bcmos_rw_read_lock(bcmos_rw_lock* lock);
+
+/** Release a read lock
+ *  \param[in] lock     the lock to operate on
+ */
+void bcmos_rw_read_release(bcmos_rw_lock* lock);
+
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_sysif.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_sysif.h
new file mode 100644
index 0000000..43df6dc
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_sysif.h
@@ -0,0 +1,93 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmos_sysif.h
+ *
+ * This internal header file includes OS-specific services
+ * that are referred in OS-independent OS abstraction implementation
+ *
+ */
+
+#ifndef BCMOS_SYSIF_H_
+#define BCMOS_SYSIF_H_
+
+/*
+ * OS-specific init
+ */
+
+/** Initialize system library
+ * Must be called before any other system function
+ * \returns 0=OK or error code <0
+ */
+bcmos_errno bcmos_sys_init(void);
+
+/** Clean-up system library
+ */
+void bcmos_sys_exit(void);
+
+
+/*
+ * Timer support
+ */
+
+/* OS abstraction must define struct bcmos_sys_timer
+ */
+typedef struct bcmos_sys_timer bcmos_sys_timer;
+
+/* System timer handler. Implemented in common OS abstraction services */
+typedef void (*bcmos_sys_timer_handler)(void *data);
+
+/* Create system timer
+ * It is expected that only one high-resolution system timer is needed.
+ * It is used to "kick" timer pool implemented in OS abstraction
+ * \param[in]   timer   System timer
+ * \param[in]   handler Timer handler
+ * \param[in]   data    Data to be passed to the handler
+ * \returns 0 if OK or error < 0
+ */
+bcmos_errno bcmos_sys_timer_create(bcmos_sys_timer *timer, bcmos_sys_timer_handler handler, void *data);
+
+/* Destroy system timer
+ * \param[in]   timer   System timer
+ */
+void bcmos_sys_timer_destroy(bcmos_sys_timer *timer);
+
+/* Start system timer
+ * \param[in]   timer           System timer
+ * \param[in]   interval        Interval (us)
+ */
+void bcmos_sys_timer_start(bcmos_sys_timer *timer, uint32_t interval);
+
+/* Stop system timer
+ * \param[in]   timer           System timer
+ */
+void bcmos_sys_timer_stop(bcmos_sys_timer *timer);
+
+#endif /* BCMOS_SYSIF_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_tree.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_tree.h
new file mode 100755
index 0000000..82d9164
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_tree.h
@@ -0,0 +1,765 @@
+/*	$NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $	*/
+/*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
+/* $FreeBSD$ */
+
+/*-
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_BCMOS_TREE_H_
+#define	_BCMOS_TREE_H_
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure.  Every operation
+ * on the tree causes a splay to happen.  The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree.  On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n).  The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute.  It fulfills a set of conditions:
+ *	- every search path from the root to a leaf consists of the
+ *	  same number of black nodes,
+ *	- each red node (except for the root) has a black parent,
+ *	- each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type)						\
+struct name {								\
+	type *sph_root; /* root of the tree */			        \
+}
+
+#define SPLAY_INITIALIZER(root)						\
+	{ NULL }
+
+#define SPLAY_INIT(root) do {						\
+	(root)->sph_root = NULL;					\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ENTRY(type)						\
+struct {								\
+	type *spe_left; /* left element */			        \
+	type *spe_right; /* right element */			        \
+}
+
+#define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
+#define SPLAY_ROOT(head)		(head)->sph_root
+#define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (/*CONSTCOND*/ 0)
+	
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do {				\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do {				\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
+	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
+	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp)				\
+void name##_SPLAY(struct name *, type *);			        \
+void name##_SPLAY_MINMAX(struct name *, int);				\
+type *name##_SPLAY_INSERT(struct name *, type *);		        \
+type *name##_SPLAY_REMOVE(struct name *, type *);		        \
+									\
+/* Finds the node with the same key as elm */				\
+static __inline type *						        \
+name##_SPLAY_FIND(struct name *head, type *elm)			        \
+{									\
+	if (SPLAY_EMPTY(head))						\
+		return(NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0)				\
+		return (head->sph_root);				\
+	return (NULL);							\
+}									\
+									\
+static __inline type *						        \
+name##_SPLAY_NEXT(struct name *head, type *elm)			        \
+{									\
+	name##_SPLAY(head, elm);					\
+	if (SPLAY_RIGHT(elm, field) != NULL) {				\
+		elm = SPLAY_RIGHT(elm, field);				\
+		while (SPLAY_LEFT(elm, field) != NULL) {		\
+			elm = SPLAY_LEFT(elm, field);			\
+		}							\
+	} else								\
+		elm = NULL;						\
+	return (elm);							\
+}									\
+									\
+static __inline type *						        \
+name##_SPLAY_MIN_MAX(struct name *head, int val)			\
+{									\
+	name##_SPLAY_MINMAX(head, val);					\
+        return (SPLAY_ROOT(head));					\
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp)				\
+type *								        \
+name##_SPLAY_INSERT(struct name *head, type *elm)		        \
+{									\
+    if (SPLAY_EMPTY(head)) {						\
+	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
+    } else {								\
+	    int __comp;							\
+	    name##_SPLAY(head, elm);					\
+	    __comp = (cmp)(elm, (head)->sph_root);			\
+	    if(__comp < 0) {						\
+		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
+		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
+		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
+	    } else if (__comp > 0) {					\
+		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
+		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
+		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
+	    } else							\
+		    return ((head)->sph_root);				\
+    }									\
+    (head)->sph_root = (elm);						\
+    return (NULL);							\
+}									\
+									\
+type *								        \
+name##_SPLAY_REMOVE(struct name *head, type *elm)		        \
+{									\
+	type *__tmp;						        \
+	if (SPLAY_EMPTY(head))						\
+		return (NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0) {			\
+		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
+			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
+		} else {						\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
+			name##_SPLAY(head, elm);			\
+			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
+		}							\
+		return (elm);						\
+	}								\
+	return (NULL);							\
+}									\
+									\
+void									\
+name##_SPLAY(struct name *head, type *elm)			        \
+{									\
+	type __node, *__left, *__right, *__tmp;			        \
+	int __comp;							\
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {		\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) < 0){			\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) > 0){			\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}									\
+									\
+/* Splay with either the minimum or the maximum element			\
+ * Used to find minimum or maximum element in tree.			\
+ */									\
+void name##_SPLAY_MINMAX(struct name *head, int __comp)                 \
+{									\
+	type __node, *__left, *__right, *__tmp;			        \
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while (1) {							\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp < 0){				\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp > 0) {				\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}
+
+#define SPLAY_NEGINF	-1
+#define SPLAY_INF	1
+
+#define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head)					\
+	for ((x) = SPLAY_MIN(name, head);				\
+	     (x) != NULL;						\
+	     (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type)						\
+struct name {								\
+	type *rbh_root; /* root of the tree */			        \
+}
+
+#define RB_INITIALIZER(root)						\
+	{ NULL }
+
+#define RB_INIT(root) do {						\
+	(root)->rbh_root = NULL;					\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_BLACK	0
+#define RB_RED		1
+#define RB_ENTRY(type)							\
+struct {								\
+	type *rbe_left;		/* left element */		        \
+	type *rbe_right;		/* right element */		\
+	type *rbe_parent;	/* parent element */		        \
+	int rbe_color;			/* node color */		\
+}
+
+#define RB_LEFT(elm, field)		(elm)->field.rbe_left
+#define RB_RIGHT(elm, field)		(elm)->field.rbe_right
+#define RB_PARENT(elm, field)		(elm)->field.rbe_parent
+#define RB_COLOR(elm, field)		(elm)->field.rbe_color
+#define RB_ROOT_NODE(head)		(head)->rbh_root
+#define RB_EMPTY(head)			(RB_ROOT_NODE(head) == NULL)
+
+#define RB_SET(elm, parent, field) do {					\
+	RB_PARENT(elm, field) = parent;					\
+	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
+	RB_COLOR(elm, field) = RB_RED;					\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_SET_BLACKRED(black, red, field) do {				\
+	RB_COLOR(black, field) = RB_BLACK;				\
+	RB_COLOR(red, field) = RB_RED;					\
+} while (/*CONSTCOND*/ 0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)	do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
+	(tmp) = RB_RIGHT(elm, field);					\
+	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {	\
+		RB_PARENT(RB_LEFT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_LEFT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
+	(tmp) = RB_LEFT(elm, field);					\
+	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {	\
+		RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_RIGHT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+#define	RB_PROTOTYPE(name, type, field, cmp)				\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define	RB_PROTOTYPE_STATIC(name, type, field, cmp)			\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)		\
+attr void name##_RB_INSERT_COLOR(struct name *, type *);		\
+attr void name##_RB_REMOVE_COLOR(struct name *, type *, type *);        \
+attr type *name##_RB_REMOVE(struct name *, type *);	                \
+attr type *name##_RB_INSERT(struct name *, type *);	                \
+attr type *name##_RB_FIND(struct name *, type *);		        \
+attr type *name##_RB_NFIND(struct name *, type *);	                \
+attr type *name##_RB_NEXT(type *);			                \
+attr type *name##_RB_PREV(type *);			                \
+attr type *name##_RB_MINMAX(struct name *, int);			\
+									\
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define	RB_GENERATE(name, type, field, cmp)				\
+	RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define	RB_GENERATE_STATIC(name, type, field, cmp)			\
+	RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_GENERATE_INLINE(name, type, field, cmp)                      \
+        RB_GENERATE_INTERNAL(name, type, field, cmp, static inline)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)		\
+attr void								\
+name##_RB_INSERT_COLOR(struct name *head, type *elm)		        \
+{									\
+	type *parent, *gparent, *tmp;				        \
+	while ((parent = RB_PARENT(elm, field)) != NULL &&		\
+	    RB_COLOR(parent, field) == RB_RED) {			\
+		gparent = RB_PARENT(parent, field);			\
+		if (parent == RB_LEFT(gparent, field)) {		\
+			tmp = RB_RIGHT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_RIGHT(parent, field) == elm) {		\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_RIGHT(head, gparent, tmp, field);	\
+		} else {						\
+			tmp = RB_LEFT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_LEFT(parent, field) == elm) {		\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_LEFT(head, gparent, tmp, field);	\
+		}							\
+	}								\
+	RB_COLOR(head->rbh_root, field) = RB_BLACK;			\
+}									\
+									\
+attr void								\
+name##_RB_REMOVE_COLOR(struct name *head, type *parent, type *elm)      \
+{									\
+	type *tmp;						        \
+	while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&	\
+	    elm != RB_ROOT_NODE(head)) {				\
+		if (RB_LEFT(parent, field) == elm) {			\
+			tmp = RB_RIGHT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = RB_RIGHT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_RIGHT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
+					type *oleft;		\
+					if ((oleft = RB_LEFT(tmp, field)) \
+					    != NULL)			\
+						RB_COLOR(oleft, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_RIGHT(head, tmp, oleft, field);\
+					tmp = RB_RIGHT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_RIGHT(tmp, field))		\
+					RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				elm = RB_ROOT_NODE(head);		\
+				break;					\
+			}						\
+		} else {						\
+			tmp = RB_LEFT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = RB_LEFT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_LEFT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
+					type *oright;		\
+					if ((oright = RB_RIGHT(tmp, field)) \
+					    != NULL)			\
+						RB_COLOR(oright, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_LEFT(head, tmp, oright, field);\
+					tmp = RB_LEFT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_LEFT(tmp, field))		\
+					RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				elm = RB_ROOT_NODE(head);		\
+				break;					\
+			}						\
+		}							\
+	}								\
+	if (elm)							\
+		RB_COLOR(elm, field) = RB_BLACK;			\
+}									\
+									\
+attr type *							        \
+name##_RB_REMOVE(struct name *head, type *elm)			        \
+{									\
+	type *child, *parent, *old = elm;			        \
+	int color;							\
+	if (RB_LEFT(elm, field) == NULL)				\
+		child = RB_RIGHT(elm, field);				\
+	else if (RB_RIGHT(elm, field) == NULL)				\
+		child = RB_LEFT(elm, field);				\
+	else {								\
+		type *left;					        \
+		elm = RB_RIGHT(elm, field);				\
+		while ((left = RB_LEFT(elm, field)) != NULL)		\
+			elm = left;					\
+		child = RB_RIGHT(elm, field);				\
+		parent = RB_PARENT(elm, field);				\
+		color = RB_COLOR(elm, field);				\
+		if (child)						\
+			RB_PARENT(child, field) = parent;		\
+		if (parent) {						\
+			if (RB_LEFT(parent, field) == elm)		\
+				RB_LEFT(parent, field) = child;		\
+			else						\
+				RB_RIGHT(parent, field) = child;	\
+			RB_AUGMENT(parent);				\
+		} else							\
+			RB_ROOT_NODE(head) = child;			\
+		if (RB_PARENT(elm, field) == old)			\
+			parent = elm;					\
+		(elm)->field = (old)->field;				\
+		if (RB_PARENT(old, field)) {				\
+			if (RB_LEFT(RB_PARENT(old, field), field) == old)\
+				RB_LEFT(RB_PARENT(old, field), field) = elm;\
+			else						\
+				RB_RIGHT(RB_PARENT(old, field), field) = elm;\
+			RB_AUGMENT(RB_PARENT(old, field));		\
+		} else							\
+			RB_ROOT_NODE(head) = elm;			\
+		RB_PARENT(RB_LEFT(old, field), field) = elm;		\
+		if (RB_RIGHT(old, field))				\
+			RB_PARENT(RB_RIGHT(old, field), field) = elm;	\
+		if (parent) {						\
+			left = parent;					\
+			do {						\
+				RB_AUGMENT(left);			\
+			} while ((left = RB_PARENT(left, field)) != NULL); \
+		}							\
+		goto color;						\
+	}								\
+	parent = RB_PARENT(elm, field);					\
+	color = RB_COLOR(elm, field);					\
+	if (child)							\
+		RB_PARENT(child, field) = parent;			\
+	if (parent) {							\
+		if (RB_LEFT(parent, field) == elm)			\
+			RB_LEFT(parent, field) = child;			\
+		else							\
+			RB_RIGHT(parent, field) = child;		\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT_NODE(head) = child;				\
+color:									\
+	if (color == RB_BLACK)						\
+		name##_RB_REMOVE_COLOR(head, parent, child);		\
+	return (old);							\
+}									\
+									\
+/* Inserts a node into the RB tree */					\
+attr type *							        \
+name##_RB_INSERT(struct name *head, type *elm)			        \
+{									\
+	type *tmp;						        \
+	type *parent = NULL;					        \
+	int comp = 0;							\
+	tmp = RB_ROOT_NODE(head);					\
+	while (tmp) {							\
+		parent = tmp;						\
+		comp = (cmp)(elm, parent);				\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	RB_SET(elm, parent, field);					\
+	if (parent != NULL) {						\
+		if (comp < 0)						\
+			RB_LEFT(parent, field) = elm;			\
+		else							\
+			RB_RIGHT(parent, field) = elm;			\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT_NODE(head) = elm;				\
+	name##_RB_INSERT_COLOR(head, elm);				\
+	return (NULL);							\
+}									\
+									\
+/* Finds the node with the same key as elm */				\
+attr type *							        \
+name##_RB_FIND(struct name *head, type *elm)			        \
+{									\
+	type *tmp = RB_ROOT_NODE(head);				        \
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (NULL);							\
+}									\
+									\
+/* Finds the first node greater than or equal to the search key */	\
+attr type *							        \
+name##_RB_NFIND(struct name *head, type *elm)			        \
+{									\
+	type *tmp = RB_ROOT_NODE(head);				        \
+	type *res = NULL;					        \
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0) {						\
+			res = tmp;					\
+			tmp = RB_LEFT(tmp, field);			\
+		}							\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (res);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr type *							        \
+name##_RB_NEXT(type *elm)					        \
+{									\
+	if (RB_RIGHT(elm, field)) {					\
+		elm = RB_RIGHT(elm, field);				\
+		while (RB_LEFT(elm, field))				\
+			elm = RB_LEFT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr type *							\
+name##_RB_PREV(type *elm)					\
+{									\
+	if (RB_LEFT(elm, field)) {					\
+		elm = RB_LEFT(elm, field);				\
+		while (RB_RIGHT(elm, field))				\
+			elm = RB_RIGHT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+attr type *							        \
+name##_RB_MINMAX(struct name *head, int val)				\
+{									\
+	type *tmp = RB_ROOT_NODE(head);				        \
+	type *parent = NULL;					        \
+	while (tmp) {							\
+		parent = tmp;						\
+		if (val < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else							\
+			tmp = RB_RIGHT(tmp, field);			\
+	}								\
+	return (parent);						\
+}
+
+#define RB_NEGINF	-1
+#define RB_INF	1
+
+#define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y)	name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
+#define RB_PREV(name, x, y)	name##_RB_PREV(y)
+#define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head)					\
+	for ((x) = RB_MIN(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_FROM(x, name, y)					\
+	for ((x) = (y);							\
+	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
+	     (x) = (y))
+
+#define RB_FOREACH_SAFE(x, name, head, y)				\
+	for ((x) = RB_MIN(name, head);					\
+	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
+	     (x) = (y))
+
+#define RB_FOREACH_REVERSE(x, name, head)				\
+	for ((x) = RB_MAX(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_PREV(x))
+
+#define RB_FOREACH_REVERSE_FROM(x, name, y)				\
+	for ((x) = (y);							\
+	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
+	     (x) = (y))
+
+#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)			\
+	for ((x) = RB_MAX(name, head);					\
+	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
+	     (x) = (y))
+
+#endif	/* _BCMOS_TREE_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/bcmos_types.h b/bcm68620_release/release/host_customized/os_abstraction/bcmos_types.h
new file mode 100644
index 0000000..21f0191
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/bcmos_types.h
@@ -0,0 +1,208 @@
+/*
+<: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 BCMOS_TYPES_H_
+#define BCMOS_TYPES_H_
+
+#ifndef BCMOS_SYSTEM_H_
+#error Please do not include bcmos_types.h directly. Include bcmos_system.h
+#endif
+
+#include "bcmos_pack.h"
+
+/** \defgroup system_types Generic types
+ * @{
+ */
+
+/*
+ * Limits of integer types.
+ */
+
+/* Minimum of signed integer types.  */
+#ifndef INT8_MIN
+#define INT8_MIN       (0x80)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN      (0x8000)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN      (0x80000000)
+#endif
+#ifndef INT64_MIN
+#define INT64_MIN      (0x8000000000000000)
+#endif
+
+/* Maximum of signed integer types.  */
+#ifndef INT8_MAX
+#define INT8_MAX       (0x7F)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX      (0x7FFF)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX      (0x7FFFFFFF)
+#endif
+#ifndef INT64_MAX
+#define INT64_MAX      (0x7FFFFFFFFFFFFFFF)
+#endif
+
+/* Maximum of unsigned integer types.  */
+#ifndef UINT8_MAX
+#define UINT8_MAX      (0xFF)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX     (0xFFFF)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX     (0xFFFFFFFF)
+#endif
+#ifndef UINT64_MAX
+#define UINT64_MAX     (0xFFFFFFFFFFFFFFFF)
+#endif
+
+
+/** Endianness */
+#define BCMOS_ENDIAN_BIG        0
+#define BCMOS_ENDIAN_LITTLE     1
+
+typedef enum
+{
+    BCMOS_ENDIAN_BIG_E          = BCMOS_ENDIAN_BIG,
+    BCMOS_ENDIAN_LITTLE_E       = BCMOS_ENDIAN_LITTLE,
+} bcmos_endian;
+
+/* If endianness is not set explicitly, try to autodetect it.
+ * Modern gcc versions (over 4.8) define __BYTE_ORDER__
+ * see "gcc -E -dM - < /dev/null | grep ENDIAN"
+ */
+#ifndef BCM_CPU_ENDIAN
+
+#ifdef __BYTE_ORDER__
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define BCM_CPU_ENDIAN BCMOS_ENDIAN_LITTLE
+#else
+#define BCM_CPU_ENDIAN BCMOS_ENDIAN_BIG
+#endif
+
+#else
+
+/* We are dealing with compiler that doesn't set __BYTE_ORDER__.
+ * If it is simulation build than it must be LE x86.
+ * Otherwise, no way to tell.
+ */
+#ifdef SIMULATION_BUILD
+#define BCM_CPU_ENDIAN BCMOS_ENDIAN_LITTLE
+#endif
+
+#endif /* #ifdef __BYTE_ORDER */
+
+#endif /* #ifndef BCM_CPU_ENDIAN */
+
+#include <bcm_config.h>
+
+/** 24-bit unsigned integer */
+typedef union
+{
+    uint8_t u8[3];
+    struct __PACKED_ATTR_START__
+    {
+#if (BCM_CPU_ENDIAN == BCMOS_ENDIAN_BIG)
+        uint8_t hi;
+        uint8_t mid;
+        uint8_t low;
+#elif (BCM_CPU_ENDIAN == BCMOS_ENDIAN_LITTLE)
+        uint8_t low;
+        uint8_t mid;
+        uint8_t hi;
+#else
+#error BCM_CPU_ENDIAN must be BCMOS_ENDIAN_BIG or _LITTLE
+#endif
+    } __PACKED_ATTR_END__ low_hi;
+} uint24_t;
+
+static inline uint32_t uint24_to_32(uint24_t u24)
+{
+    return (u24.low_hi.hi << 16) | (u24.low_hi.mid << 8) | u24.low_hi.low;
+}
+
+static inline uint24_t uint32_to_24(uint32_t u32)
+{
+    return (uint24_t){ .low_hi= { .hi = (u32 >> 16) & 0xff, .mid = (u32 >> 8) & 0xff, .low = u32 & 0xff } };
+}
+
+/** VLAN tag (CoS/CFI/VID) */
+typedef uint16_t bcmos_vlan_tag;
+
+#define BCMOS_ETH_ALEN   6
+
+/** MAC address */
+typedef struct
+{
+    uint8_t u8[BCMOS_ETH_ALEN];
+} bcmos_mac_address;
+
+/** IPv4 address. It is stored in network byte order. */
+typedef union
+{
+    uint32_t u32;
+    uint8_t u8[4];
+} bcmos_ipv4_address;
+
+/** IPv6 address */
+typedef uint8_t bcmos_ipv6_address[16];
+
+static inline void bcmos_mac_address_init(bcmos_mac_address *mac)
+{
+    memset(mac, 0, sizeof(*mac));
+}
+
+static inline void bcmos_ipv4_address_init(bcmos_ipv4_address *ip)
+{
+    memset(ip, 0, sizeof(*ip));
+}
+
+#ifndef CFE_BUILD
+static inline char *bcmos_inet_ntoa(bcmos_ipv4_address *ip, char *ip_str)
+{
+    snprintf(ip_str, 16, "%u.%u.%u.%u", ip->u8[0], ip->u8[1], ip->u8[2], ip->u8[3]);
+
+    return ip_str;
+}
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({            \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (long)__mptr - offsetof(type,member) );})
+#endif
+
+/** @} */
+
+#endif /* BCMOS_TYPES_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmolt_model_data_cfe_ext.h b/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmolt_model_data_cfe_ext.h
new file mode 100644
index 0000000..ddca9ce
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmolt_model_data_cfe_ext.h
@@ -0,0 +1,92 @@
+/*
+<:copyright-BRCM:2016:proprietary:standard
+
+   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+   All Rights Reserved
+
+This program is the proprietary software of Broadcom Corporation and/or its
+licensors, and may only be used, duplicated, modified or distributed pursuant
+to the terms and conditions of a separate, written license agreement executed
+between you and Broadcom (an "Authorized License").  Except as set forth in
+an Authorized License, Broadcom grants no license (express or implied), right
+to use, or waiver of any kind with respect to the Software, and Broadcom
+expressly reserves all rights in and to the Software and all intellectual
+property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
+
+Except as expressly set forth in the Authorized License,
+
+1. This program, including its structure, sequence and organization,
+    constitutes the valuable trade secrets of Broadcom, and you shall use
+    all reasonable efforts to protect the confidentiality thereof, and to
+    use this information only in connection with your use of Broadcom
+    integrated circuit products.
+
+2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+    AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+    WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+    RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+    ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+    FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+    COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+    TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+    PERFORMANCE OF THE SOFTWARE.
+
+3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+    ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+    INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+    WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+    IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+    OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+    SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+    SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+    LIMITED REMEDY.
+:>
+*/
+
+#ifndef BCMOS_MODEL_DATA_CFE_EXT_H_
+#define BCMOS_MODEL_DATA_CFE_EXT_H_
+
+#include "bcmolt_model_data.h"
+
+typedef struct
+{
+    bcmolt_system_mode system_mode;
+    bcmolt_device_nni_speed nni_speed;
+    bcmos_bool use_prev_nni_serdes_firmware;
+} db_rec_device;
+
+/* System mode */
+static bcmolt_system_mode device_system_mode;
+
+/** Set system mode
+ * \param[in]  dev            Device id
+ * \param[in]  system_mode    System mode
+ * \returns BCM_ERR_OK, BCM_ERR_NOT_SUPPORTED
+ */
+static inline bcmos_errno bcmolt_system_mode_set(uint16_t dev, bcmolt_system_mode system_mode)
+{
+    device_system_mode = system_mode;
+    return BCM_ERR_OK;
+}
+
+/** Get system mode
+ * \param[in]  dev            Device id
+ * \param[in]  system_mode    System mode
+ * \returns BCM_ERR_OK
+ */
+static inline bcmos_errno bcmolt_system_mode_get(uint16_t dev, bcmolt_system_mode *system_mode)
+{
+    *system_mode = device_system_mode;
+    return BCM_ERR_OK;
+}
+
+
+static inline int is_issu_boot(void)
+{
+    return BCMOS_FALSE;
+}
+
+
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmos_system.h b/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmos_system.h
new file mode 100644
index 0000000..763cc79
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/cfe/bcmos_system.h
@@ -0,0 +1,138 @@
+/*
+<:copyright-BRCM:2016:proprietary:standard
+
+   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+   All Rights Reserved
+
+This program is the proprietary software of Broadcom Corporation and/or its
+licensors, and may only be used, duplicated, modified or distributed pursuant
+to the terms and conditions of a separate, written license agreement executed
+between you and Broadcom (an "Authorized License").  Except as set forth in
+an Authorized License, Broadcom grants no license (express or implied), right
+to use, or waiver of any kind with respect to the Software, and Broadcom
+expressly reserves all rights in and to the Software and all intellectual
+property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
+NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
+BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
+
+Except as expressly set forth in the Authorized License,
+
+1. This program, including its structure, sequence and organization,
+    constitutes the valuable trade secrets of Broadcom, and you shall use
+    all reasonable efforts to protect the confidentiality thereof, and to
+    use this information only in connection with your use of Broadcom
+    integrated circuit products.
+
+2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+    AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
+    WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
+    RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND
+    ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
+    FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
+    COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
+    TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
+    PERFORMANCE OF THE SOFTWARE.
+
+3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+    ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
+    INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
+    WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+    IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
+    OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+    SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
+    SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+    LIMITED REMEDY.
+:>
+*/
+#ifndef BCMOS_SYSTEM_H_
+#define BCMOS_SYSTEM_H_
+
+#include <limits.h>
+
+#include "lib_types.h"
+#include "lib_string.h"
+
+#include "../bcmos_errno.h"
+#include "../bcmos_types.h"
+#include "../bcmos_endian.h"
+#include "cfe_timer.h"
+#include "lib_printf.h"
+
+#define bcmos_printf printf
+
+#define bcmos_usleep(x)                              \
+                        do {                         \
+                        cfe_usleep (x);              \
+                        }                            \
+                        while(0) 
+/* Define bcmos_bool - the boolean type for bcmos - based on C99 standard boolean type */
+#ifndef BCMOS_BOOLEAN
+typedef _Bool bcmos_bool;
+#define BCMOS_FALSE 0
+#define BCMOS_TRUE 1
+#endif
+
+#define PERIPH_GENINT_REVID              0xffe00000
+#define CHIP_REV_MASK                    0xFF
+static inline unsigned int get_chip_revision(void)
+{
+    return *(volatile unsigned int*)PERIPH_GENINT_REVID & CHIP_REV_MASK;
+} 
+
+#define CHIP_REVISION_A0 0xA0
+#define CHIP_REVISION_B0 0xB0
+
+#ifdef SIMULATION_BUILD
+#define GET_CHIP_REVISION CHIP_REVISION_A0
+#else
+extern uint32_t chip_revision;
+#define GET_CHIP_REVISION (chip_revision != 0 ? chip_revision : (chip_revision = get_chip_revision()))
+#endif
+
+
+typedef uint16_t bcmos_fastlock;
+#define BCMOS_FASTLOCK_INITIALIZER 0
+#define bcmos_fastlock_lock(fastlock) (long)fastlock
+#define bcmos_fastlock_unlock(fastlock, flags)  (void)flags
+
+typedef uint16_t bcmos_mutex;
+#define bcmos_mutex_create(mutex, flags, name)  
+#define bcmos_mutex_lock(mutex)
+#define bcmos_mutex_unlock(mutex)
+
+
+#define BCM_SIZEOFARRAY(arr) (sizeof(arr)/sizeof(*arr))
+#define BCM_SIZEOFFIELD(s, f) (sizeof(((s*)NULL)->f))
+#define BCM_MEMZERO_STRUCT(ptr) memset(ptr, 0, sizeof(*(ptr)))
+#define BCM_MEMCPY_ARRAY(dst, src) memcpy(dst, src, sizeof(dst))
+
+
+#define BUG_ON_PRINT(condition, fmt, args...) \
+    do \
+    { \
+        if (condition) \
+        { \
+            printf(fmt, ##args); \
+            /* On one hand, don't let this task continue - it is likely to crash/create a system exception.
+             * On the other hand, it mustn't do a busy loop - otherwise it can cause lower priority tasks to stop responding. */ \
+            while (1) \
+                bcmos_usleep(10000000); \
+        } \
+    } while (0)
+
+#define BUG_ON(condition)      BUG_ON_PRINT((condition), "BUG in %s %d!\n", __FUNCTION__, __LINE__)
+#define BUG()                  BUG_ON(1)
+#define BUG_UNLESS(condition)  BUG_ON(!(condition))
+
+
+#define BCMOS_TRACE_ERR(fmt, args...) \
+    do \
+    { \
+        printf( fmt, ## args); \
+   } while (0)
+
+
+#define bcmos_vprintf printf
+#define bcmos_calloc(s) KMALLOC((s), 0)
+
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/linux/Makefile b/bcm68620_release/release/host_customized/os_abstraction/linux/Makefile
new file mode 100644
index 0000000..c66f726
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/linux/Makefile
@@ -0,0 +1,31 @@
+# Linux kernel OS abstraction
+#
+ifeq ("$(OS_KERNEL)", "linux")
+
+MOD_NAME = os_linux
+MOD_TYPE = linux_module
+MOD_SUPPRESS_OS_DEP = y
+MOD_DEPS = ll_pcie
+
+MOD_INC_DIRS = $(SRC_DIR) $(SRC_DIR)/..
+ifeq ("$(RELEASE_BUILD)", "y")
+    MOD_INC_DIRS += host_driver/config
+else
+    MOD_INC_DIRS += $(SUBSYSTEM)/os_abstraction/$(PLATFORM) $(SUBSYSTEM)/config
+endif
+
+EXTRA_CFLAGS += -DBCMOS_TRACE_PRINTF
+
+srcs = bcmos_system.c ../bcmos_errno.c ../bcmos_common.c
+
+ifeq ("$(DEBUG)", "y")
+	MOD_DEFS	+= -DBCMOS_MEM_DEBUG -DBCMOS_SYS_UNITTEST
+endif
+
+# If called by linux kernel builder - add include paths manually.
+# It is not elegant, but we'll not have many linux modules
+ifneq ("$(KBUILD_SRC)", "")
+	-include $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+endif
+
+endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.c b/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.c
new file mode 100644
index 0000000..0b4a023
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.c
@@ -0,0 +1,536 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmos_system.c
+ *
+ * This file implements a subset of OS Abstraction services
+ * for linux kernel
+ */
+
+#include <bcmos_system.h>
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <asm-generic/pci-dma-compat.h>
+#include <linux/fs.h>
+#include <linux/fdtable.h>
+
+#include <bcmolt_llpcie.h>
+
+/* task control blocks */
+extern STAILQ_HEAD(task_list, bcmos_task) task_list;
+
+/* global OS lock */
+extern bcmos_mutex bcmos_res_lock;
+
+/* Initialize system library */
+bcmos_errno bcmos_sys_init(void)
+{
+    return BCM_ERR_OK;
+}
+/* Clean-up system library */
+void bcmos_sys_exit(void)
+{
+}
+
+/*
+ * Thread handler
+ */
+static int bcmos_task_handler(void *data)
+{
+    bcmos_task *task = (bcmos_task *)data;
+    F_bcmos_task_handler handler;
+    long handler_data;
+
+    task->sys_task.t = current;
+
+    if (task->parm.handler)
+    {
+        /* "traditional task */
+        handler = task->parm.handler;
+        handler_data = task->parm.data;
+    }
+    else
+    {
+        /* "integrated" task */
+        handler = bcmos_dft_task_handler;
+        handler_data = (long)task;
+    }
+    handler(handler_data);
+
+    return 0;
+}
+
+void _bcmos_backtrace(void)
+{
+    /*todo implement this*/
+}
+
+/* Create a new task.
+ * Attention! Priority is ignored.
+ */
+bcmos_errno bcmos_task_create(bcmos_task *task, const bcmos_task_parm *parm)
+{
+    struct task_struct *t;
+    bcmos_errno rc;
+
+    if (!task || !parm)
+        return BCM_ERR_PARM;
+
+    memset(task, 0, sizeof(*task));
+    task->parm = *parm;
+    if (!parm->handler)
+    {
+        /* Initialize and lock mutex to wait on */
+        rc = bcmos_sem_create(&task->active_sem, 0, task->parm.flags, parm->name);
+        if (rc)
+        {
+            BCMOS_TRACE_ERR("Task %s: can't create active_sem. Error %s (%d)\n",
+                task->parm.name, bcmos_strerror(rc), rc);
+            return rc;
+        }
+    }
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (task->parm.name)
+    {
+        strncpy(task->name, task->parm.name, sizeof(task->name) - 1);
+        task->parm.name = task->name;
+    }
+    bcmos_fastlock_init(&task->active_lock, 0);
+    task->magic = BCMOS_TASK_MAGIC;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&task_list, task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+
+    t = kthread_run(bcmos_task_handler, task, parm->name);
+    if (t == ERR_PTR(-ENOMEM))
+    {
+        bcmos_mutex_lock(&bcmos_res_lock);
+        STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+        bcmos_mutex_unlock(&bcmos_res_lock);
+        task->magic = 0;
+        return BCM_ERR_NOMEM;
+    }
+
+    return BCM_ERR_OK;
+}
+
+/* Destroy task */
+bcmos_errno bcmos_task_destroy(bcmos_task *task)
+{
+    if (task->magic != BCMOS_TASK_MAGIC)
+    {
+        return BCM_ERR_PARM;
+    }
+    if (!task->sys_task.t)
+    {
+        return BCM_ERR_NOENT;
+    }
+    task->destroy_request = BCMOS_TRUE;
+    task->magic = BCMOS_TASK_MAGIC_DESTROYED;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    /* The task may be waiting on semaphore. Kick it */
+    if (!task->parm.handler)
+    {
+        bcmos_sem_post(&task->active_sem);
+    }
+
+    /* Sometimes by the time we get here the task has already been disposed of.
+     * TODO: investigate why */
+    if (task->sys_task.t->cred != NULL)
+    {
+        kthread_stop(task->sys_task.t);
+    }
+    return BCM_ERR_OK;
+}
+
+/** Get current task
+ * \returns task handle or NULL if not in task context
+ */
+bcmos_task *bcmos_task_current(void)
+{
+    struct task_struct *kt = current;
+    bcmos_task *t, *tmp;
+
+    STAILQ_FOREACH_SAFE(t, &task_list, list, tmp)
+    {
+        if (t->sys_task.t == kt)
+            break;
+    }
+    return t;
+}
+
+/* timer signal handler */
+static void sys_timer_handler(unsigned long data)
+{
+    bcmos_sys_timer *timer = (bcmos_sys_timer *)data;
+    timer->handler(timer->data);
+}
+
+/* Create timer */
+bcmos_errno bcmos_sys_timer_create(bcmos_sys_timer *timer, bcmos_sys_timer_handler handler, void *data)
+{
+    if (!timer || !handler)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "timer %p, handler %p\n", timer, handler);
+
+   timer->handler = handler;
+   timer->data = data;
+   init_timer(&timer->t);
+   timer->t.function = sys_timer_handler;
+   timer->t.data = (unsigned long)timer;
+
+   return BCM_ERR_OK;
+}
+
+/* Destroy timer */
+void bcmos_sys_timer_destroy(bcmos_sys_timer *timer)
+{
+    del_timer_sync(&timer->t);
+}
+
+/* (Re)start timer */
+void bcmos_sys_timer_start(bcmos_sys_timer *timer, uint32_t delay)
+{
+    /* Convert delay us --> ticks */
+    uint32_t ticks = usecs_to_jiffies(delay);
+    mod_timer(&timer->t, jiffies + ticks);
+}
+
+/* Stop timer if running */
+void bcmos_sys_timer_stop(bcmos_sys_timer *timer)
+{
+    /* No need to do anything. System timer isn't running */
+}
+
+void bcmos_usleep(uint32_t u)
+{
+    if (u >= 10000)
+        msleep((u + 999) / 1000);
+    else
+        udelay(u);
+}
+
+/*
+ * Semaphore
+ */
+
+/* Decrement semaphore counter. Wait if the counter is 0.
+ */
+bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout)
+{
+    if (timeout)
+    {
+        if (timeout != BCMOS_WAIT_FOREVER)
+        {
+            if (down_timeout(&sem->s, usecs_to_jiffies(timeout)))
+                return BCM_ERR_TIMEOUT;
+        }
+        else
+        {
+            if (down_interruptible(&sem->s))
+                return BCM_ERR_INTERNAL;
+        }
+        return BCM_ERR_OK;
+    }
+
+    /* 0 timeout */
+    if (down_trylock(&sem->s))
+    {
+        return BCM_ERR_NOENT;
+    }
+    return BCM_ERR_OK;
+}
+
+
+/*
+ * Byte memory pool
+ */
+
+/* Memory block header */
+typedef struct bcmos_byte_memblk
+{
+    bcmos_byte_pool *pool;      /** pool that owns the block */
+    uint32_t size;              /** block size (bytes) including bcmos_byte_memblk header */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /** magic number */
+#define BCMOS_MEM_MAGIC_ALLOC   (('m'<<24) | ('b' << 16) | ('l' << 8) | 'k')
+#define BCMOS_MEM_MAGIC_FREE    (('m'<<24) | ('b' << 16) | ('l' << 8) | '~')
+#endif
+} bcmos_byte_memblk;
+
+/* Create byte memory pool */
+bcmos_errno bcmos_byte_pool_create(bcmos_byte_pool *pool, const bcmos_byte_pool_parm *parm)
+{
+    if (!pool || !parm)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool %p, parm %p\n", pool, parm);
+    }
+
+    BCM_MEMZERO_STRUCT(pool);
+    pool->parm = *parm;
+    if (!pool->parm.size)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "size %u\n", parm->size);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_VALID;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Destroy memory pool */
+bcmos_errno bcmos_byte_pool_destroy(bcmos_byte_pool *pool)
+{
+    if (pool->allocated)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_STATE, "%u bytes of memory are still allocated from the pool %s\n",
+            pool->allocated, pool->parm.name);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_DELETED;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Allocate memory from memory pool */
+void *bcmos_byte_pool_alloc(bcmos_byte_pool *pool, uint32_t size)
+{
+    bcmos_byte_memblk *blk;
+    uint32_t byte_size;
+    void *ptr;
+
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+#endif
+
+    if (size + pool->allocated > pool->parm.size)
+        return NULL;
+
+    byte_size = size + sizeof(bcmos_byte_memblk);
+#ifdef BCMOS_MEM_DEBUG
+    byte_size += sizeof(uint32_t); /* block suffix */
+#endif
+    /* ToDo: Maintain LL of allocated blocks */
+    blk = (bcmos_byte_memblk *)bcmos_alloc(byte_size);
+    if (!blk)
+        return NULL;
+    ptr = (void *)(blk + 1);
+    blk->size = byte_size;
+    pool->allocated += byte_size;
+    blk->pool = pool;
+#ifdef BCMOS_MEM_DEBUG
+    blk->magic = BCMOS_MEM_MAGIC_ALLOC;
+    *(uint32_t *)((long)blk + byte_size - sizeof(uint32_t)) = BCMOS_MEM_MAGIC_ALLOC;
+#endif
+
+    return ptr;
+}
+
+/* Release memory allocated using bcmos_byte_pool_alloc() */
+void bcmos_byte_pool_free(void *ptr)
+{
+    bcmos_byte_memblk *blk;
+    bcmos_byte_pool *pool;
+
+    BUG_ON(!ptr);
+    blk = (bcmos_byte_memblk *)((long)ptr - sizeof(bcmos_byte_memblk));
+    pool = blk->pool;
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+    BUG_ON(blk->magic != BCMOS_MEM_MAGIC_ALLOC);
+    BUG_ON(*(uint32_t *)((long)blk + blk->size - sizeof(uint32_t)) != BCMOS_MEM_MAGIC_ALLOC);
+    blk->magic = BCMOS_MEM_MAGIC_FREE;
+#endif
+    pool->allocated -= blk->size;
+    bcmos_free(blk);
+}
+
+/*
+ * DMA-able memory management
+ */
+
+/* Dma-able block header */
+typedef struct
+{
+    struct pci_dev *pdev;
+    dma_addr_t dma_handle;
+    uint32_t size;
+} bcmos_dma_mem_hdr;
+
+/* Allocate DMA-able memory */
+void *bcmos_dma_alloc(uint8_t device, uint32_t size)
+{
+    bcmos_dma_mem_hdr hdr =
+    {
+        .pdev = (struct pci_dev *)bcm_ll_pcie_dev_get(device),
+        .size = size
+    };
+    void *ptr;
+
+    if (!hdr.pdev)
+    {
+        return NULL;
+    }
+
+    ptr = pci_alloc_consistent(hdr.pdev, size + sizeof(bcmos_dma_mem_hdr), &hdr.dma_handle);
+    if (ptr)
+    {
+        memcpy(ptr, &hdr, sizeof(hdr));
+    }
+    return (void *)((long)ptr + sizeof(hdr));
+}
+
+/* Release DMA-able memory */
+void bcmos_dma_free(uint8_t device, void *ptr)
+{
+    bcmos_dma_mem_hdr hdr;
+
+    /* Step back to prefix area */
+    ptr = (void *)((long)ptr - sizeof(hdr));
+    memcpy(&hdr, ptr, sizeof(hdr));
+
+    /* Sanity check */
+    if (!hdr.pdev || hdr.pdev != bcm_ll_pcie_dev_get(device))
+    {
+        BCMOS_TRACE_ERR("!!!Attempt to release insane DMA-able pointer. ptr=%p pdev=%p/%p\n",
+            ptr, hdr.pdev, bcm_ll_pcie_dev_get(device));
+        return;
+    }
+    pci_free_consistent(hdr.pdev, hdr.size, ptr, hdr.dma_handle);
+}
+
+/*
+ * Print to the current process' stdout
+ */
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+static int _bcmos_write(struct file *fd, const unsigned char *buf, int len)
+{
+    mm_segment_t oldfs;
+    int len0 = len;
+    oldfs = get_fs();
+    set_fs(KERNEL_DS);
+    while(len)
+    {
+        int lw;
+        lw = vfs_write(fd, (char *)buf, len, &fd->f_pos);
+        if (lw < 0)
+            break;
+        len -= lw;
+        if (len)
+        {
+            if (msleep_interruptible(1))
+                break;
+            buf += lw;
+        }
+    }
+    set_fs(oldfs);
+    return (len0 - len);
+}
+
+int bcmos_sys_vprintf(const char *format, va_list args)
+{
+    struct file *f;
+    int rc=0;
+
+    /* Get stdout file handle if any */
+    if (in_interrupt() || !current || !current->files)
+        f = 0;
+    else
+        f = fcheck(STDOUT_FILENO);
+    if (!f)
+    {
+         rc = vprintk(format, args);
+    }
+    else
+    {
+        char printbuf[1024];
+        char *p1=printbuf, *p2;
+        vscnprintf(printbuf, sizeof(printbuf)-1, format, args);
+        printbuf[sizeof(printbuf)-1]=0;
+        do
+        {
+            p2 = strchr(p1, '\n');
+            if (p2)
+            {
+                rc += _bcmos_write(f, (unsigned char*) p1, p2-p1+1);
+                rc += _bcmos_write(f, (unsigned char*)"\r", 1);
+            }
+            else
+            {
+                rc += _bcmos_write(f, (unsigned char*)p1, strlen(p1));
+            }
+            p1 = p2 + 1;
+        } while(p2);
+    }
+    return rc;
+}
+
+static int os_linux_module_init(void)
+{
+    bcmos_errno rc;
+
+    rc = bcmos_init();
+
+    return rc ? -EINVAL : 0;
+}
+
+static void os_linux_module_exit(void)
+{
+    bcmos_exit();
+}
+
+module_init(os_linux_module_init);
+module_exit(os_linux_module_exit);
+
+MODULE_DESCRIPTION("OS Abstraction");
+MODULE_LICENSE("Dual BSD/GPL");
+
+EXPORT_SYMBOL(bcmos_task_create);
+EXPORT_SYMBOL(bcmos_task_destroy);
+EXPORT_SYMBOL(bcmos_task_current);
+EXPORT_SYMBOL(bcmos_sem_wait);
+EXPORT_SYMBOL(bcmos_sys_trace_level);
+EXPORT_SYMBOL(bcmos_usleep);
+EXPORT_SYMBOL(bcmos_byte_pool_create);
+EXPORT_SYMBOL(bcmos_byte_pool_destroy);
+EXPORT_SYMBOL(bcmos_byte_pool_alloc);
+EXPORT_SYMBOL(bcmos_byte_pool_free);
+EXPORT_SYMBOL(bcmos_sys_vprintf);
+EXPORT_SYMBOL(bcmos_dma_alloc);
+EXPORT_SYMBOL(bcmos_dma_free);
+EXPORT_SYMBOL(_bcmos_backtrace);
+EXPORT_SYMBOL(sw_error_handler);
+EXPORT_SYMBOL(bcmos_exit);
diff --git a/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.h b/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.h
new file mode 100644
index 0000000..d6f36fe
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/linux/bcmos_system.h
@@ -0,0 +1,519 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmos_system.h
+ * Maple System Services
+ * posix port: simulation
+ */
+
+#ifndef BCMOS_SYSTEM_H_
+#define BCMOS_SYSTEM_H_
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/skbuff.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/semaphore.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/compiler.h>
+#include <linux/random.h>
+#include <linux/ctype.h>
+#include <linux/time.h>
+#include <asm/io.h>
+
+#define BCMOS_IRQ_SINGLE    0
+#define BCMOS_IRQ_SHARED    IRQF_SHARED
+
+/* Re-define GNU typeof as ISO __typeof__ */
+#define typeof __typeof__
+
+#define strtol(s,p,b) simple_strtol(s,p,b)
+
+/* Specify here which system functions are inlined */
+
+#define BCMOS_FASTLOCK_INLINE
+#define BCMOS_SEM_INLINE
+#define BCMOS_MUTEX_INLINE
+
+#ifdef ENABLE_LOG
+#define BCMOS_TRACE_IN_DEV_LOG
+#endif
+
+#if !defined(BCMOS_TRACE_IN_DEV_LOG) && !defined(BCMOS_TRACE_PRINTF)
+#define BCMOS_TRACE_PRINTF
+#endif
+
+/* #define BCMOS_BYTE_POOL_ALLOC_FREE_INLINE */
+#define BCMOS_MALLOC_FREE_INLINE
+/* #define BCMOS_CALLOC_INLINE */
+#define BCMOS_BUF_OS_SPECIFIC
+#define BCMOS_BUF_INLINE
+#define BCMOS_INTERRUPT_INLINE
+#define BCMOS_TIMESTAMP_INLINE
+/* #define BCMOS_DMA_ALLOC_FREE_INLINE */
+#define BCMOS_VIRT_TO_PHYS_INLINE
+#define BCMOS_CACHE_INLINE
+/* Uncommentthe following line if h/w supports DMA cache coherency */
+/* #define BCMOS_DMA_CACHE_COHERENCY */
+
+/* getchar, putchar are not support. define as inline and proviude dummy targets */
+#define BCMOS_GETCHAR_INLINE
+#define BCMOS_PUTCHAR_INLINE
+
+#include "bcmos_common.h"
+
+static inline void bcm_pci_write32(volatile uint32_t *address, uint32_t value)
+{
+    writel(value, address);
+}
+
+static inline uint32_t bcm_pci_read32(const volatile uint32_t *address)
+{
+	return readl(address);
+}
+
+
+void _bcmos_backtrace(void);
+int bcmos_sys_vprintf(const char *format, va_list args);
+
+/*
+ * Memory allocation
+ */
+
+/* Allocate DMAable memory from the main heap */
+static inline void *bcmos_alloc(uint32_t size)
+{
+    return kmalloc(size, GFP_DMA);
+}
+
+/* Release memory to the main pool */
+static inline void bcmos_free(void *ptr)
+{
+    return kfree(ptr);
+}
+
+static inline void *bcmos_alloc_not_cache(int32_t size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+static inline void bcmos_free_not_cache(void *dest)
+{
+	kfree(dest);
+}
+/*
+ * Synchronization
+ */
+
+/* Mutex control block */
+struct bcmos_mutex
+{
+    struct mutex m;             /**< linux kernel mutex */
+};
+
+/* Create recursive mutex */
+static inline bcmos_errno bcmos_mutex_create(bcmos_mutex *mutex, uint32_t flags, const char *name)
+{
+    mutex_init(&mutex->m);
+    return BCM_ERR_OK;
+}
+
+/* Destroy mutex */
+static inline void bcmos_mutex_destroy(bcmos_mutex *mutex)
+{
+    mutex_destroy(&mutex->m);
+}
+
+/* Lock mutex */
+static inline void bcmos_mutex_lock(bcmos_mutex *mutex)
+{
+    mutex_lock(&mutex->m);
+}
+
+/* Release mutex */
+static inline void bcmos_mutex_unlock(bcmos_mutex *mutex)
+{
+    mutex_unlock(&mutex->m);
+}
+
+/** Fast lock control block */
+struct bcmos_fastlock
+{
+    spinlock_t m;
+};
+
+/** Fastlock initializer. Can be used instead of calling bcmos_fastlock_init() */
+#define BCMOS_FASTLOCK_INITIALIZER      { SPINLOCK_UNLOCKED }
+
+/* Init fastlock */
+static inline void bcmos_fastlock_init(bcmos_fastlock *lock, uint32_t flags)
+{
+    spin_lock_init(&lock->m);
+}
+
+/* Take fast lock */
+static inline long bcmos_fastlock_lock(bcmos_fastlock *lock)
+{
+    unsigned long flags;
+    spin_lock_irqsave(&lock->m, flags);
+    return (long)flags;
+}
+
+/* Release fast lock */
+static inline void bcmos_fastlock_unlock(bcmos_fastlock *lock, long flags)
+{
+    spin_unlock_irqrestore(&lock->m, (unsigned long)flags);
+}
+
+/** Semaphore control block */
+struct bcmos_sem
+{
+    struct semaphore s;      /**< linux kernel semaphore */
+};
+
+/* Create semaphore */
+static inline bcmos_errno bcmos_sem_create(bcmos_sem *sem, uint32_t count, uint32_t flags, const char *name)
+{
+    sema_init(&sem->s, count);
+    return BCM_ERR_OK;
+}
+
+/* Destroy semaphore */
+static inline void bcmos_sem_destroy(bcmos_sem *sem)
+{
+}
+
+/* Wait for semaphore */
+bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout);
+
+/* Increment semaphore counter */
+static inline void bcmos_sem_post(bcmos_sem *sem)
+{
+    up(&sem->s);
+}
+
+/*
+ * Timers
+ */
+
+/** System timer */
+struct bcmos_sys_timer
+{
+    struct timer_list t;                /**< linux timer */
+    bcmos_sys_timer_handler handler;    /**< Timer handler */
+    void *data;                         /**< Parameter to be passed to the handler */
+};
+
+/* Get current timestamp (us) */
+static inline uint32_t bcmos_timestamp(void)
+{
+    struct timespec uptime;
+    do_posix_clock_monotonic_gettime(&uptime);
+    monotonic_to_bootbased(&uptime);
+    return uptime.tv_sec * USEC_PER_SEC + uptime.tv_nsec / NSEC_PER_USEC;
+}
+
+/* Get current timestamp (us) */
+static inline uint64_t bcmos_timestamp64(void)
+{
+    struct timespec uptime;
+    do_posix_clock_monotonic_gettime(&uptime);
+    monotonic_to_bootbased(&uptime);
+    return (uint64_t)uptime.tv_sec * USEC_PER_SEC + (uint64_t)uptime.tv_nsec / NSEC_PER_USEC;
+}
+
+/*
+ * Task control
+ */
+
+/** OS-specific task control block extension */
+typedef struct bcmos_sys_task
+{
+    struct task_struct *t;
+} bcmos_sys_task;
+
+/** Memory pool control block */
+struct bcmos_byte_pool
+{
+    bcmos_byte_pool_parm parm;  /**< Pool parameters */
+    uint32_t allocated;         /**< Number of bytes allocated */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /**< magic number */
+#define BCMOS_BYTE_POOL_VALID           (('b'<<24) | ('y' << 16) | ('p' << 8) | 'o')
+#define BCMOS_BYTE_POOL_DELETED         (('b'<<24) | ('y' << 16) | ('p' << 8) | '~')
+#endif
+};
+
+/* Transport / network buffer service */
+extern uint32_t bcmos_buf_default_headroom;
+
+/*
+ * Network / transport buffer
+ */
+
+/* Data alignment. Should be a max lf L1, L2 cache line size */
+#define BCMOS_BUF_DATA_ALIGNMENT        128
+
+/* Encapsulated skb */
+struct bcmos_buf
+{
+    struct sk_buff skb;
+};
+
+/* Buffer list */
+typedef struct sk_buff_head bcmos_buf_queue;
+
+/* Allocate buffer */
+static inline bcmos_buf *bcmos_buf_alloc(uint32_t size)
+{
+    /* Allocate extra 2 * BCMOS_BUF_DATA_ALIGNMENT to make sure that neither data start nor end
+     * end up in the middle of cache line
+     */
+    struct sk_buff *skb = dev_alloc_skb(size + BCMTR_BUF_EXTRA_HEADROOM + 2 * BCMOS_BUF_DATA_ALIGNMENT - 1);
+    if (!skb)
+        return NULL;
+#if BCMTR_BUF_EXTRA_HEADROOM
+    skb_reserve(skb, BCMTR_BUF_EXTRA_HEADROOM);
+#endif
+    if ((long)skb->data & (BCMOS_BUF_DATA_ALIGNMENT - 1))
+    {
+        skb_reserve(skb, BCMOS_BUF_DATA_ALIGNMENT - ((long)skb->data & (BCMOS_BUF_DATA_ALIGNMENT - 1)));
+    }
+    return (bcmos_buf *)skb;
+}
+
+/* Release buffer */
+static inline void bcmos_buf_free(bcmos_buf *buf)
+{
+    consume_skb(&buf->skb);
+}
+
+/* Get data length */
+static inline uint32_t bcmos_buf_length(bcmos_buf *buf)
+{
+    return buf->skb.len;
+}
+
+/* Set data length */
+static inline bcmos_errno bcmos_buf_length_set(bcmos_buf *buf, uint32_t length)
+{
+    if (unlikely(length > skb_tailroom(&buf->skb)))
+    {
+        BCMOS_TRACE_ERR("!!!%s: length=%u tailroom=%d\n",
+            __FUNCTION__, length, skb_tailroom(&buf->skb));
+        return BCM_ERR_OVERFLOW;
+    }
+    buf->skb.len = length;
+    return BCM_ERR_OK;
+}
+
+/* Get buffer data pointer. */
+static inline uint8_t *bcmos_buf_data(bcmos_buf *buf)
+{
+    return buf->skb.data;
+}
+
+/* Get buffer channel. */
+static inline uint8_t bcmos_buf_channel(bcmos_buf *buf)
+{
+    return buf->skb.cb[0];
+}
+
+/* Set buffer channel. */
+static inline void bcmos_buf_channel_set(bcmos_buf *buf, uint8_t channel)
+{
+    buf->skb.cb[0] = channel;
+}
+
+/** Initialize buffer queue
+ * \param[in]   q       Buffer queue
+ */
+static inline void bcmos_buf_queue_init(bcmos_buf_queue *q)
+{
+    skb_queue_head_init(q);
+}
+
+/** Enqueue buffer
+ *
+ * Must be called under lock, e.g., q->lock
+ *
+ * \param[in]   q       Buffer queue
+ * \param[in]   buf     Buffer
+ */
+static inline void bcmos_buf_queue_put(bcmos_buf_queue *q, bcmos_buf *buf)
+{
+    __skb_queue_tail(q, &buf->skb);
+}
+
+/* Check if buffer queue is empty
+ * \param[in]   q       Buffer queue
+ * \returns TRUE if the queue is empty
+ */
+static inline bcmos_bool bcmos_buf_queue_is_empty(bcmos_buf_queue *q)
+{
+    return (bcmos_bool)skb_queue_empty(q);
+}
+
+/* Dequeue buffer
+ *
+ * Must be called under lock, e.g., q->lock
+ *
+ * Remove and return the 1st queued buffer.
+ * \param[in]   q       Buffer queue
+ * \returns the  buffer pointer
+ */
+static inline bcmos_buf *bcmos_buf_queue_get(bcmos_buf_queue *q)
+{
+    struct sk_buff *skb = __skb_dequeue(q);
+    return skb ? container_of(skb, bcmos_buf, skb) : NULL;
+}
+
+/* Peek into queue and return the 1st buffer without dequeing it
+ *
+ * Must be called under lock, e.g., q->lock
+ * \param[in]   q       Buffer queue
+ * \returns the  buffer pointer
+ */
+static inline bcmos_buf *bcmos_buf_queue_peek(bcmos_buf_queue *q)
+{
+    struct sk_buff *skb = skb_peek(q);
+    return skb ? container_of(skb, bcmos_buf, skb) : NULL;
+}
+
+/*
+ * dcache utilities
+ */
+/* Invalidate address area in data cache. Dirty cache lines content is discarded */
+static inline void bcmos_dcache_inv(void *start, uint32_t size)
+{
+#if defined(CONFIG_MIPS)
+    dma_cache_inv((unsigned long)start, size);
+#elif defined(CONFIG_PPC)
+    if (((unsigned long)start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
+        flush_dcache_range((unsigned long)start, (unsigned long)start + size);
+    else
+        invalidate_dcache_range((unsigned long)start, (unsigned long)start + size);
+#elif defined(CONFIG_UML)
+    /* Nothing to do */
+#else
+#error Please implement bcmos_dcache_inv()
+#endif
+}
+
+/* Flush address area in data cache. Dirty cache lines are committed to memory */
+static inline void bcmos_dcache_flush(void *start, uint32_t size)
+{
+#if defined(CONFIG_MIPS)
+    dma_cache_wback((unsigned long)start, size);
+#elif defined(CONFIG_PPC)
+    clean_dcache_range((unsigned long)start, (unsigned long)start + size);
+#elif defined(CONFIG_UML)
+    /* Nothing to do */
+#else
+#error Please implement bcmos_dcache_flush()
+#endif
+}
+
+/*
+ * Interrupt service
+ */
+
+/* Connect system interrupt */
+static inline int bcmos_int_connect(int irq, int cpu, int flags,
+    int (*isr)(int irq, void *priv), const char *name, void *priv)
+{
+    return request_irq(irq, (irq_handler_t)isr, flags, name, priv);
+}
+
+/* Disconnect system interrupt */
+static inline void bcmos_int_disconnect(int irq, void *priv)
+{
+    free_irq(irq, priv);
+}
+
+/* Unmask IRQ */
+static inline void bcmos_int_enable(int irq)
+{
+    enable_irq(irq);
+}
+
+/* Mask IRQ */
+static inline void bcmos_int_disable(int irq)
+{
+    disable_irq(irq);
+}
+
+/* Check in-irq status */
+static inline int is_irq_mode(void)
+{
+    return in_interrupt();
+}
+
+/* Check if interrupts are disabled */
+static inline int is_irq_disabled(void)
+{
+    return irqs_disabled();
+}
+
+/* Convert virtual address to physical address */
+static inline unsigned long bcmos_virt_to_phys(void *va)
+{
+    return virt_to_phys(va);
+}
+
+/* write barrier */
+static inline void bcmos_barrier(void)
+{
+    smp_wmb();
+}
+static inline int bcmos_getchar(void)
+{
+    return -1;
+}
+
+static inline void bcmos_putchar(int c)
+{
+}
+
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+#undef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+#endif
+
+#ifdef BCMOS_MSG_QUEUE_UDP_SOCKET
+#undef BCMOS_MSG_QUEUE_UDP_SOCKET
+#endif
+
+/* 2nd part of OS-independent declarations */
+#include "bcmos_common2.h"
+
+#endif /* BCMOS_SYSTEM_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/os_cli/Makefile b/bcm68620_release/release/host_customized/os_abstraction/os_cli/Makefile
new file mode 100644
index 0000000..545a86a
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/os_cli/Makefile
@@ -0,0 +1,7 @@
+# OS CLI commands
+#
+MOD_NAME = os_cli
+MOD_TYPE = lib
+MOD_DEPS = cli
+
+srcs = bcmos_cli.c
diff --git a/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.c b/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.c
new file mode 100644
index 0000000..3aef31a
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.c
@@ -0,0 +1,335 @@
+/*
+<: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_cli.h>
+
+static bcmcli_entry *os_cli_dir;
+
+static bcmcli_enum_val trace_level_table[] =
+{
+    { .name="none", .val=BCMOS_TRACE_LEVEL_NONE },
+    { .name="error", .val=BCMOS_TRACE_LEVEL_ERROR },
+    { .name="info", .val=BCMOS_TRACE_LEVEL_INFO },
+    { .name="verbose_info", .val=BCMOS_TRACE_LEVEL_VERBOSE },
+    { .name="debug", .val=BCMOS_TRACE_LEVEL_DEBUG },
+    BCMCLI_ENUM_LAST
+};
+
+/*
+ * Command handlers
+ */
+
+static bcmos_errno _oscli_trace_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    bcmos_trace_level level = (bcmos_trace_level)parm[0].value.number;
+
+    if (bcmcli_parm_is_set(session, &parm[0]))
+    {
+        bcmos_trace_level old_level;
+
+        old_level = bcmos_trace_level_set(level);
+        bcmcli_session_print(session, "OS trace level: old=%s  new=%s\n",
+            bcmcli_enum_stringval(trace_level_table, old_level),
+            bcmcli_enum_stringval(trace_level_table, level));
+    }
+    else
+    {
+        bcmcli_session_print(session, "OS trace level: %s\n",
+            bcmcli_enum_stringval(trace_level_table, bcmos_trace_level_get()));
+    }
+    return BCM_ERR_OK;
+}
+
+static bcmos_errno _oscli_task_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
+    bcmos_task *task = NULL;
+    int nt = 0;
+
+    bcmcli_session_print(session, "%-20s %4s %4s %-10s %s\n", "task", "prio", "core", "timeout", "handler");
+    while (bcmos_task_get_next(&task) == BCM_ERR_OK)
+    {
+        bcmos_task_parm tp = {};
+        bcmos_task_query(task, &tp);
+        if (!name || (name && tp.name && strstr(tp.name, name)))
+        {
+            char core_name[10];
+            if (tp.core != BCMOS_CPU_CORE_ANY)
+            {
+                snprintf(core_name, sizeof(core_name), "%d", tp.core - 1);
+            }
+            else
+            {
+                strcpy(core_name, "any");
+            }
+            bcmcli_session_print(session, "%-20s %-4d %-4s %-10u %p\n",
+                tp.name, tp.priority, core_name,
+                (tp.msg_wait_timeout == BCMOS_WAIT_FOREVER) ? 0 : tp.msg_wait_timeout, tp.handler);
+            ++nt;
+        }
+    }
+    bcmcli_session_print(session, "%d tasks listed\n", nt);
+
+    return BCM_ERR_OK;
+}
+
+static void _oscli_print_qinfo_hdr(bcmcli_session *session, const char *prefix)
+{
+    bcmcli_session_print(session, "%-9s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n",
+        prefix ? prefix : "", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full");
+}
+
+static void _oscli_print_qinfo(bcmcli_session *session, bcmos_msg_queue_info *qi, const char *prefix)
+{
+    bcmcli_session_print(session, "%-s %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n",
+        prefix ? prefix : "", (int)qi->parm.size, qi->stat.msg_in,
+        qi->stat.msg_sent, qi->stat.msg_received,
+        qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm,
+        qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no");
+}
+
+static bcmos_errno _oscli_module_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    bcmos_module_id id = bcmcli_parm_is_set(session, &parm[0]) ?
+        (bcmos_module_id)parm[0].value.number : BCMOS_MODULE_ID_NONE;
+    bcmos_module_id i;
+    int nm = 0;
+
+    /* Heading */
+    _oscli_print_qinfo_hdr(session, "Module Task                 ");
+
+    for (i = BCMOS_MODULE_ID_NONE + 1; i < BCMOS_MODULE_ID__NUM_OF; i++)
+    {
+        bcmos_errno rc;
+        const bcmos_task *t = NULL;
+        bcmos_msg_queue_info qi = {};
+
+        rc = bcmos_module_query(i, &t, &qi);
+        if ((id == BCMOS_MODULE_ID_NONE || id == i) && rc == BCM_ERR_OK)
+        {
+            bcmos_task_parm tp = {};
+
+            bcmos_task_query(t, &tp);
+            bcmcli_session_print(session, "%-6d %-20s", i, (t && t->parm.name) ? t->parm.name : "*unknown*");
+            _oscli_print_qinfo(session, &qi, " ");
+            ++nm;
+        }
+    }
+    bcmcli_session_print(session, "%d modules listed\n", nm);
+
+    return BCM_ERR_OK;
+}
+
+static bcmos_errno _oscli_blk_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
+    const bcmos_blk_pool *bp = NULL;
+    int nb = 0;
+
+    bcmcli_session_print(session, "%-24s %-9s %-9s %-9s %-10s %-10s %-10s %-10s\n",
+        "name", "pool_size", "blocks", "blk_size", "free", "allocated", "released", "failed");
+    while (bcmos_blk_pool_get_next(&bp) == BCM_ERR_OK)
+    {
+        bcmos_blk_pool_info pi = {};
+
+        bcmos_blk_pool_query(bp, &pi);
+        if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name)))
+        {
+            bcmcli_session_print(session, "%-24s %-9u %-9u %-9u %-10u %-10u %-10u %-10u\n",
+                pi.parm.name ? pi.parm.name : "", pi.parm.pool_size, pi.parm.num_blks, pi.parm.blk_size,
+                    pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed);
+            ++nb;
+        }
+    }
+    bcmcli_session_print(session, "Total memory occupied by all block pools: %u bytes\n", bcmos_total_blk_pool_size);
+    bcmcli_session_print(session, "%d block pools listed\n", nb);
+
+    return BCM_ERR_OK;
+}
+
+static bcmos_errno _oscli_msg_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
+    const bcmos_msg_pool *mp = NULL;
+    int np = 0;
+
+    bcmcli_session_print(session, "%-24s %-9s %-9s %-10s %-10s %-10s %-10s\n",
+        "name", "size", "data_size", "free", "allocated", "released", "failed");
+    while (bcmos_msg_pool_get_next(&mp) == BCM_ERR_OK)
+    {
+        bcmos_msg_pool_info pi = {};
+
+        bcmos_msg_pool_query(mp, &pi);
+        if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name)))
+        {
+            bcmcli_session_print(session, "%-24s %-9u %-9u %-10u %-10u %-10u %-10u\n",
+                pi.parm.name ? pi.parm.name : "", pi.parm.size, pi.parm.data_size,
+                    pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed);
+            ++np;
+        }
+    }
+    bcmcli_session_print(session, "Total memory occupied by all message pools: %u bytes\n", bcmos_total_msg_pool_size);
+    bcmcli_session_print(session, "%d msg pools listed\n", np);
+
+    return BCM_ERR_OK;
+}
+
+static bcmos_errno _oscli_msg_queue_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
+    const bcmos_msg_queue *mq = NULL;
+    int nq = 0;
+
+    _oscli_print_qinfo_hdr(session, "name                 ");
+    while (bcmos_msg_queue_get_next(&mq) == BCM_ERR_OK)
+    {
+        bcmos_msg_queue_info qi = {};
+
+        bcmos_msg_queue_query(mq, &qi);
+        if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name)))
+        {
+            bcmcli_session_print(session, "%-20s", qi.parm.name ? qi.parm.name : "");
+            _oscli_print_qinfo(session, &qi, " ");
+            ++nq;
+        }
+    }
+    bcmcli_session_print(session, "%d msg queues listed\n", nq);
+
+    return BCM_ERR_OK;
+}
+
+static void _oscli_print_qgroup_info_hdr(bcmcli_session *session)
+{
+    bcmcli_session_print(session, "%-12s %-6s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n",
+        "name", "queues", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full");
+}
+
+static void _oscli_print_qgroup_info(bcmcli_session *session, bcmos_msg_qgroup_info *qi)
+{
+    bcmcli_session_print(session, "%-12s %-6d %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n",
+        qi->parm.name ? qi->parm.name : "", (int)qi->parm.nqueues, (int)qi->parm.size, qi->stat.msg_in,
+        qi->stat.msg_sent, qi->stat.msg_received,
+        qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm,
+        qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no");
+}
+
+static bcmos_errno _oscli_msg_qgroup_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
+    const bcmos_msg_qgroup *qgrp = NULL;
+    int ngroups = 0;
+
+    _oscli_print_qgroup_info_hdr(session);
+    while (bcmos_msg_qgroup_get_next(&qgrp) == BCM_ERR_OK)
+    {
+        bcmos_msg_qgroup_info qi = {};
+
+        bcmos_msg_qgroup_query(qgrp, &qi);
+        if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name)))
+        {
+            _oscli_print_qgroup_info(session, &qi);
+            ++ngroups;
+        }
+    }
+    bcmcli_session_print(session, "%d msg queue groups listed\n", ngroups);
+
+    return BCM_ERR_OK;
+}
+
+#ifdef BCM_OS_THREADX
+
+extern TX_THREAD __sys_shell__;
+extern TX_THREAD *__usr_shell__;
+
+static bcmos_errno _oscli_sys_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
+{
+    bcmcli_session_print(session, "Application CLI is suspended. Type \"suspend\" in system shell to resume\n");
+    tx_thread_resume(&__sys_shell__);
+    tx_thread_suspend(tx_thread_identify());
+    tx_thread_wait_abort(tx_thread_identify());
+    bcmcli_session_print(session, "Application CLI is resumed\n");
+    return BCM_ERR_OK;
+}
+#endif
+
+/*
+ * Init / exit interface
+ */
+
+
+bcmos_errno bcmos_cli_init(bcmcli_entry *top_dir)
+{
+    if (os_cli_dir)
+    {
+        return BCM_ERR_ALREADY;
+    }
+
+    /*
+     * rx directory
+     */
+    os_cli_dir = bcmcli_dir_add(top_dir, "os", "OS Abstraction", BCMCLI_ACCESS_GUEST, NULL);
+    BCMOS_CHECK_RETURN_ERROR(!os_cli_dir, BCM_ERR_INTERNAL);
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "trace", "Get/Set trace level", _oscli_trace_handler,
+        BCMCLI_MAKE_PARM_ENUM("level", "Trace level", trace_level_table, BCMCLI_PARM_FLAG_OPTIONAL));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "task", "Task info", _oscli_task_handler,
+        BCMCLI_MAKE_PARM("name", "Task name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "module", "Module(s)", _oscli_module_handler,
+        BCMCLI_MAKE_PARM_RANGE("id", "Module id", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_OPTIONAL,
+            BCMOS_MODULE_ID_NONE + 1, BCMOS_MODULE_ID__NUM_OF - 1));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "blk_pool", "Block pool(s)", _oscli_blk_pool_handler,
+        BCMCLI_MAKE_PARM("name", "Block pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "msg_pool", "Message pool(s)", _oscli_msg_pool_handler,
+        BCMCLI_MAKE_PARM("name", "Message pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "queue", "Message queue(s)", _oscli_msg_queue_handler,
+        BCMCLI_MAKE_PARM("name", "Message queue name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
+
+    BCMCLI_MAKE_CMD(os_cli_dir, "qgroup", "Message queue group(s)", _oscli_msg_qgroup_handler,
+        BCMCLI_MAKE_PARM("name", "Message queue group name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
+
+#ifdef BCM_OS_THREADX
+    BCMCLI_MAKE_CMD_NOPARM(os_cli_dir, "sys", "System shell", _oscli_sys_handler);
+#endif
+
+    return BCM_ERR_OK;
+}
+
+void bcmos_cli_exit(void)
+{
+    if (os_cli_dir)
+    {
+        bcmcli_token_destroy(os_cli_dir);
+        os_cli_dir = NULL;
+    }
+}
diff --git a/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.h b/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.h
new file mode 100644
index 0000000..487952c
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/os_cli/bcmos_cli.h
@@ -0,0 +1,48 @@
+/*
+<: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 BCMOS_CLI_H_
+#define BCMOS_CLI_H_
+
+#include <bcmos_system.h>
+#include <bcmcli.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+bcmos_errno bcmos_cli_init(bcmcli_entry *top_dir);
+
+void bcmos_cli_exit(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* BCMOS_CLI_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.c b/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.c
new file mode 100644
index 0000000..d3cb902
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.c
@@ -0,0 +1,921 @@
+/*
+<: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"
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+#include <sys/un.h>
+#endif
+#include <sys/resource.h>
+
+/* task control blocks */
+extern STAILQ_HEAD(task_list, bcmos_task) task_list;
+
+/* global OS lock */
+extern bcmos_mutex bcmos_res_lock;
+
+/*
+ * Init
+ */
+
+#define TIMER_SIG       SIGRTMIN
+
+/* Initialize system library */
+bcmos_errno bcmos_sys_init(void)
+{
+    return BCM_ERR_OK;
+}
+
+/* Clean-up system library */
+void bcmos_sys_exit(void)
+{
+}
+
+/*
+ * Task management
+ */
+
+/*
+ * Default task handler
+ */
+
+/* Create a new task */
+bcmos_errno bcmos_task_create(bcmos_task *task, const bcmos_task_parm *parm)
+{
+    F_bcmos_task_handler handler;
+    pthread_attr_t pthread_attr;
+    struct sched_param pthread_sched_param = {};
+    int pthread_prio;
+    uint32_t stack_size;
+    void *data;
+    int rc;
+
+    if (!task || !parm)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "task %p, parm %p\n", task, parm);
+    memset(task, 0, sizeof(*task));
+    if (parm->handler)
+    {
+        /* "traditional task */
+        handler = parm->handler;
+        data = (void *)parm->data;
+    }
+    else
+    {
+        /* "integrated" task */
+        handler = bcmos_dft_task_handler;
+        data = task;
+
+        /* Initialize and lock mutex to wait on */
+        rc = bcmos_sem_create(&task->active_sem, 0, task->parm.flags, parm->name);
+        if (rc)
+        {
+            BCMOS_TRACE_ERR("Task %s: can't create active_sem. Error %s (%d)\n",
+                parm->name, bcmos_strerror(rc), rc);
+            return rc;
+        }
+    }
+
+    task->parm = *parm;
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (task->parm.name)
+    {
+        strncpy(task->name, task->parm.name, sizeof(task->name) - 1);
+        task->parm.name = task->name;
+    }
+    bcmos_fastlock_init(&task->active_lock, 0);
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&task_list, task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    task->magic = BCMOS_TASK_MAGIC;
+    /* pthread priorities are 1..32, 32 being the highest */
+    pthread_prio = 32 - (int)parm->priority;
+    if (pthread_prio <= 0)
+        pthread_prio = 1;
+    stack_size = PTHREAD_STACK_MIN;
+    if (parm->stack_size && parm->stack_size > PTHREAD_STACK_MIN)
+        stack_size = parm->stack_size;
+    rc = pthread_attr_init(&pthread_attr);
+    pthread_sched_param.sched_priority = pthread_prio;
+    rc = rc ? rc : pthread_attr_setinheritsched(&pthread_attr, PTHREAD_EXPLICIT_SCHED);
+    rc = rc ? rc : pthread_attr_setschedpolicy(&pthread_attr, SCHED_RR);
+    rc = rc ? rc : pthread_attr_setschedparam(&pthread_attr, &pthread_sched_param);
+    rc = rc ? rc : pthread_attr_setstacksize(&pthread_attr, stack_size);
+    rc = rc ? rc : pthread_create(&task->sys_task.t, &pthread_attr, (void *(*)(void *))handler, data);
+    pthread_attr_destroy(&pthread_attr);
+    if (rc == EPERM)
+    {
+        BCMOS_TRACE_INFO("Thread %s: priority %d is ignored. Start as root to honor priorities\n",
+            parm->name, (int)parm->priority);
+        rc = pthread_create(&task->sys_task.t, NULL, (void *(*)(void *))handler, data);
+    }
+    if (rc)
+    {
+        bcmos_mutex_lock(&bcmos_res_lock);
+        STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+        bcmos_mutex_unlock(&bcmos_res_lock);
+        task->magic = 0;
+        if (!parm->handler)
+        {
+            bcmos_sem_destroy(&task->active_sem);
+        }
+        BCMOS_TRACE_RETURN(BCM_ERR_SYSCALL_ERR, "%s (%d)\n", strerror(rc), rc);
+    }
+    return BCM_ERR_OK;
+}
+
+/* Destroy task */
+bcmos_errno bcmos_task_destroy(bcmos_task *task)
+{
+    void *res;
+    int rc_cancel;
+    int rc;
+
+    if (task->magic != BCMOS_TASK_MAGIC)
+    {
+        return BCM_ERR_PARM;
+    }
+    task->destroy_request = BCMOS_TRUE;
+    task->magic = BCMOS_TASK_MAGIC_DESTROYED;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    /* The task may be waiting on semaphore. Kick it */
+    if (!task->parm.handler)
+    {
+        bcmos_sem_post(&task->active_sem);
+    }
+    rc_cancel = pthread_cancel(task->sys_task.t);
+    rc = pthread_join(task->sys_task.t, &res);
+    return (rc || ((!rc_cancel) && (res != PTHREAD_CANCELED))) ? BCM_ERR_SYSCALL_ERR : 0;
+}
+
+/** Get current task
+ * \returns task handle or NULL if not in task context
+ */
+bcmos_task *bcmos_task_current(void)
+{
+    pthread_t pt = pthread_self();
+    bcmos_task *t, *tmp;
+
+    STAILQ_FOREACH_SAFE(t, &task_list, list, tmp)
+    {
+        if (pthread_equal(pt, t->sys_task.t))
+            break;
+    }
+    return t;
+}
+
+/*
+ * Recursive mutex
+ */
+
+/* Create recursive mutex */
+bcmos_errno bcmos_mutex_create(bcmos_mutex *mutex, uint32_t flags, const char *name)
+{
+    int err;
+    err = pthread_mutexattr_init(&mutex->attr);
+    err = err ? err : pthread_mutexattr_settype(&mutex->attr, PTHREAD_MUTEX_RECURSIVE_NP);
+    err = err ? err : pthread_mutex_init(&mutex->m, &mutex->attr);
+    if (err)
+        BCMOS_TRACE_RETURN(BCM_ERR_SYSCALL_ERR, "errno=%s\n", strerror(err));
+    return BCM_ERR_OK;
+}
+
+/** Destroy mutex
+ * \param[in]   mutex   Mutex control block
+ */
+void bcmos_mutex_destroy(bcmos_mutex *mutex)
+{
+    pthread_mutex_destroy(&mutex->m);
+    pthread_mutexattr_destroy(&mutex->attr);
+}
+
+/* calculate absolute time equal to the current time + timeout */
+static inline void _bcmos_get_abs_time(struct timespec *ts, uint32_t timeout)
+{
+    int rc;
+    rc = clock_gettime(CLOCK_REALTIME, ts);
+    BUG_ON(rc);
+    ts->tv_sec += timeout / 1000000;
+    ts->tv_nsec += (timeout % 1000000) * 1000;
+    if (ts->tv_nsec > 1000000000)
+    {
+        ts->tv_sec += ts->tv_nsec / 1000000000;
+        ts->tv_nsec %= 1000000000;
+    }
+}
+
+/** Lock mutex
+ */
+void bcmos_mutex_lock(bcmos_mutex *mutex)
+{
+    int rc;
+    rc = pthread_mutex_lock(&mutex->m);
+    BUG_ON(rc);
+    return;
+}
+
+/** Release mutex
+ * \param[in]   mutex   Mutex control block
+ */
+void bcmos_mutex_unlock(bcmos_mutex *mutex)
+{
+    int rc;
+    rc = pthread_mutex_unlock(&mutex->m);
+    if (rc)
+        BCMOS_TRACE_ERR("pthread_mutex_unlock()->%d\n", rc);
+    BUG_ON(rc);
+}
+
+/*
+ * Semaphores
+ * Most of semaphore functions are inline
+ */
+
+/* Create semaphore */
+bcmos_errno bcmos_sem_create(bcmos_sem *sem, uint32_t count, uint32_t flags, const char *name)
+{
+    sem_init(&sem->s, 0, count);
+    return BCM_ERR_OK;
+}
+
+/* Destroy semaphore */
+void bcmos_sem_destroy(bcmos_sem *sem)
+{
+    sem_destroy(&sem->s);
+}
+
+/* Decrement semaphore counter. Wait if the counter is 0 */
+bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout)
+{
+    int rc;
+    struct timespec ts;
+
+    /* Init end time if necessary */
+    if (timeout && timeout != BCMOS_WAIT_FOREVER)
+    {
+        _bcmos_get_abs_time(&ts, timeout);
+    }
+
+    do
+    {
+        if (timeout == BCMOS_WAIT_FOREVER)
+        {
+            rc = sem_wait(&sem->s);
+        }
+        else if (timeout)
+        {
+            rc = sem_timedwait(&sem->s, &ts);
+        }
+        else
+        {
+            rc = sem_trywait(&sem->s);
+        }
+    } while (rc && errno == EINTR);
+
+    if (rc)
+    {
+        bcmos_errno err;
+
+        rc = errno;
+        if (rc == ETIMEDOUT)
+        {
+            err = BCM_ERR_TIMEOUT;
+        }
+        else
+        {
+            err = BCM_ERR_INTERNAL;
+            BCMOS_TRACE_ERR("sem_wait()->%d\n", rc);
+        }
+        return err;
+    }
+
+    return BCM_ERR_OK;
+}
+
+
+/*
+ * Timers
+ */
+
+/** Get current timestamp
+ * \returns the current system timestamp (us)
+ */
+uint32_t bcmos_timestamp(void)
+{
+    struct timespec tp;
+    clock_gettime(CLOCK_MONOTONIC, &tp);
+    return (tp.tv_sec * 1000000 + tp.tv_nsec / 1000);
+}
+
+/** Get current timestamp - 64 bit
+ * \returns the current system timestamp (us)
+ */
+uint64_t bcmos_timestamp64(void)
+{
+    struct timespec tp;
+    clock_gettime(CLOCK_MONOTONIC, &tp);
+    return ((uint64_t)tp.tv_sec * 1000000LL + (uint64_t)tp.tv_nsec / 1000LL);
+}
+
+/*
+ * Timer handlers
+ */
+
+
+
+/* For posix we must create timer task, because there is no way
+ * to enforce protection between a signal handler and a thread
+ */
+static bcmos_task _bcmos_timer_task;
+static sem_t _bcmos_timer_lock;
+
+static int _bcmos_tmr_task_handler(long data)
+{
+    bcmos_sys_timer *timer = (bcmos_sys_timer *)data;
+    bcmos_task *this_task = bcmos_task_current();
+
+    while(!this_task->destroy_request)
+    {
+        sem_wait(&_bcmos_timer_lock);
+        timer->handler(timer->data);
+    }
+    this_task->destroyed = BCMOS_TRUE;
+
+    return 0;
+}
+
+/* timer signal handler */
+static void timer_sig_handler(int sig, siginfo_t *si, void *uc)
+{
+    BUG_ON(si->si_code != SI_TIMER);
+    sem_post(&_bcmos_timer_lock);
+}
+
+/* Create timer */
+bcmos_errno bcmos_sys_timer_create(bcmos_sys_timer *timer, bcmos_sys_timer_handler handler, void *data)
+{
+    static bcmos_task_parm tmr_task_parm = {
+        .name = "tmr_task",
+        .priority = BCMOS_TASK_PRIORITY_0,
+        .handler = _bcmos_tmr_task_handler
+    };
+    bcmos_errno rc;
+
+    struct sigaction sa;
+    struct sigevent sev = {};
+
+    if (!timer || !handler)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "timer %p, handler %p\n", timer, handler);
+
+    timer->handler = handler;
+    timer->data = data;
+
+    sem_init(&_bcmos_timer_lock, 0, 0);
+    tmr_task_parm.data = (long)timer;
+    rc = bcmos_task_create(&_bcmos_timer_task, &tmr_task_parm);
+    if (rc)
+        BCMOS_TRACE_RETURN(rc, "Can't create timer task\n");
+
+    sa.sa_flags = SA_SIGINFO;
+    sa.sa_sigaction = timer_sig_handler;
+    sigemptyset(&sa.sa_mask);
+    if (sigaction(TIMER_SIG, &sa, NULL) == -1)
+        perror("sigaction");
+    /* Prevent timer signal from interrupting system calls */
+    if (siginterrupt(TIMER_SIG, 0) == -1)
+        perror("siginterrupt");
+
+   /* Create librt timer */
+   sev.sigev_notify = SIGEV_SIGNAL;
+   sev.sigev_signo = TIMER_SIG;
+   sev.sigev_value.sival_ptr = timer;
+   if (timer_create(CLOCK_REALTIME, &sev, &timer->t) == -1)
+       BCMOS_TRACE_RETURN(BCM_ERR_SYSCALL_ERR, "errno %s\n", strerror(errno));
+
+   return BCM_ERR_OK;
+}
+
+/* Destroy timer */
+void bcmos_sys_timer_destroy(bcmos_sys_timer *timer)
+{
+    timer_delete(timer->t);
+    sem_destroy(&_bcmos_timer_lock);
+    bcmos_task_destroy(&_bcmos_timer_task);
+}
+
+/* (Re)start timer */
+void bcmos_sys_timer_start(bcmos_sys_timer *timer, uint32_t delay)
+{
+    struct itimerspec its;
+
+    its.it_value.tv_sec = delay / 1000000;
+    its.it_value.tv_nsec = (delay % 1000000) * 1000;
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;
+    if (timer_settime(timer->t, 0, &its, NULL) == -1)
+    {
+        BCMOS_TRACE_ERR("timer_settime errno %s\n", strerror(errno));
+        BUG();
+    }
+}
+
+/* Stop timer if running */
+void bcmos_sys_timer_stop(bcmos_sys_timer *timer)
+{
+    struct itimerspec its;
+
+    BUG_ON(!timer);
+    memset(&its, 0, sizeof(its));
+    timer_settime(timer->t, 0, &its, NULL);
+}
+
+
+/* Suspend current task for a time */
+void bcmos_usleep(uint32_t us)
+{
+    uint32_t ts = bcmos_timestamp();
+    uint32_t tse = ts + us;
+    int32_t d = (us > 1000000) ? 1000000 : us;
+
+    do
+    {
+        usleep(d);
+        d = tse - bcmos_timestamp();
+        if (d > 1000000) d = 1000000;
+    } while (d > 0);
+}
+
+/*
+ * Memory management
+ */
+
+/* Allocate memory from the main heap */
+void *bcmos_alloc(uint32_t size)
+{
+    return malloc(size);
+}
+
+/* Release memory to the main pool */
+void bcmos_free(void *ptr)
+{
+    free(ptr);
+}
+
+/*
+ * Byte memory pool
+ */
+
+/* Memory block header */
+typedef struct bcmos_byte_memblk
+{
+    bcmos_byte_pool *pool;      /** pool that owns the block */
+    uint32_t size;              /** block size (bytes) including bcmos_byte_memblk header */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /** magic number */
+#define BCMOS_MEM_MAGIC_ALLOC   (('m'<<24) | ('b' << 16) | ('l' << 8) | 'k')
+#define BCMOS_MEM_MAGIC_FREE    (('m'<<24) | ('b' << 16) | ('l' << 8) | '~')
+#endif
+} bcmos_byte_memblk;
+
+/* Create byte memory pool */
+bcmos_errno bcmos_byte_pool_create(bcmos_byte_pool *pool, const bcmos_byte_pool_parm *parm)
+{
+    if (!pool || !parm)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool %p, parm %p\n", pool, parm);
+    }
+
+    BCM_MEMZERO_STRUCT(pool);
+    pool->parm = *parm;
+    if (!pool->parm.size)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "size %u\n", parm->size);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_VALID;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Destroy memory pool */
+bcmos_errno bcmos_byte_pool_destroy(bcmos_byte_pool *pool)
+{
+    if (pool->allocated)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_STATE, "%u bytes of memory are still allocated from the pool %s\n",
+            pool->allocated, pool->parm.name);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_DELETED;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Allocate memory from memory pool */
+void *bcmos_byte_pool_alloc(bcmos_byte_pool *pool, uint32_t size)
+{
+    bcmos_byte_memblk *blk;
+    uint32_t byte_size;
+    void *ptr;
+
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+#endif
+
+    if (size + pool->allocated > pool->parm.size)
+        return NULL;
+
+    byte_size = size + sizeof(bcmos_byte_memblk);
+#ifdef BCMOS_MEM_DEBUG
+    byte_size += sizeof(uint32_t); /* block suffix */
+#endif
+    /* ToDo: Maintain LL of allocated blocks */
+    blk = (bcmos_byte_memblk *)malloc(byte_size);
+    if (!blk)
+        return NULL;
+    ptr = (void *)(blk + 1);
+    blk->size = byte_size;
+    pool->allocated += byte_size;
+    blk->pool = pool;
+#ifdef BCMOS_MEM_DEBUG
+    blk->magic = BCMOS_MEM_MAGIC_ALLOC;
+    *(uint32_t *)((long)blk + byte_size - sizeof(uint32_t)) = BCMOS_MEM_MAGIC_ALLOC;
+#endif
+
+    return ptr;
+}
+
+/* Release memory allocated using bcmos_byte_pool_alloc() */
+void bcmos_byte_pool_free(void *ptr)
+{
+    bcmos_byte_memblk *blk;
+    bcmos_byte_pool *pool;
+
+    BUG_ON(!ptr);
+    blk = (bcmos_byte_memblk *)((long)ptr - sizeof(bcmos_byte_memblk));
+    pool = blk->pool;
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+    BUG_ON(blk->magic != BCMOS_MEM_MAGIC_ALLOC);
+    BUG_ON(*(uint32_t *)((long)blk + blk->size - sizeof(uint32_t)) != BCMOS_MEM_MAGIC_ALLOC);
+    blk->magic = BCMOS_MEM_MAGIC_FREE;
+#endif
+    pool->allocated -= blk->size;
+    free(blk);
+}
+
+void _bcmos_backtrace(void)
+{
+    void *array[32];
+    size_t size;
+    char **strings;
+    size_t i;
+
+    size = backtrace(array, sizeof(array)/sizeof(array[0]));
+    strings = backtrace_symbols(array, size);
+
+    printf("Obtained %zd stack frames.\n", size);
+
+    for (i = 0; i < size; i++)
+        printf("%s\n", strings[i]);
+
+    free(strings);
+}
+
+/* stub for int enable */
+void bcmos_int_enable(int irq)
+{
+}
+
+void bcmos_int_disable(int irq)
+{
+}
+
+/* stub for int connect */
+int bcmos_int_connect(int irq, int cpu, int flags,
+    int (*isr)(int irq, void *priv), const char *name, void *priv)
+{
+    return 0;
+}
+
+/* Functions common for domain socket and UDP socket - based message queues */
+#if defined(BCMOS_MSG_QUEUE_DOMAIN_SOCKET) || defined(BCMOS_MSG_QUEUE_UDP_SOCKET)
+
+/** "send" to socket */
+static bcmos_errno _bcmos_socket_send(bcmos_msg_queue *queue, uint8_t *buf, uint32_t buf_length)
+{
+    int rc;
+    /* Message queue without remote endpoint address doesn't support transmit */
+    if (!queue->ep_extra_data_size)
+        return BCM_ERR_NOT_SUPPORTED;
+    rc = sendto(queue->ep, buf, buf_length, 0,
+        (struct sockaddr *)queue->ep_extra_data, queue->ep_extra_data_size);
+    return (rc == buf_length) ? BCM_ERR_OK : BCM_ERR_COMM_FAIL;
+}
+
+/** "recv" from socket */
+static bcmos_errno _bcmos_socket_recv(bcmos_msg_queue *queue, uint32_t timeout, uint8_t **buf, uint32_t *buf_length)
+{
+    int rc;
+    int wait = 0;
+
+    /* Message queue without local endpoint address doesn't support receive */
+    if (!queue->q.parm.local_ep_address)
+        return BCM_ERR_NOT_SUPPORTED;
+
+    if (timeout && timeout != BCMOS_WAIT_FOREVER)
+    {
+        fd_set read_fds;
+        struct timeval tv;
+
+        FD_ZERO(&read_fds);
+        FD_SET(queue->ep, &read_fds);
+        tv.tv_sec = timeout / 1000000;
+        tv.tv_usec = (timeout % 1000000) * 1000;
+        rc = select(queue->ep + 1, &read_fds, NULL, NULL, &tv);
+        if (rc < 0)
+        {
+            return BCM_ERR_COMM_FAIL;
+        }
+        if (!rc || !FD_ISSET(queue->ep, &read_fds))
+            return BCM_ERR_TIMEOUT;
+        wait = MSG_DONTWAIT;
+    }
+
+    rc = recv(queue->ep, queue->recv_buf, queue->q.parm.max_mtu, wait);
+    if (rc < 0)
+    {
+        return BCM_ERR_COMM_FAIL;
+    }
+    if (rc == 0)
+        return BCM_ERR_NOENT;
+
+    *buf = queue->recv_buf;
+    *buf_length = rc;
+    return BCM_ERR_OK;
+}
+
+
+static bcmos_errno _bcmos_socket_close(bcmos_msg_queue *queue)
+{
+    /* Close domain socket */
+    if (queue->ep > 0)
+    {
+        close(queue->ep);
+    }
+    if (queue->ep_extra_data)
+    {
+        bcmos_free(queue->ep_extra_data);
+    }
+    return BCM_ERR_OK;
+}
+
+
+/* Pack message for over-the-socket transmission.
+ * This function is good for case when both queue ends are on the same CPU
+ * and there is no need to do any translation.
+ */
+static bcmos_errno _bcmos_transparent_pack(bcmos_msg_queue *queue, bcmos_msg *msg, uint8_t **buf, uint32_t *buf_length)
+{
+    uint32_t size = BCMOS_MSG_HDR_SIZE + msg->size;
+
+    if (size > queue->q.parm.max_mtu)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_OVERFLOW, "Attempt to send message longer than configured max_mtu %u > %u\n",
+            size, queue->q.parm.max_mtu);
+    }
+    bcmos_msg_hdr_pack(msg, queue->send_buf, msg->size);
+    if (msg->size)
+    {
+        BUG_ON(msg->data == NULL);
+        memcpy(queue->send_buf + BCMOS_MSG_HDR_SIZE, msg->data, msg->size);
+    }
+    *buf = queue->send_buf;
+    *buf_length = size;
+    return BCM_ERR_OK;
+}
+
+/** "unpack" message. In case of domain socket both queue ends are in the same CPU.
+ * Message is sent as-is
+ */
+static bcmos_errno _bcmos_transparent_unpack(bcmos_msg_queue *queue, uint8_t *buf, uint32_t buf_length, bcmos_msg **msg)
+{
+    bcmos_msg *m;
+
+    if (buf_length < BCMOS_MSG_HDR_SIZE)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_INTERNAL, "Received message is too short (%u)\n", buf_length);
+    }
+
+    /* Adjust buf_length to account for difference in packed and unpacked message header sizes */
+    buf_length -= BCMOS_MSG_HDR_SIZE;
+    buf_length += sizeof(bcmos_msg);
+
+    m = bcmos_alloc(buf_length);
+    if (!m)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "Received message discarded: %u bytes\n", buf_length);
+    }
+
+    bcmos_msg_hdr_unpack(buf, m);
+    m->release = NULL;
+    m->data_release = NULL;
+    if (m->size != buf_length - sizeof(bcmos_msg))
+    {
+        BCMOS_TRACE_ERR("Received message is insane. Expected data length %u, got %u\n",
+            m->size, buf_length - sizeof(bcmos_msg));
+        bcmos_free(m);
+        return BCM_ERR_INTERNAL;
+    }
+    if (m->size)
+    {
+        m->data = m->start = (void *)(m + 1);
+        memcpy(m->data, &buf[BCMOS_MSG_HDR_SIZE], m->size);
+    }
+    else
+    {
+        m->data = m->start = NULL;
+    }
+    *msg = m;
+
+    return BCM_ERR_OK;
+}
+
+
+#endif
+
+/* Domain-socket-based inter-process communication */
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+
+bcmos_errno bcmos_sys_msg_queue_domain_socket_open(bcmos_msg_queue *queue)
+{
+    struct sockaddr_un sa;
+
+    /* Open domain socket */
+    queue->ep = socket(AF_UNIX, SOCK_DGRAM, 0);
+    if (queue->ep < 0)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Can't create domain socket. error %s\n", strerror(errno));
+    }
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sun_family = AF_UNIX;
+
+    /* If local_ep_address is set - the queue supports receive */
+    if (queue->q.parm.local_ep_address)
+    {
+        strncpy(sa.sun_path, queue->q.parm.local_ep_address, sizeof(sa.sun_path) - 1);
+        /* In linux path can start from 0 character */
+        if (!sa.sun_path[0])
+        {
+            strncpy(&sa.sun_path[1], &queue->q.parm.local_ep_address[1], sizeof(sa.sun_path) - 1);
+        }
+        if (bind(queue->ep, (struct sockaddr *)&sa, sizeof(sa)) < 0)
+        {
+            int err = errno;
+            close(queue->ep);
+            BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Can't bind domain socket to %s. error %s\n",
+                queue->q.parm.local_ep_address, strerror(err));
+        }
+    }
+
+    /* If remote_ep_address is set - the queue supports transmit */
+    if (queue->q.parm.remote_ep_address)
+    {
+        queue->ep_extra_data = bcmos_calloc(sizeof(struct sockaddr_un));
+        if (!queue->ep_extra_data)
+        {
+            close(queue->ep);
+            return BCM_ERR_NOMEM;
+        }
+        strncpy(sa.sun_path, queue->q.parm.remote_ep_address, sizeof(sa.sun_path) - 1);
+        /* In linux path can start from 0 character */
+        if (!sa.sun_path[0])
+        {
+            strncpy(&sa.sun_path[1], &queue->q.parm.remote_ep_address[1], sizeof(sa.sun_path) - 1);
+        }
+        memcpy(queue->ep_extra_data, &sa, sizeof(sa));
+        queue->ep_extra_data_size = sizeof(sa);
+    }
+
+    /* Set callbacks */
+    queue->q.parm.close = _bcmos_socket_close;
+    queue->q.parm.send = _bcmos_socket_send;
+    queue->q.parm.recv = _bcmos_socket_recv;
+    if (!queue->q.parm.pack)
+        queue->q.parm.pack = _bcmos_transparent_pack;
+    if (!queue->q.parm.unpack)
+        queue->q.parm.unpack = _bcmos_transparent_unpack;
+
+    return BCM_ERR_OK;
+}
+
+#endif
+
+/* UDP-socket-based inter-process communication */
+#ifdef BCMOS_MSG_QUEUE_UDP_SOCKET
+
+static bcmos_errno _bcmos_parse_ip_port(const char *s, struct sockaddr_in *sa)
+{
+    uint32_t ip;
+    int n;
+    uint32_t ip1, ip2, ip3, ip4, port;
+
+    n = sscanf(s, "%u.%u.%u.%u:%u", &ip1, &ip2, &ip3, &ip4, &port);
+    if (n != 5 || ip1 > 0xff || ip2 > 0xff || ip3 > 0xff || ip4 > 0xff || port > 0xffff)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Can't parse %s. Must be ip_address:port\n", s);
+    }
+    ip = (ip1 << 24) | (ip2 << 16) | (ip3 << 8) | ip4;
+    sa->sin_port = htons(port);
+    sa->sin_addr.s_addr = htonl(ip);
+
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmos_sys_msg_queue_udp_socket_open(bcmos_msg_queue *queue)
+{
+    struct sockaddr_in sa;
+    bcmos_errno rc;
+
+    /* Open UDP socket */
+    queue->ep = socket(AF_INET, SOCK_DGRAM, 0);
+    if (queue->ep < 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;
+
+    /* If local_ep_address is set - the queue supports receive */
+    if (queue->q.parm.local_ep_address)
+    {
+        rc = _bcmos_parse_ip_port(queue->q.parm.local_ep_address, &sa);
+        if (rc)
+            return rc;
+        if (!sa.sin_addr.s_addr)
+            sa.sin_addr.s_addr = INADDR_ANY;
+        if (bind(queue->ep, (struct sockaddr *)&sa, sizeof(sa)) < 0)
+        {
+            int err = errno;
+            close(queue->ep);
+            BCMOS_TRACE_RETURN(BCM_ERR_PARM, "Can't bind UDP socket to %s. error %s\n",
+                queue->q.parm.local_ep_address, strerror(err));
+        }
+    }
+
+    /* If remote_ep_address is set - the queue supports transmit */
+    if (queue->q.parm.remote_ep_address)
+    {
+        rc = _bcmos_parse_ip_port(queue->q.parm.remote_ep_address, &sa);
+        if (rc)
+            return rc;
+        queue->ep_extra_data = bcmos_calloc(sizeof(sa));
+        if (!queue->ep_extra_data)
+        {
+            close(queue->ep);
+            return BCM_ERR_NOMEM;
+        }
+        memcpy(queue->ep_extra_data, &sa, sizeof(sa));
+        queue->ep_extra_data_size = sizeof(sa);
+    }
+
+    /* Set callbacks */
+    queue->q.parm.close = _bcmos_socket_close;
+    queue->q.parm.send = _bcmos_socket_send;
+    queue->q.parm.recv = _bcmos_socket_recv;
+    if (!queue->q.parm.pack)
+        queue->q.parm.pack = _bcmos_transparent_pack;
+    if (!queue->q.parm.unpack)
+        queue->q.parm.unpack = _bcmos_transparent_unpack;
+
+    return BCM_ERR_OK;
+}
+#endif
diff --git a/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.h b/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.h
new file mode 100644
index 0000000..9dc902e
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/posix/bcmos_system.h
@@ -0,0 +1,301 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmos_system.h
+ * Maple System Services
+ * posix port: simulation
+ */
+
+#ifndef BCMOS_SYSTEM_H_
+#define BCMOS_SYSTEM_H_
+
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <execinfo.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* posix port has only been tested in linux user space */
+#define LINUX_USER_SPACE
+
+/* Re-define GNU typeof as ISO __typeof__ */
+#define typeof __typeof__
+
+void _bcmos_backtrace(void);
+
+#define BUG_ON_PRINT(condition, fmt, args...) \
+    do \
+    { \
+        if (condition) \
+        { \
+            BCMOS_TRACE_ERR(fmt, ##args); \
+            assert(!(condition)); \
+        } \
+    } while (0)
+
+#define BUG_ON(condition)     BUG_ON_PRINT((condition), "BUG in %s %d!\n", __FUNCTION__, __LINE__)
+#define BUG()                 BUG_ON(1)
+#define BUG_UNLESS(condition) BUG_ON(!(condition))
+
+/* If 'err' is not BCM_ERR_OK, there is a bug in the software - halt and print the specified message */
+#define BUG_ON_ERROR(err, fmt, args...) \
+    BUG_ON_PRINT((err) != BCM_ERR_OK, \
+        "%s:%d: err=%s (%d): " fmt, \
+        __FUNCTION__, __LINE__, bcmos_strerror(err), (err), ##args)
+
+/* Specify here which system functions are inlined */
+
+#define BCMOS_FASTLOCK_INLINE
+/* #define BCMOS_SEM_WAIT_INLINE */
+#define BCMOS_SEM_POST_INLINE
+#define BCMOS_TRACE_PRINTF
+/* #define BCMOS_BYTE_POOL_ALLOC_FREE_INLINE */
+/* #define BCMOS_MALLOC_FREE_INLINE */
+/* #define BCMOS_CALLOC_INLINE */
+#define BCMOS_DMA_ALLOC_FREE_INLINE
+#define BCMOS_VIRT_TO_PHYS_INLINE
+#define BCMOS_CACHE_INLINE
+
+#include "bcmos_common.h"
+
+/* posix-specific stuff */
+
+/*
+ * Synchronization
+ */
+
+/** \addtogroup system_mutex
+ * @{
+ */
+
+/** Mutex control block */
+struct bcmos_mutex
+{
+    pthread_mutex_t m;          /**< pthread mutex */
+    pthread_mutexattr_t attr;   /**< pthread mutex attribute */
+};
+
+/** @} system_mutex */
+
+/** \addtogroup system_fastlock
+ * @{
+ */
+
+/** Fast lock control block */
+struct bcmos_fastlock
+{
+    bcmos_mutex m;
+};
+
+/** Fastlock initializer. Can be used instead of calling bcmos_fastlock_init() */
+#define BCMOS_FASTLOCK_INITIALIZER      { { PTHREAD_MUTEX_INITIALIZER } }
+
+/* Init fastlock */
+static inline void bcmos_fastlock_init(bcmos_fastlock *lock, uint32_t flags)
+{
+    bcmos_mutex_create(&lock->m, 0, NULL);
+}
+
+/* Take fast lock */
+static inline long bcmos_fastlock_lock(bcmos_fastlock *lock)
+{
+    bcmos_mutex_lock(&lock->m);
+    return 0;
+}
+
+/* Release fast lock */
+static inline void bcmos_fastlock_unlock(bcmos_fastlock *lock, long flags)
+{
+    bcmos_mutex_unlock(&lock->m);
+}
+
+/** @} system_fastlock */
+
+/** \addtogroup system_sem
+ * @{
+ */
+
+/** Semaphore control block */
+struct bcmos_sem
+{
+    sem_t s;            /**< pthread semaphore */
+};
+
+/* Increment semaphore counter */
+static inline void bcmos_sem_post(bcmos_sem *sem)
+{
+    sem_post(&sem->s);
+}
+
+/** @} system_sem */
+
+/** \addtogroup system_timer
+ * @{
+ */
+
+/** System timer */
+struct bcmos_sys_timer
+{
+    timer_t t;                          /**< librt timer */
+    bcmos_sys_timer_handler handler;    /**< Timer handler */
+    void *data;                         /**< Parameter to be passed to the handler */
+};
+
+/** @} system_timer */
+
+/** \addtogroup system_task
+ * @{
+ */
+
+/** OS-specific task control block extension */
+typedef struct bcmos_sys_task
+{
+    pthread_t t;                        /**< posix pthread */
+} bcmos_sys_task;
+
+/** @} system_task */
+
+/** \addtogroup byte_pool
+ * @{
+ */
+
+/** Memory pool control block */
+struct bcmos_byte_pool
+{
+    bcmos_byte_pool_parm parm;  /**< Pool parameters */
+    uint32_t allocated;         /**< Number of bytes allocated */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /**< magic number */
+#define BCMOS_BYTE_POOL_VALID           (('b'<<24) | ('y' << 16) | ('p' << 8) | 'o')
+#define BCMOS_BYTE_POOL_DELETED         (('b'<<24) | ('y' << 16) | ('p' << 8) | '~')
+#endif
+};
+
+/** @} */
+
+/* Print */
+#define bcmos_sys_vprintf(fmt, args)        vprintf(fmt, args)
+
+/* A few macros to enable linux kernel space compilation */
+#define EXPORT_SYMBOL(_sym)
+
+/*
+ * The following low-level functions are mostly for simulation
+ */
+
+/*
+ * DMA-able memory allocation
+ */
+
+/* Allocate DMA-able memory */
+static inline void *bcmos_dma_alloc(uint8_t device, uint32_t size)
+{
+    return bcmos_alloc(size);
+}
+
+/* Release DMA-able memory */
+static inline void bcmos_dma_free(uint8_t device, void *ptr)
+{
+    bcmos_free(ptr);
+}
+
+/* Convert virtual address to physical address */
+static inline unsigned long bcmos_virt_to_phys(void *va)
+{
+    return (unsigned long)(va);
+}
+
+/* Invalidate address area in data cache. Dirty cache lines content is discarded. */
+static inline void bcmos_dcache_inv(void *start, uint32_t size)
+{
+}
+
+/* Flush address area in data cache. Dirty cache lines are committed to memory. */
+static inline void bcmos_dcache_flush(void *start, uint32_t size)
+{
+}
+
+/* write barrier */
+static inline void bcmos_barrier(void)
+{
+}
+
+static inline void bcm_pci_write32(volatile uint32_t *address, uint32_t value)
+{
+}
+
+static inline uint32_t bcm_pci_read32(const volatile uint32_t *address)
+{
+	return -1;
+}
+
+/* Check in-irq status */
+static inline bcmos_bool is_irq_mode(void)
+{
+    return BCMOS_FALSE;
+}
+
+/* Check if interrupts are disabled */
+static inline bcmos_bool is_irq_disabled(void)
+{
+    return BCMOS_FALSE;
+}
+
+/*
+ * Internal (to OS abstraction) functions for messaging over domain and UDP sockets
+ */
+#ifdef BCMOS_MSG_QUEUE_DOMAIN_SOCKET
+bcmos_errno bcmos_sys_msg_queue_domain_socket_open(bcmos_msg_queue *queue);
+#endif
+
+#ifdef BCMOS_MSG_QUEUE_UDP_SOCKET
+bcmos_errno bcmos_sys_msg_queue_udp_socket_open(bcmos_msg_queue *queue);
+#endif
+
+/* 2nd part of OS-independent declarations */
+#include "bcmos_common2.h"
+
+#endif /* BCMOS_SYSTEM_H_ */
diff --git a/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.c b/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.c
new file mode 100644
index 0000000..645c8d0
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.c
@@ -0,0 +1,742 @@
+/*
+<: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 <vxWorks.h>
+#include <unistd.h>
+#include <taskLib.h>
+#include <wdLib.h>
+#include <sysLib.h>
+#include <errnoLib.h>
+#include <time.h>
+#include <intLib.h>
+#include <cacheLib.h>
+#include "memPartLib.h"
+
+#ifdef HOST_CPU_IS_MIPS
+#include "arch/mips/archMips.h"
+#endif
+
+#include <iv.h>
+
+#define BCMOS_DEFAULT_STACK_SIZE (100*1024)/*0x4000*/
+#define BCMOS_MICROSECONDS_TO_TICKS(u) (u)/1000000*bcmos_timer_get_frequency() + BCMOS_DIVIDE_ROUND_UP(((u)%1000000)*bcmos_timer_get_frequency(),1000000)
+
+/* task control blocks */
+extern STAILQ_HEAD(task_list, bcmos_task) task_list;
+
+/* global OS lock */
+extern bcmos_mutex bcmos_res_lock;
+
+/*
+ * Default task handler
+ */
+extern int bcmos_dft_task_handler(long data);
+
+bcmos_errno bcmos_sys_init(void)
+{
+    return BCM_ERR_OK;
+}
+
+/* Clean-up system library */
+void bcmos_sys_exit(void)
+{
+}
+
+static uint32_t bcmos_timer_get_frequency()
+{
+    static uint32_t frequency = 0;
+    if (!frequency)
+        frequency = sysClkRateGet();
+    return frequency;
+}
+
+bcmos_errno bcmos_task_create(bcmos_task *task, const bcmos_task_parm *parm)
+{
+    F_bcmos_task_handler handler;
+    void *data;
+
+    if (!task || !parm)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "task %p, parm %p\n", (void* )task, (void* )parm);
+    memset(task, 0, sizeof ( *task ));
+
+    if (parm->handler)
+    {
+        /* "traditional task */
+        handler = parm->handler;
+        data = (void *)parm->data;
+    }
+    else
+    {
+        bcmos_errno rc;
+        /* "integrated" task */
+        handler = bcmos_dft_task_handler;
+        data = task;
+
+        /* Initialize and lock mutex to wait on */
+        rc = bcmos_sem_create(&task->active_sem, 0, task->parm.flags, parm->name);
+        if (rc)
+        {
+            BCMOS_TRACE_ERR("Task %s: can't create active_sem. Error %s (%d)\n",
+                parm->name, bcmos_strerror(rc), rc);
+            return rc;
+        }
+    }
+
+    task->parm = *parm;
+    /* Copy name to make sure that it is not released - in case it was on the stack */
+    if (task->parm.name)
+    {
+        strncpy(task->name, task->parm.name, sizeof(task->name) - 1);
+        task->parm.name = task->name;
+    }
+    bcmos_fastlock_init(&task->active_lock, 0);
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_INSERT_TAIL(&task_list, task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    task->magic = BCMOS_TASK_MAGIC;
+    task->sys_task.t = taskSpawn((char*)parm->name,
+                        10 + parm->priority * 2,
+                        0,
+                        parm->stack_size ? parm->stack_size : BCMOS_DEFAULT_STACK_SIZE,
+                        (FUNCPTR)handler,
+                        (int32_t)data,
+                        0,
+                        0,
+                        0,
+                        0,
+                        0,
+                        0,
+                        0,
+                        0,
+                        0);
+
+    if (task->sys_task.t == ERROR)
+    {
+        bcmos_mutex_lock(&bcmos_res_lock);
+        STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+        bcmos_mutex_unlock(&bcmos_res_lock);
+        task->magic = 0;
+        if (!parm->handler)
+        {
+            bcmos_sem_destroy(&task->active_sem);
+        }
+        BCMOS_TRACE_ERR("(%s) Error: taskSpawn, errnoGet()=%d\n", __FUNCTION__, errnoGet());
+        BUG();
+    }
+
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmos_task_destroy(bcmos_task *task)
+{
+    if (task->magic != BCMOS_TASK_MAGIC)
+    {
+        return BCM_ERR_PARM;
+    }
+    task->destroy_request = BCMOS_TRUE;
+    bcmos_mutex_lock(&bcmos_res_lock);
+    STAILQ_REMOVE(&task_list, task, bcmos_task, list);
+    bcmos_mutex_unlock(&bcmos_res_lock);
+    task->magic = BCMOS_TASK_MAGIC_DESTROYED;
+    /* The task may be waiting on semaphore. Kick it */
+    if (!task->parm.handler)
+    {
+        bcmos_sem_post(&task->active_sem);
+    }
+    if (taskDelete(task->sys_task.t) != OK)
+    {
+        BCMOS_TRACE_ERR("(%s) Error: taskDelete, errnoGet()=%d\n", __FUNCTION__, errnoGet());
+        BUG();
+    }
+
+    return BCM_ERR_OK;
+}
+
+bcmos_task *bcmos_task_current(void)
+{
+    uint32_t pt = taskIdSelf();
+    bcmos_task *t, *tmp;
+
+    STAILQ_FOREACH_SAFE(t, &task_list, list, tmp)
+    {
+        if (pt == t->sys_task.t)
+            break;
+    }
+    return t;
+}
+
+void *bcmos_alloc(uint32_t size)
+{
+    return malloc(size);
+}
+
+void bcmos_free(void *ptr)
+{
+    free(ptr);
+}
+
+inline static void bcmos_sem_mutex_destroy(uint32_t sm)
+{
+    if (semDelete((SEM_ID)sm) != OK)
+    {
+        BCMOS_TRACE_ERR("(%s) Error: semDelete, errnoGet()=%d\n", __FUNCTION__, errnoGet());
+        BUG();
+    }
+}
+
+inline static bcmos_errno bcmos_sem_mutex_wait(uint32_t sm, uint32_t timeout)
+{
+    int errno;
+    STATUS status;
+
+    timeout = ((timeout == BCMOS_WAIT_FOREVER )? WAIT_FOREVER : BCMOS_MICROSECONDS_TO_TICKS(timeout));
+    status = semTake((SEM_ID)sm, timeout);
+    if (status != OK)
+    {
+        errno = errnoGet();
+        if (errno == S_objLib_OBJ_TIMEOUT)
+        {
+            return BCM_ERR_TIMEOUT;
+        }
+        BUG();
+        return BCM_ERR_INTERNAL;
+    }
+    return BCM_ERR_OK;
+}
+
+inline static void bcmos_sem_mutex_post(uint32_t sm)
+{
+    STATUS status;
+
+    status = semGive((SEM_ID)sm);
+    if (status != OK)
+    {
+        BCMOS_TRACE_ERR("(%s) Error: semGive, status=%d\n", __FUNCTION__, status);
+        BUG();
+    }
+}
+
+bcmos_errno bcmos_sem_create(bcmos_sem *sem, uint32_t count, uint32_t flags, const char *name)
+{
+    SEM_ID semaphore;
+
+    semaphore = semCCreate(SEM_Q_PRIORITY, (SEM_B_STATE)count);
+    if (semaphore == NULL)
+    {
+        BCMOS_TRACE_ERR("(%s) Error: semCCreate, errnoGet()=%d\n", __FUNCTION__, errnoGet());
+        BUG();
+    }
+    sem->s = (uint32_t)semaphore;
+
+    return BCM_ERR_OK;
+}
+
+void bcmos_sem_destroy(bcmos_sem *sem)
+{
+    bcmos_sem_mutex_destroy(sem->s);
+}
+
+bcmos_errno bcmos_sem_wait(bcmos_sem *sem, uint32_t timeout)
+{
+    return bcmos_sem_mutex_wait(sem->s, timeout);
+}
+
+void bcmos_sem_post(bcmos_sem *sem)
+{
+    bcmos_sem_mutex_post(sem->s);
+}
+
+bcmos_errno bcmos_mutex_create(bcmos_mutex *mutex, uint32_t flags, const char *name)
+{
+    SEM_ID semaphore;
+    int options;
+
+    /* SEM_INVERSION_SAFE: Enable (by default) the prevention of priority inversion problem */
+    options = SEM_Q_PRIORITY | SEM_INVERSION_SAFE;
+
+    semaphore = semMCreate(options);
+    if (semaphore == NULL)
+    {
+        BCMOS_TRACE_ERR("(%s) Error: semCCreate, errnoGet()=%d\n", __FUNCTION__, errnoGet());
+        BUG();
+    }
+
+    mutex->m = (uint32_t)semaphore;
+
+    return BCM_ERR_OK;
+}
+
+void bcmos_mutex_destroy(bcmos_mutex *mutex)
+{
+    bcmos_sem_mutex_destroy(mutex->m);
+}
+
+void bcmos_mutex_lock(bcmos_mutex *mutex)
+{
+    bcmos_sem_mutex_wait(mutex->m, BCMOS_WAIT_FOREVER);
+}
+
+void bcmos_mutex_unlock(bcmos_mutex *mutex)
+{
+    bcmos_sem_mutex_post(mutex->m);
+}
+
+void bcmos_fastlock_init(bcmos_fastlock *lock, uint32_t flags)
+{
+}
+
+long bcmos_fastlock_lock(bcmos_fastlock *lock)
+{
+    return (long)intLock();
+}
+
+void bcmos_fastlock_unlock(bcmos_fastlock *lock, long flags)
+{
+    intUnlock(flags);
+}
+
+bcmos_errno bcmos_sys_timer_create(bcmos_sys_timer *timer, bcmos_sys_timer_handler handler, void *data)
+{
+    WDOG_ID watchdog;
+
+    if (!timer || !handler)
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "timer %p, handler %p\n", timer, handler);
+
+    /* Call the underlying OS */
+    watchdog = wdCreate();
+    if (watchdog == NULL)
+        BCMOS_TRACE_RETURN(BCM_ERR_SYSCALL_ERR, "errno %s\n", strerror(errno));
+
+    timer->t = (uint32_t)watchdog;
+    timer->handler = handler;
+    timer->data = data;
+
+    return BCM_ERR_OK;
+}
+
+void bcmos_sys_timer_destroy(bcmos_sys_timer *timer)
+{
+    STATUS status;
+    status = wdDelete((WDOG_ID)timer->t);
+    BCMOS_TRACE_DEBUG("wdDelete: status=%d\n", status);
+}
+
+static void _bcmos_time_handler_wrapper(long data)
+{
+    bcmos_sys_timer * timer = (bcmos_sys_timer*)data ;
+    timer->handler(timer->data);
+}
+
+void bcmos_sys_timer_start(bcmos_sys_timer *timer, uint32_t delay)
+{
+    STATUS status;
+    status = wdStart((WDOG_ID)timer->t, BCMOS_MICROSECONDS_TO_TICKS(delay), (FUNCPTR)_bcmos_time_handler_wrapper, (long)timer);
+    if (status == ERROR)
+    {
+        BCMOS_TRACE_ERR("wdStart status %d\n", status);
+        BUG();
+    }
+}
+
+void bcmos_sys_timer_stop(bcmos_sys_timer *timer)
+{
+    STATUS status;
+    status = wdCancel((WDOG_ID)timer->t);
+    if (status == ERROR)
+    {
+        BCMOS_TRACE_ERR("wdCancel status=%d\n", status);
+        BUG();
+    }
+}
+
+void bcmos_usleep(uint32_t us)
+{
+    struct timespec ts;
+
+    ts.tv_sec = us / 1000000;
+    ts.tv_nsec = ( us % 1000000 ) * 1000;
+
+    nanosleep(&ts, 0);
+}
+
+uint32_t bcmos_timestamp(void)
+{
+    struct timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    return (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
+}
+
+/** Get current timestamp - 64 bit
+ * \returns the current system timestamp (us)
+ */
+uint64_t bcmos_timestamp64(void)
+{
+    struct timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    return ((uint64_t)ts.tv_sec * 1000000LL + (uint64_t)ts.tv_nsec / 1000LL);
+}
+
+/*
+ * Byte memory pool
+ */
+
+/* Memory block header */
+typedef struct bcmos_byte_memblk
+{
+    bcmos_byte_pool *pool;      /** pool that owns the block */
+    uint32_t size;              /** block size (bytes) including bcmos_byte_memblk header */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /** magic number */
+#define BCMOS_MEM_MAGIC_ALLOC   (('m'<<24) | ('b' << 16) | ('l' << 8) | 'k')
+#define BCMOS_MEM_MAGIC_FREE    (('m'<<24) | ('b' << 16) | ('l' << 8) | '~')
+#endif
+} bcmos_byte_memblk;
+
+/* Create byte memory pool */
+bcmos_errno bcmos_byte_pool_create(bcmos_byte_pool *pool, const bcmos_byte_pool_parm *parm)
+{
+    if (!pool || !parm)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "pool %p, parm %p\n", pool, parm);
+    }
+
+    BCM_MEMZERO_STRUCT(pool);
+    pool->parm = *parm;
+    if (!pool->parm.size)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_PARM, "size %u\n", parm->size);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_VALID;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Destroy memory pool */
+bcmos_errno bcmos_byte_pool_destroy(bcmos_byte_pool *pool)
+{
+    if (pool->allocated)
+    {
+        BCMOS_TRACE_RETURN(BCM_ERR_STATE, "%u bytes of memory are still allocated from the pool %s\n",
+            pool->allocated, pool->parm.name);
+    }
+#ifdef BCMOS_MEM_DEBUG
+    pool->magic = BCMOS_BYTE_POOL_DELETED;
+#endif
+    return BCM_ERR_OK;
+}
+
+/* Allocate memory from memory pool */
+void *bcmos_byte_pool_alloc(bcmos_byte_pool *pool, uint32_t size)
+{
+    bcmos_byte_memblk *blk;
+    uint32_t byte_size;
+    void *ptr;
+
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+#endif
+
+    if (size + pool->allocated > pool->parm.size)
+        return NULL;
+
+    byte_size = size + sizeof(bcmos_byte_memblk);
+#ifdef BCMOS_MEM_DEBUG
+    byte_size += sizeof(uint32_t); /* block suffix */
+#endif
+    /* ToDo: Maintain LL of allocated blocks */
+    blk = (bcmos_byte_memblk *)malloc(byte_size);
+    if (!blk)
+        return NULL;
+    ptr = (void *)(blk + 1);
+    blk->size = byte_size;
+    pool->allocated += byte_size;
+    blk->pool = pool;
+#ifdef BCMOS_MEM_DEBUG
+    blk->magic = BCMOS_MEM_MAGIC_ALLOC;
+    *(uint32_t *)((long)blk + byte_size - sizeof(uint32_t)) = BCMOS_MEM_MAGIC_ALLOC;
+#endif
+
+    return ptr;
+}
+
+/* Release memory allocated using bcmos_byte_pool_alloc() */
+void bcmos_byte_pool_free(void *ptr)
+{
+    bcmos_byte_memblk *blk;
+    bcmos_byte_pool *pool;
+
+    BUG_ON(!ptr);
+    blk = (bcmos_byte_memblk *)((long)ptr - sizeof(bcmos_byte_memblk));
+    pool = blk->pool;
+#ifdef BCMOS_MEM_DEBUG
+    BUG_ON(pool->magic != BCMOS_BYTE_POOL_VALID);
+    BUG_ON(blk->magic != BCMOS_MEM_MAGIC_ALLOC);
+    BUG_ON(*(uint32_t *)((long)blk + blk->size - sizeof(uint32_t)) != BCMOS_MEM_MAGIC_ALLOC);
+    blk->magic = BCMOS_MEM_MAGIC_FREE;
+#endif
+    pool->allocated -= blk->size;
+    free(blk);
+}
+
+void _bcmos_backtrace(void)
+{
+    /*todo implement this*/
+}
+
+int ffsll(long long int i)
+{
+    int l = ffs(i & 0xFFFFFFFF);
+    int h = ffs((i >> 32) & 0xFFFFFFFF);
+
+    if (l)
+        return l;
+
+    if (h)
+        return h + 32;
+
+    return 0;
+}
+
+/* stub for int enable */
+void bcmos_int_enable(int irq)
+{
+}
+
+typedef struct bcmos_int_data
+{
+   int (*isr)(int irq, void *priv);
+   int irq;
+   void *priv;
+} bcmos_int_data;
+
+static void _bcmos_int_handler(long priv)
+{
+     bcmos_int_data *data = (bcmos_int_data *)priv;
+     data->isr(data->irq, data->priv);
+}
+
+int bcmos_int_connect(int irq, int cpu, int flags, int (*isr)(int irq, void *priv), const char *name, void *priv)
+{
+   bcmos_int_data *data = bcmos_calloc(sizeof(bcmos_int_data));
+   if (!data)
+      return (int)BCM_ERR_NOMEM;
+   data->isr = isr;
+   data->irq = irq;
+   data->priv = priv;
+   return pciIntConnect(INUM_TO_IVEC(irq), _bcmos_int_handler, (long)data);
+}
+
+/* Disconnect system interrupt */
+void bcmos_int_disconnect(int irq, void *priv)
+{
+    pciIntDisconnect(INUM_TO_IVEC(irq), _bcmos_int_handler);
+}
+
+/**************************************************************
+ * Check in-irq status                                        *
+ * related header file: "intLib.h"                            *
+ * param[in]   none                                           *
+ * param[out]  none                                           *
+ * return      BCMOS_TRUE  (1) - in interrupt context;        *
+ *             BCMOS_FALSE (0) - in task context;             *
+ **************************************************************/
+
+bcmos_bool is_irq_mode(void)
+{
+    return intContext();
+}
+
+// from bsp
+extern int isIntDisabled();
+/**************************************************************
+ * Check if interrupts are disabled                           *
+ * related header file: "mipsinc.h"                           *
+ * param[in]   none                                           *
+ * param[out]  none                                           *
+ * return      BCMOS_TRUE (1) -  Gloal interrupt disable      *
+               BCMOS_FALSE (0) - Gloal interrupt enable;      *
+ * comment     if BSP team can provide similar function,      *
+               we will call it;                               *
+ * Another option is share this macro used on switch product  *
+ *************************************************************/
+bcmos_bool is_irq_disabled(void)
+{
+    return isIntDisabled();
+}
+
+/**************************************************************
+ * write barrier                                              *
+ * related header file: none                                  *
+ * param[in]   none                                           *
+ * param[out]  none                                           *
+ * return none                                                *
+ * comment:use "sync" base on MIPS (GNU style)                *
+ *************************************************************/
+
+void bcmos_barrier(void)
+{
+ #if defined(HOST_CPU_IS_MIPS) || defined(HOST_CPU_IS_PPC)
+    {__asm__ __volatile__("sync");}
+ #else
+   #error HOST CPU MUST BE MIPS OR POWERPC
+ #endif
+}
+
+/**************************************************************
+ * Allocate DMA-able memory                                   *
+ * related header file:memPartLib.h                           *
+ * param[in]   device  Device id                              *
+ * param[in]   size    Block size (bytes)                     *
+ * param[out]  none                                           *
+ * returns    memory block pointer(uncached memory) or NULL   *
+ * comment:   BSP need to allocate uncached memory pool first *
+ * if BSP team can provide such function,call it directly;    *
+ * suggestion: memPartCreate()create uncached memory and      *
+ * return memory ID:uncachePoolMemPartId                      *
+ * memPartAlloc()/memPartFree():allocate/free memory via      *
+ * memory ID:uncachePoolMemPartId and size                    *
+ * if BSP can gurantee the Memory allocated by cacheDmaMalloc *
+ * cacheDmaFree() is noncached memory,we can call them directly*
+ *************************************************************/
+
+void *bcmos_dma_alloc(uint8_t device, uint32_t size)
+{
+    void * pBuffer;
+#ifdef NON_CACHED_MEMORY_CREATED_BY_CACHEDMAMALLOC
+    pBuffer = cacheDmaMalloc(size);
+    return (pBuffer);
+#else
+    pBuffer = (void *)memPartAlloc(uncachePoolMemPartId, size));
+    return (pBuffer);
+#endif
+}
+
+/**************************************************************
+ * Release DMA-able memory                                    *
+ * related header file: memPartLib.h                          *
+ * param[in]   device  Device id                              *
+ * param[in]   ptr     Block pointer                          *
+ * param[out]  none                                           *
+ * return  none                                               *
+ * comment: see above                                         *
+ *************************************************************/
+void bcmos_dma_free(uint8_t device, void *ptr)
+{
+#ifdef NON_CACHED_MEMORY_CREATED_BY_CACHEDMAMALLOC
+    cacheDmaFree((void *)(ptr));
+#else
+    memPartFree(uncachePoolMemPartId,ptr);
+#endif
+    return;
+}
+
+/**************************************************************
+ * Convert virtual address to physical address                *
+ * related header file:for MIPS CPU	archMips.h                *
+ * param[in]   va    Virtual address                          *
+ * return - physical address va is mapped to                  *
+**************************************************************/
+unsigned long bcmos_virt_to_phys(void *va)
+{
+#ifdef HOST_CPU_IS_MIPS
+  return (unsigned long)(K0_TO_PHYS(va));
+
+#else
+	/* this is an just an example,
+	if you are not working with mips make sure you define the correct mapping for your system */
+    return (unsigned long)(va);
+#endif
+}
+
+/**************************************************************
+ * Invalidate address area in data cache.                     *
+ * related header file:  cacheLib.h                           *
+ * param[in]   start   Address area start                     *
+ * param[in]   size    Address area size                      *
+ * return  none                                               *
+ **************************************************************/
+void bcmos_dcache_inv(void *start, uint32_t size)
+{
+    cacheInvalidate(DATA_CACHE,start, size);
+    return;
+}
+
+/**************************************************************
+ * Flush address area in data cache.                          *
+ * related header file:  cacheLib.h                           *
+ * param[in]   start   Address area start                     *
+ * param[in]   size    Address area size                      *
+ * return  none                                               *
+**************************************************************/
+void bcmos_dcache_flush(void *start, uint32_t size)
+{
+    cacheFlush(DATA_CACHE,start, size);
+    return;
+}
+
+/**************************************************************
+ * write value to PCI memory                                  *
+ * related header file: bcmos_common2.h                       *
+ * param[in]   address  pointer to Address                    *
+ * param[in]   value    value                                 *
+ * return  none                                               *
+ * Comment re-use BCMOS_ENDIAN_CPU_TO_LITTLE_U32 which is from*
+ * bcmos_common2.h,by this macro,can support both big endian  *
+ * host and little endian host.move PCI access functions after*
+ * bcmos_common2.h                                            *
+ **************************************************************/
+void bcm_pci_write32(volatile uint32_t *address, uint32_t value)
+{
+#ifdef HOST_PCIE_SWAP_NEEDED
+    value = BCMOS_ENDIAN_CPU_TO_LITTLE_U32(value);
+#endif
+    *address = value;
+}
+
+/**************************************************************
+ * read value to PCI memory                                   *
+ * related header file: bcmos_common2.h                       *
+ * param[in]   address  pointer to Address                    *
+ * return  value                                              *
+ * Comment see above                                          *
+**************************************************************/
+uint32_t bcm_pci_read32(const volatile uint32_t *address)
+{
+    uint32_t value;
+    value = *address;
+#ifdef HOST_PCIE_SWAP_NEEDED
+    value = BCMOS_ENDIAN_LITTLE_TO_CPU_U32(value);
+#endif
+    return value;
+
+}
+
+
diff --git a/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.h b/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.h
new file mode 100644
index 0000000..5633e28
--- /dev/null
+++ b/bcm68620_release/release/host_customized/os_abstraction/vxworks55/bcmos_system.h
@@ -0,0 +1,184 @@
+/*
+<: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.
+
+:>
+ */
+
+/*
+ * bcmos_system.h
+ * Maple System Services
+ * vxWorks 5.5 port
+ */
+
+#ifndef BCMOS_SYSTEM_H_
+#define BCMOS_SYSTEM_H_
+
+#define BCMOS_IRQ_SINGLE    0
+#define BCMOS_IRQ_SHARED    1
+
+#define inline __inline
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <time.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sockLib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* Re-define GNU typeof as ISO __typeof__ */
+#define typeof __typeof__
+
+/* Specify here which system functions are inlined */
+
+/* #define BCMOS_FASTLOCK_INLINE */
+/* #define BCMOS_SEM_WAIT_INLINE */
+/* #define BCMOS_SEM_POST_INLINE */
+/* #define BCMOS_USLEEP_INLINE */
+#define BCMOS_TRACE_PRINTF
+#define BCMOS_BYTE_POOL_ALLOC_FREE_INLINE
+/* #define BCMOS_MALLOC_FREE_INLINE */
+/* #define BCMOS_CALLOC_INLINE */
+/* if Host cpu is MIPS cpu,enable this macro */
+/* Host cpu type will be determined during compile*/
+//#define HOST_CPU_IS_MIPS
+//#define HOST_CPU_IS_PPC
+/*if the Memory allocated by cacheDmaMalloc/acheDmaFree() is non-cached memory,enable this macro*/
+#define NON_CACHED_MEMORY_CREATED_BY_CACHEDMAMALLOC
+/* Uncommentthe following line if h/w supports DMA cache coherency */
+/* #define BCMOS_DMA_CACHE_COHERENCY */
+
+static inline void bcmos_int_disable(int irq)
+{}
+
+void _bcmos_backtrace(void);
+
+#define BUG_ON(_f)      do { if (_f) { _bcmos_backtrace(); } } while (0)
+#define BUG()           BUG_ON(1)
+#define BUG_UNLESS(_f)  BUG_ON(!(_f))
+
+/** Boolean */
+#define BCMOS_BOOLEAN
+typedef enum
+{
+    BCMOS_FALSE = 0,
+    BCMOS_TRUE  = 1,
+} bcmos_bool;
+
+#include "bcmos_common.h"
+
+#define ffs(n) ffsLsb(n)
+
+/** Semaphore control block */
+struct bcmos_sem
+{
+    uint32_t s;
+};
+
+
+/** Mutex control block */
+struct bcmos_mutex
+{
+    uint32_t m;
+};
+
+/** Fast lock control block */
+struct bcmos_fastlock
+{
+    uint32_t l;
+};
+
+/** Fastlock initializer. Can be used instead of calling bcmos_fastlock_init() */
+#define BCMOS_FASTLOCK_INITIALIZER      { 0 }
+
+/** OS-specific task control block extension */
+typedef struct bcmos_sys_task
+{
+    uint32_t t;                         /**< vxWorks task ID */
+} bcmos_sys_task;
+
+
+/** System timer */
+struct bcmos_sys_timer
+{
+    uint32_t t;                         /**< VxW timer */
+    bcmos_sys_timer_handler handler;    /**< Timer handler */
+    void *data;                         /**< Parameter to be passed to the handler */
+};
+
+/** Byte memory pool control block */
+struct bcmos_byte_pool
+{
+    bcmos_byte_pool_parm parm;  /**< Pool parameters */
+    uint32_t allocated;         /**< Number of bytes allocated */
+#ifdef BCMOS_MEM_DEBUG
+    uint32_t magic;             /**< magic number */
+#define BCMOS_BYTE_POOL_VALID           (('b'<<24) | ('y' << 16) | ('p' << 8) | 'o')
+#define BCMOS_BYTE_POOL_DELETED         (('b'<<24) | ('y' << 16) | ('p' << 8) | '~')
+#endif
+};
+
+#define bcmos_sys_vprintf(fmt, args)        vprintf(fmt, args)
+
+#define EXPORT_SYMBOL(_sym)
+
+/* 2nd part of OS-independent declarations */
+#include "bcmos_common2.h"
+
+void bcm_pci_write32(volatile uint32_t *address, uint32_t value);
+uint32_t bcm_pci_read32(const volatile uint32_t *address);
+
+
+/*todo must check validity that the string is numeric, sscanf cannot detect errors,
+ * if not valid, put (*tailptr) in the first non valid char in string,
+ if valid, point tailptr in the last char in string (*tailptr=string+strlen(string))*/
+#define strtoull(string,tailptr,base)   ({\
+                                            unsigned long long int __a;\
+                                            *(tailptr)=(char*)((string)+strlen(string));\
+                                            sscanf(string, base == 10 ? "%llu" : "%llx", &__a );\
+                                            __a;\
+                                        })
+#define strtoll(string,tailptr,base)    ({\
+                                            long long int __a;\
+                                            *(tailptr)=(char*)((string)+strlen(string));\
+                                            sscanf(string,"%lld", &__a );\
+                                            __a;\
+                                        })
+
+#define snprintf(s1,n,s2,args...)      sprintf(s1, s2,## args)
+#define vsnprintf(s1,n,s2,args...)     vsprintf(s1, s2,## args)
+
+
+int ffsLsb (UINT32 i);
+int ffsll(long long int i);
+
+
+#endif /* BCMOS_SYSTEM_H_ */