BAL and Maple Release 2.2

Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_driver/utils/Makefile b/bcm68620_release/release/host_driver/utils/Makefile
new file mode 100644
index 0000000..9c905ec
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/Makefile
@@ -0,0 +1,8 @@
+# Common utilities
+#
+MOD_NAME = utils
+MOD_TYPE = lib
+ifeq ("$(OS_KERNEL)", "linux")
+    MOD_DEPS = utils_linux
+endif
+srcs = bcmolt_utils.c bcmolt_buf.c bcmolt_bit_utils.c bcmolt_conv.c bcmolt_string.c
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.c b/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.c
new file mode 100644
index 0000000..130c07e
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.c
@@ -0,0 +1,370 @@
+/*
+<: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 "math.h"
+#include "bcmolt_bit_utils.h"
+
+
+/** dynamically allocate space for an array of `nbits' bits and initalize
+ *  the bits to all be zero.
+ *
+ * \param[out]  bv      pointer to a bit_vector struct.
+ * \param[in]   nbits   number of bits to allocate.
+ * \return      FALSE if space was not available, otherwise TRUE.
+ */
+bcmos_bool bcmolt_bv_new(bit_vector *bv, const uint32_t nbits)
+{
+    uint32_t nwords = BCMOS_DIVIDE_ROUND_UP(nbits, (BITS_SZ));
+
+    bv->nbits  = nbits;
+    bv->vector = (bv_bits *)calloc(nwords, sizeof(bv_bits));
+    return (bv->vector != NULL);
+}
+
+
+/** return the value of the `offset'th bit element of the bit vector.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to test.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+bcmos_bool bcmolt_bv_get(const bit_vector *bv, const uint32_t offset)
+{
+    bcmos_bool    rv = BCMOS_FALSE;
+
+    if (offset <= bv->nbits)
+    {
+        rv = test_bits_set(bv->vector[(offset / BITS_SZ)],
+                           (1 << (offset % BITS_SZ)));
+    }
+    else
+    {
+        BCMOS_TRACE_ERR("out of range %u\n", offset);
+    }
+    return rv;
+}
+
+
+/** set or clear the bit in position `offset' of the bit vector.
+ *  bv->vector[bit_pos] is to be set (assigned to 1) if value is TRUE,
+ *  otherwise it is to be cleared (assigned to 0).
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to set or clear.
+ * \param[in]   value   boolean value. TRUE for set, BCMOS_FALSE for clear.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+void bcmolt_bv_assign(bit_vector       *bv,
+                      const uint32_t    offset,
+                      const bcmos_bool  value)
+{
+    if (offset <= bv->nbits)
+    {
+        if (value)
+        {
+            bv->vector[offset / BITS_SZ] |= (1 << (offset % BITS_SZ));
+        }
+        else
+        {
+            bv->vector[offset / BITS_SZ] &= ~(1 << (offset % BITS_SZ));
+        }
+    }
+    else
+    {
+        BCMOS_TRACE_ERR("out of range %u\n", offset);
+    }
+}
+
+
+/** toggle the bit in position `offset' of the bit vector.
+ *  i.e. if it was 1 it is 0; if it was 0 it is 1.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to toggle.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+void bcmolt_bv_toggle(bit_vector *bv, const uint32_t offset)
+{
+    if (offset <= bv->nbits)
+    {
+        bv->vector[offset / BITS_SZ] ^= (1 << (offset % BITS_SZ));
+    }
+    else
+    {
+        BCMOS_TRACE_ERR("out of range %u\n", offset);
+    }
+}
+
+
+/** copy bit vector from 'src' to 'dst'.
+ *
+ * \param[out]  dst     pointer to a bit_vector struct to copy to.
+ * \param[in]   src     pointer to a bit_vector struct to copy from.
+ * \param[in]   nbits   number of bits to copy.
+ * \return      none.
+ */
+void bcmolt_bv_copy(bit_vector        *dst, 
+                    const bit_vector  *src, 
+                    const uint32_t     nbits)
+{
+    uint32_t  i;
+    uint32_t  nwords    = nbits / BITS_SZ;
+    bv_bits   bit_remainder = nbits % BITS_SZ;
+
+    if ((nbits <= dst->nbits) && (nbits <= src->nbits))
+    {
+        for (i = 0; i < nwords; i++)
+        {
+            dst->vector[i] = src->vector[i];
+        }
+
+        if (0 != bit_remainder)
+        {
+            dst->vector[nwords] = (dst->vector[nwords] & ~((2^bit_remainder) - 1)) |
+                (src->vector[nwords] & ((2^bit_remainder) - 1));
+        }
+    }
+    else
+    {
+        BCMOS_TRACE_ERR("out of range %u\n", nbits);
+    }
+}
+
+
+/** Print bit pattern of word FORMATTED to string.
+ *
+ * \param[in]   value   value to transform to bit string.
+ * \param[in]   bitcnt  count of bits to be shown.
+ * \param[out]  outstr  pointer to a output buffer to store the string.
+ * \return      none
+ * \warning     this fn doesn't check the size of 'outstr'.
+ *              the caller should ensure 'outstr' has enough room for the
+ *              bit string, space characters and null terminator.
+ */
+void bcmolt_bit_string(const bv_bits value, const uint32_t bitcnt, char *outstr)
+{
+    uint32_t  offset;
+
+    if (bitcnt <= BITS_SZ)
+    {
+        for (offset = 0; offset < bitcnt; offset++)
+        {
+            *outstr++ = ((value >> offset) & 1) + '0';
+            if ((((offset + 1) % 4) == 0))
+            {
+                *outstr++ = ' ';
+            }
+        }
+    }
+
+    *outstr = '\0';
+}
+
+
+/** Print all bits in the bit vector.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \return      none.
+ */
+void bcmolt_bv_dump(const bit_vector *bv)
+{
+    uint32_t  idx;                        /* word idx */
+    char      outstr[BITS_SZ + 8 + 1];    /* 8 spaces + null */
+
+    for (idx = 0; idx < (bv->nbits / BITS_SZ); idx++)
+    {
+        bcmolt_bit_string(bv->vector[idx], BITS_SZ, outstr);
+        bcmos_printf("%s\n", outstr);
+    }
+
+    if (0 != (bv->nbits % BITS_SZ))
+    {
+        bcmolt_bit_string(bv->vector[idx], (bv->nbits % BITS_SZ), outstr);
+        bcmos_printf("%s\n", outstr);
+    }
+}
+
+
+/** Count the number of bits set in a long integer.
+ *
+ * \param[in]   num     integer value.
+ * \return      number of bits set.
+ */
+uint32_t bcmolt_bit_count(uint32_t num)
+{
+    num = ((num & 0xAAAAAAAAL) >>  1) + (num & 0x55555555L);
+    num = ((num & 0xCCCCCCCCL) >>  2) + (num & 0x33333333L);
+    num = ((num & 0xF0F0F0F0L) >>  4) + (num & 0x0F0F0F0FL);
+    num = ((num & 0xFF00FF00L) >>  8) + (num & 0x00FF00FFL);
+    num = ((num & 0xFFFF0000L) >> 16) + (num & 0x0000FFFFL);
+    return num;
+}
+
+
+/** Count the number of bits set in the whole bit vector.
+ *
+ * \param[in]   bv      pointer to the bit vector struct.
+ * \return      number of bits set.
+ */
+uint32_t bcmolt_bv_bit_count(const bit_vector *bv)
+{
+    uint32_t  nwords = BCMOS_DIVIDE_ROUND_UP(bv->nbits, (BITS_SZ));
+    uint32_t  cnt = 0;
+
+    while (0 != nwords--)
+    {
+        cnt += bcmolt_bit_count(bv->vector[nwords]);
+    }
+
+    return cnt;
+}
+
+
+
+/** Copy bit range from a 32-bit word array to an arbitrary bit position of
+ *  the destination 32-bit word array.
+ *
+ * \param[in]   dst             destination buffer
+ * \param[in]   dst_bytes       destination buffer size in bytes
+ * \param[in]   dst_bit_pos     least bit position to dest
+ * \param[in]   src             source buffer
+ * \param[in]   n_bits          how many bits to copy from source
+ * \note        src is in little endian and dst is in big endian.
+ */
+void bcmos_bit_range_set(uint32_t *dst, uint32_t dst_bytes, uint16_t dst_bit_pos,
+                         uint32_t *src, uint16_t n_bits)
+{
+    uint16_t    bp = dst_bit_pos;
+    uint16_t    len;
+    uint32_t    wp;
+    uint32_t    mask;
+    uint32_t    src_idx;
+    uint32_t    dst_idx;
+
+    wp = bp / 32;
+    bp = bp & (32 - 1);
+    src_idx = 0;
+
+    for (len = n_bits; len > 0; len -= 32)
+    {
+        if (bp != 0)
+        {
+            mask = (len < 32) ? (1 << len) - 1 : 0xFFFFFFFF;
+            dst_idx = wp;
+            dst[dst_idx] &= ~(mask << bp);
+            dst[dst_idx] |= src[src_idx] << bp;
+            wp++;
+            if (len > (32 - bp))
+            {
+                dst_idx = wp;
+                dst[dst_idx] &= ~(mask >> (32 - bp));
+                dst[dst_idx] |= src[src_idx] >> (32 - bp) & ((1 << bp) - 1);
+            }
+        }
+        else
+        {
+            dst_idx = wp;
+            if (len < 32)
+            {
+                mask = (1 << len) - 1;
+                dst[dst_idx] &= ~mask;
+                dst[dst_idx] |= src[src_idx] << bp;
+            }
+            else
+            {
+                dst[dst_idx] = src[src_idx];
+            }
+            wp++;
+        }
+        src_idx++;
+    }
+}
+
+
+/** Get bit range at an arbitrary bit position of a 32-bit word array
+ * 
+ * \param[in]   src             source buffer (e.g. dataport)
+ * \param[in]   src_bytes       source buffer size in bytes
+ * \param[in]   src_bit_pos     least bit position of the source
+ * \param[in]   dst             destination buffer to store the bit value
+ * \param[in]   n_bits          how many bits to copy from srouce
+ * \note        src is in big endian and dst is in little endian.
+ */
+void bcmos_bit_range_get(const uint32_t *src, uint32_t src_bytes,
+                         uint16_t src_bit_pos, uint32_t *dst, uint16_t n_bits)
+{
+    uint16_t    bp = src_bit_pos;   /* for readability */
+    uint16_t    len = n_bits;
+    uint32_t    wp;
+    uint32_t    src_idx;
+    uint32_t    dst_idx;
+
+    if (n_bits == 1)
+    {
+        wp = bp / 32;
+        bp = bp & (32 - 1);
+        src_idx = BCMOS_DIVIDE_ROUND_UP(src_bytes, 4) - 1 - wp;
+        dst[0] = ((src[src_idx] & (1 << bp)) != 0) ? 1: 0;
+        return;
+    }
+
+    wp = bp / 32;
+    bp = bp & (32 - 1);
+    dst_idx = 0;
+
+    for (; len > 0; len -= 32)
+    {
+        if (bp != 0)
+        {
+            src_idx = BCMOS_DIVIDE_ROUND_UP(src_bytes, 4) - 1 - wp;
+            dst[dst_idx] = src[src_idx] >> bp & ((1 << (32 - bp)) - 1);
+            wp++;
+            if (len > (32 - bp))
+            {
+                src_idx = BCMOS_DIVIDE_ROUND_UP(src_bytes, 4) - 1 - wp;
+                dst[dst_idx] |= src[src_idx] << (32 - bp);
+            }
+        }
+        else
+        {
+            src_idx = BCMOS_DIVIDE_ROUND_UP(src_bytes, 4) - 1 - wp;
+            dst[dst_idx] = src[src_idx];
+            wp++;
+        }
+
+        if (len < 32)
+        {
+            dst[dst_idx] &= ((1 << len) - 1);
+        }
+        dst_idx++;
+    }
+}
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.h b/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.h
new file mode 100644
index 0000000..9971292
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_bit_utils.h
@@ -0,0 +1,242 @@
+/*
+<: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.
+
+:>
+ */
+
+/**
+ * bcmolt_bit_utils.h
+ *  Created on: 03/10/2014
+ *      Author: cpark1
+ *
+ * This bit vector implementation is used for the EPON encryption.
+ * There is a certain hardware restriction that the global encryption mode
+ * can not be changed when a link encryption is configured for a different
+ * encryption mode.
+ * Likewise, the link encryption mode can not be changed if the global
+ * encryption mode is set to other mode.
+ * Therefore, when the host tries to change any of them, the OLT needs to
+ * check either the global encryption mode or the link encryption mode
+ * before applying the change.
+ * In the old implementation (like Pioneer), the firmware iterates through
+ * every link records of each PON port and check the encryption mode of each.
+ * This is very inefficient and time consuming.
+ * The host may want to know how many links are enabled for the encryption,
+ * or which link is enabled, etc.
+ * I thought that a bit vector implementation is best satisfies.
+ * Also, this implementation exactly reflects the IC implementation, so we
+ * can use it to mirror the hardware status.
+ *
+ */
+
+#ifndef BCMOLT_BIT_UTILS_H
+#define BCMOLT_BIT_UTILS_H
+
+
+#include "bcmos_system.h"
+
+
+/* the current (draft) design of the ASIC uses 32-bit bitmap data port */
+typedef uint32_t    bv_bits;
+
+typedef struct
+{
+    uint32_t  nbits;
+    bv_bits  *vector;
+} bit_vector;
+
+
+#define BITS_SZ     (sizeof(bv_bits) * CHAR_BIT)
+
+#define BITS_SET(val, mask) (((val) & (mask)) == (mask))
+
+/** Test if all given bits are set in the given data word
+ * \param[in]   word    Given data word to test
+ * \param[in]   mask    Test mask
+ * \return      TRUE if all the bits in the bitMask are set
+ */
+static inline bcmos_bool test_bits_set(uint32_t word, uint32_t mask)
+{
+    return ((word & mask) == mask);
+}
+
+/** Test if all given bits are clear in the given data word
+ * \param       word    Given word to test
+ * \param       mask Test mask
+ * \return      TRUE if all the bits given by bitMask are clear
+ */
+static inline bcmos_bool test_bits_clear(uint32_t word, uint32_t mask)
+{
+    return (word & mask) == 0;
+}
+
+/** Test whether any of the given bits are set in a value
+ * \param[in]   val     The value to test
+ * \param[in]   bits    The bits to test for
+ * \return      TRUE if any of the bits are set in the value, FALSE otherwise
+ */
+static inline bcmos_bool test_bits_any(uint32_t val, uint32_t bits)
+{
+    return (val & bits) != 0;
+}
+
+
+/** return true if only one bit is set for a given integer.
+ */
+static inline bcmos_bool is_one_bit_set(uint32_t number)
+{
+    return (number & (number - 1)) == 0;
+}
+
+
+
+/** dynamically allocate space for an array of `nbits' bits and initalize
+ *  the bits to all be zero.
+ *
+ * \param[out]  bv      pointer to a bit_vector struct.
+ * \param[in]   nbits   number of bits to allocate.
+ * \return      FALSE if space was not available, otherwise TRUE.
+ */
+bcmos_bool bcmolt_bv_new(bit_vector *bv, const uint32_t nbits);
+
+
+/** return the value of the `offset'th bit element of the bit vector.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to test.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+bcmos_bool bcmolt_bv_get(const bit_vector *bv, const uint32_t offset);
+
+
+/** set or clear the bit in position `offset' of the bit vector.
+ *  bv->vector[bit_pos] is to be set (assigned to 1) if value is TRUE,
+ *  otherwise it is to be cleared (assigned to 0).
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to set or clear.
+ * \param[in]   value   boolean value. TRUE for set, FALSE for clear.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+void bcmolt_bv_assign(bit_vector *bv, const uint32_t offset, const bcmos_bool value);
+
+
+/** set or clear 'nbits' bits of given bit vector.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   nbits   number of bits to set or clear.
+ * \param[in]   value   boolean value. TRUE for set, FALSE for clear.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+void bv_assign_nbits(bit_vector *bv, const uint32_t nbits,
+                     const bcmos_bool value);
+
+
+/** toggle the bit in position `offset' of the bit vector.
+ *  i.e. if it was 1 it is 0; if it was 0 it is 1.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \param[in]   offset  offset of bit to toggle.
+ * \return      FALSE if the bit offset is out of range, otherwise TRUE.
+ */
+void bcmolt_bv_toggle(bit_vector *bv, const uint32_t offset);
+
+
+/** copy bit vector from 'src' to 'dst'.
+ *
+ * \param[out]  dst     pointer to a bit_vector struct to copy to.
+ * \param[in]   src     pointer to a bit_vector struct to copy from.
+ * \param[in]   nbits   number of bits to copy.
+ * \return      none.
+ */
+void bcmolt_bv_copy(bit_vector *dst, const bit_vector *src, const uint32_t nbits);
+
+
+/** Print bit pattern of word FORMATTED to string.
+ *
+ * \param[in]   value   value to transform to bit string.
+ * \param[in]   bitcnt  count of bits to be shown.
+ * \param[out]  outstr  pointer to a output buffer to store the string.
+ * \return      none
+ * \warning     this fn doesn't check the size of 'outstr'.
+ *              the caller should ensure 'outstr' has enough room for the
+ *              bit string, space characters and null terminator.
+ */
+void bcmolt_bit_string(const bv_bits value, const uint32_t bitcnt, char *outstr);
+
+
+/** Print all bits in the bit vector.
+ *
+ * \param[in]   bv      pointer to a bit_vector struct.
+ * \return      none.
+ */
+void bcmolt_bv_dump(const bit_vector *bv);
+
+
+/** Count the number of bits set in a long integer.
+ *
+ * \param[in]   num     integer value.
+ * \return      number of bits set.
+ */
+uint32_t bcmolt_bit_count(uint32_t num);
+
+
+/** Count the number of bits set in the whole bit vector.
+ *
+ * \param[in]   bv      pointer to the bit vector struct.
+ * \return      number of bits set.
+ */
+uint32_t bcmolt_bv_bit_count(const bit_vector *bv);
+
+
+/** Copy bit range from a 32-bit word array to an arbitrary bit position of
+ *  the destination 32-bit word array.
+ *
+ * \param[in]   dst             destination buffer
+ * \param[in]   dst_bytes       destination buffer size in bytes
+ * \param[in]   dst_bit_pos     least bit position to dest
+ * \param[in]   src             source buffer
+ * \param[in]   src_bits        many bits to copy from source
+ * \note        src is in little endian and dst is in big endian.
+ */
+void bcmos_bit_range_set(uint32_t *dst, uint32_t dst_bytes, uint16_t dst_bit_pos,
+                         uint32_t *src, uint16_t n_bits);
+
+/** Get bit range at an arbitrary bit position of a 32-bit word array
+ *
+ * \param[in]   src             source buffer (e.g. dataport)
+ * \param[in]   src_bytes       source buffer size in bytes
+ * \param[in]   src_bit_pos     least bit position of the source
+ * \param[in]   dst             destination buffer to store the bit value
+ * \param[in]   n_bits          how many bits to copy from srouce
+ * \note        src is in big endian and dst is in little endian.
+ */
+void bcmos_bit_range_get(const uint32_t *src, uint32_t src_bytes,
+                         uint16_t src_bit_pos, uint32_t *dst, uint16_t n_bits);
+
+
+#endif  /* BCMOLT_BIT_UTILS_H */
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_buf.c b/bcm68620_release/release/host_driver/utils/bcmolt_buf.c
new file mode 100644
index 0000000..cb57fe9
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_buf.c
@@ -0,0 +1,247 @@
+/*
+<: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 "bcmolt_buf.h"
+#include "bcmos_system.h"
+
+/** Initalize a bcmolt_buf stream
+ *
+ * \param buf 
+ * \param size 
+ * \param start
+ * \param endian Endianness of numbers in the resulting stream
+ */
+void bcmolt_buf_init(bcmolt_buf *buf, uint32_t size, uint8_t *start, bcmos_endian endian)
+{
+    buf->len = size;
+    buf->curr = start;
+    buf->start = start;
+    buf->free = NULL;
+    buf->bh = NULL;
+    /* Currently, we only support reading/writing numbers in a single endianness. */
+    BUG_ON(endian != BCMOLT_BUF_ENDIAN_FIXED);
+}
+
+/** Allocate data buffer and initialize bcmolt_buf stream
+ *
+ * \param buf
+ * \param size
+ * \param endian Endianness of numbers in the resulting stream
+ * \return BCM_ERR_OK or BCM_ERR_NOMEM
+ */
+bcmos_errno bcmolt_buf_alloc(bcmolt_buf *buf, uint32_t size, bcmos_endian endian)
+{
+    buf->start = bcmos_alloc(size);
+    if (buf->start == NULL)
+    {
+        return BCM_ERR_NOMEM;
+    }
+    bcmolt_buf_init(buf, size, buf->start, endian);
+    return BCM_ERR_OK;
+}
+
+/** Release data buffer pointed by bcmolt_buf stream
+ * \param[in,out] buf
+ */
+void bcmolt_buf_free(bcmolt_buf *buf)
+{
+    if (buf->start != NULL)
+    {
+        if (buf->free)
+        {
+            buf->free(buf->bh);
+            buf->free = NULL;
+            buf->bh = NULL;
+        }
+        else
+        {
+            bcmos_free(buf->start);
+        }
+        buf->start = NULL;
+    }
+    buf->len = 0;
+    buf->curr = NULL;
+}
+
+/** Read from the buffer
+ *
+ * \param buf    bcmolt_buf instance
+ * \param to     Where to read to
+ * \param len    Number of bytes to copy
+ *
+ * \return       BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_read(bcmolt_buf *buf, void *to, size_t len)
+{
+    if ((buf->start + buf->len) >= (buf->curr + len))
+    {
+        memcpy(to, buf->curr, len);
+        buf->curr += len;
+        return BCMOS_TRUE;
+    }
+
+    return BCMOS_FALSE;
+}
+
+/** Transfer bytes from one buf to another
+ *
+ * \param *from    Source buffer
+ * \param *to      Destination buffer
+ * \param bytes    Number of bytes to transfer
+ * \return         BCMOS_TRUE if successfully transferred
+ */
+bcmos_bool bcmolt_buf_transfer_bytes(bcmolt_buf *from, bcmolt_buf *to, uint32_t bytes)
+{
+    uint8_t tmp[256];
+    uint32_t toRead;
+    while (bytes != 0)
+    {
+        toRead = bytes > sizeof(tmp) ? sizeof(tmp) : bytes;
+        if (!bcmolt_buf_read(from, tmp, toRead) || !bcmolt_buf_write(to, tmp, toRead))
+        {
+            return BCMOS_FALSE;
+        }
+
+        bytes -= toRead;
+    }
+
+    return BCMOS_TRUE;
+}
+
+/** Write to the buffer
+ *
+ * \param buf    bcmolt_buf instance
+ * \param from   Source, to copy from
+ * \param len    Number of bytes to copy
+ *
+ * \return       BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_write(bcmolt_buf *buf, const void *from, size_t len)
+{
+    if ((buf->start + buf->len) >= (buf->curr + len))
+    {
+        memcpy(buf->curr, from, len);
+        buf->curr += len;
+        return BCMOS_TRUE;
+    }
+    else
+    {
+        return BCMOS_FALSE;
+    }
+}
+
+/** Move the current pointer to a given position in the buffer
+ *
+ * \param pos    Byte position in the buffer to move the current pointer to
+ *
+ * \param *buf   Input buffer
+ * \return       BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_set_pos(bcmolt_buf *buf, uint32_t pos)
+{
+    if (pos <= buf->len)
+    {
+        buf->curr = buf->start + pos;
+        return BCMOS_TRUE;
+    }
+
+    return BCMOS_FALSE;
+}
+
+/** Move the current pointer ahead by given number of bytes
+ *
+ * \param buf    bcmolt_buf instance
+ * \param len    Number of bytes to skip
+ *
+ * \return       BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_skip(bcmolt_buf *buf, uint32_t len)
+{
+    if ((buf->start + buf->len) >= (buf->curr + len))
+    {
+        buf->curr += len;
+        return BCMOS_TRUE;
+    }
+
+    return BCMOS_FALSE;
+}
+
+/** Move the current pointer back by given number of bytes
+ *
+ * \param buf    bcmolt_buf instance
+ * \param len    Number of bytes to go back
+ *
+ * \return       BCMOS_FALSE if len takes us past the start of buffer
+ */
+bcmos_bool bcmolt_buf_rewind(bcmolt_buf *buf, uint32_t len)
+{
+    if (buf->curr >= (buf->start + len))
+    {
+        buf->curr -= len;
+        return BCMOS_TRUE;
+    }
+
+    return BCMOS_FALSE;
+}
+
+/** Reads a boolean from a buffer
+ *
+ * \param *buf
+ * \param *val
+ */
+bcmos_bool bcmolt_buf_read_bool(bcmolt_buf *buf, bcmos_bool *val)
+{
+    /* this function isn't inlined like the rest because it's too complex to inline cleanly */
+    uint8_t tmp;
+    if (bcmolt_buf_read_u8(buf, &tmp))
+    {
+        *val = (tmp != 0);
+        return BCMOS_TRUE;
+    }
+    else
+    {
+        return BCMOS_FALSE;
+    }
+}
+
+
+#ifdef __KERNEL__
+EXPORT_SYMBOL(bcmolt_buf_init);
+EXPORT_SYMBOL(bcmolt_buf_alloc);
+EXPORT_SYMBOL(bcmolt_buf_free);
+EXPORT_SYMBOL(bcmolt_buf_read);
+EXPORT_SYMBOL(bcmolt_buf_transfer_bytes);
+EXPORT_SYMBOL(bcmolt_buf_write);
+EXPORT_SYMBOL(bcmolt_buf_set_pos);
+EXPORT_SYMBOL(bcmolt_buf_skip);
+EXPORT_SYMBOL(bcmolt_buf_rewind);
+EXPORT_SYMBOL(bcmolt_buf_read_bool);
+
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_buf.h b/bcm68620_release/release/host_driver/utils/bcmolt_buf.h
new file mode 100644
index 0000000..206337a
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_buf.h
@@ -0,0 +1,733 @@
+/*
+<: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 BCMOLT_BUF_H_
+#define BCMOLT_BUF_H_
+
+#include "bcmos_system.h"
+
+/** Generic memory stream object */
+typedef struct bcmolt_buf bcmolt_buf;
+
+struct bcmolt_buf
+{
+    uint8_t *start;  /**< Pointer to the start of the buffer */
+    uint8_t *curr;   /**< Pointer to the current position in the buffer */
+    uint32_t len;    /**< Total Length of buffer */
+    /* The following 2 fields enable foreign buffer encapsulation */
+    void (*free)(void *bh);  /**< Foreign buffer release callback */
+    void *bh;        /**< Foreign buffer handle */
+};
+
+/* Serialization buffer endianness */
+#define BCMOLT_BUF_ENDIAN_FIXED BCMOS_ENDIAN_BIG
+
+#if BCMOLT_BUF_ENDIAN_FIXED == BCMOS_ENDIAN_BIG
+    #define BCMOLT_BUF_ENDIAN_BUF_TO_CPU(size, n) BCMOS_ENDIAN_BIG_TO_CPU_##size(n)
+    #define BCMOLT_BUF_ENDIAN_CPU_TO_BUF(size, n) BCMOS_ENDIAN_CPU_TO_BIG_##size(n)
+#else
+    #define BCMOLT_BUF_ENDIAN_BUF_TO_CPU(size, n) BCMOS_ENDIAN_LITTLE_TO_CPU_##size(n)
+    #define BCMOLT_BUF_ENDIAN_CPU_TO_BUF(size, n) BCMOS_ENDIAN_CPU_TO_LITTLE_##size(n)
+#endif
+
+/** Initalize a bcmolt_buf stream
+ *
+ * \param buf
+ * \param size
+ * \param start
+ * \param endian Endianness of numbers in the resulting stream.
+ *               This parameter is only for sanity check. Buffer endianness is
+ *               set at compile time. Application MUST NOT rely on default buffer endianness
+ *               being Big Endian.
+ *               If Big Endian buffer is required, application must use
+ *               access functions with "_be" designator (bcmolt_buf_read_u16_be(), etc.)
+ */
+void bcmolt_buf_init(bcmolt_buf *buf, uint32_t size, uint8_t *start, bcmos_endian endian);
+
+/** Allocate data buffer and initialize bcmolt_buf stream
+ *
+ * \param buf
+ * \param size
+ * \param endian Endianness of numbers in the resulting stream.
+ *               See explanation in bcmolt_buf_alloc()
+ * \return BCM_ERR_OK or BCM_ERR_NOMEM
+ */
+bcmos_errno bcmolt_buf_alloc(bcmolt_buf *buf, uint32_t size, bcmos_endian endian);
+
+/** Release data buffer pointed by bcmolt_buf stream
+ * \param[in,out] buf
+ */
+void bcmolt_buf_free(bcmolt_buf *buf);
+
+/** Read from the buffer
+ *
+ * \param buf    bcmolt_buf instance
+ * \param to     Where to read to
+ * \param len    Number of bytes to copy
+ *
+ * \return       BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_read(bcmolt_buf *buf, void *to, size_t len);
+
+/** Transfer bytes from one buf to another
+ *
+ * \param *from    Source buffer
+ * \param *to      Destination buffer
+ * \param bytes    Number of bytes to transfer
+ * \return         BCMOS_TRUE if successfully transferred
+ */
+bcmos_bool bcmolt_buf_transfer_bytes(bcmolt_buf *from, bcmolt_buf *to, uint32_t bytes);
+
+/** Write to the buffer
+ *
+ * \param buf    bcmolt_buf instance
+ * \param from   Source, to copy from
+ * \param len    Number of bytes to copy
+ *
+ * \return       BCMOS_TRUE if successfully copied
+ */
+bcmos_bool bcmolt_buf_write(bcmolt_buf *buf, const void *from, size_t len);
+
+/** Move the current pointer to a given position in the buffer
+ *
+ * \param pos    Byte position in the buffer to move the current pointer to
+ *
+ * \param *buf   Input buffer
+ * \return       BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_set_pos(bcmolt_buf *buf, uint32_t pos);
+
+/** Move the current pointer ahead by given number of bytes
+ *
+ * \param buf    bcmolt_buf instance
+ * \param len    Number of bytes to skip
+ *
+ * \return       BCMOS_FALSE if len takes us past the end of buffer
+ */
+bcmos_bool bcmolt_buf_skip(bcmolt_buf *buf, uint32_t len);
+
+/** Move the current pointer back by given number of bytes
+ *
+ * \param buf    bcmolt_buf instance
+ * \param len    Number of bytes to go back
+ *
+ * \return       BCMOS_FALSE if len takes us past the start of buffer
+ */
+bcmos_bool bcmolt_buf_rewind(bcmolt_buf *buf, uint32_t len);
+
+/** Get the current buffer pointer
+ *
+ * \param buf   bcmolt_buf instance
+ *
+ * \return      the current buffer pointer
+ */
+static inline uint8_t *bcmolt_buf_snap_get(const bcmolt_buf *buf)
+{
+    return buf->curr;
+}
+
+/** Move the current pointer to a snapped location
+ *
+ * \param buf   bcmolt_buf instance
+ * \param snap  snapped location
+ */
+static inline void bcmolt_buf_snap_restore(bcmolt_buf *buf, uint8_t *snap)
+{
+    buf->curr = snap;
+}
+
+/** Get the length of unprocessed bytes in given stream
+ *
+ * \param buf    Input buffer
+ *
+ * \return       The number of remaining bytes in the buffer
+ */
+static inline uint32_t bcmolt_buf_get_remaining_size(const bcmolt_buf *buf)
+{
+    return (uint32_t)((buf->start + buf->len) - buf->curr);
+}
+
+/** Get amount of buf that has been read or written so far
+ *
+ * \param buf     Input buffer
+ * \return        Amount of buffer used
+ */
+static inline uint32_t bcmolt_buf_get_used(const bcmolt_buf *buf)
+{
+    return (uint32_t)(buf->curr - buf->start);
+}
+
+/** Reads a uint8_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint8_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u8(bcmolt_buf *buf, uint8_t *val)
+{
+    return bcmolt_buf_read(buf, val, sizeof(*val));
+}
+
+/** Writes a uint8_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint8_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u8(bcmolt_buf *buf, uint8_t val)
+{
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Reads a boolean from a buffer
+ *
+ * \param *buf
+ * \param *val
+ */
+bcmos_bool bcmolt_buf_read_bool(bcmolt_buf *buf, bcmos_bool *val);
+
+/** Writes a bcmos_bool to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint8_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_bool(bcmolt_buf *buf, bcmos_bool val)
+{
+    return bcmolt_buf_write_u8(buf, val ? 1 : 0);
+}
+
+/** Reads a int8_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int8_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s8(bcmolt_buf *buf, int8_t *val)
+{
+    return bcmolt_buf_read_u8(buf, (uint8_t *)val);
+}
+
+/** Writes a int8_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int8_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s8(bcmolt_buf *buf, int8_t val)
+{
+    return bcmolt_buf_write_u8(buf, (uint8_t)val);
+}
+
+/** Reads a uint16_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint16_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u16(bcmolt_buf *buf, uint16_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U16, *val);
+    return res;
+}
+
+/** Reads a uint16_t from a Big Endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint16_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u16_be(bcmolt_buf *buf, uint16_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOS_ENDIAN_BIG_TO_CPU_U16(*val);
+    return res;
+}
+
+/** Writes a uint16_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint16_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u16(bcmolt_buf *buf, uint16_t val)
+{
+    val = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U16, val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Writes a uint16_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint16_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u16_be(bcmolt_buf *buf, uint16_t val)
+{
+    val = BCMOS_ENDIAN_CPU_TO_BIG_U16(val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Reads a int16_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int16_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s16(bcmolt_buf *buf, int16_t *val)
+{
+    return bcmolt_buf_read_u16(buf, (uint16_t *)val);
+}
+
+/** Reads a int16_t from a Big Endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int16_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s16_be(bcmolt_buf *buf, int16_t *val)
+{
+    return bcmolt_buf_read_u16_be(buf, (uint16_t *)val);
+}
+
+/** Writes int16_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int16_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s16(bcmolt_buf *buf, int16_t val)
+{
+    return bcmolt_buf_write_u16(buf, (uint16_t)val);
+}
+
+/** Writes int16_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int16_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s16_be(bcmolt_buf *buf, int16_t val)
+{
+    return bcmolt_buf_write_u16_be(buf, (uint16_t)val);
+}
+
+/** Reads a bcmos_u24 from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val bcmos_u24 to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u24(bcmolt_buf *buf, uint24_t *val)
+{
+    return bcmolt_buf_read_u8(buf, &(val->low_hi.hi)) &&
+           bcmolt_buf_read_u8(buf, &(val->low_hi.mid)) &&
+           bcmolt_buf_read_u8(buf, &(val->low_hi.low));
+}
+
+/** Writes a bcmos_u24 to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    bcmos_u24 to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u24(bcmolt_buf *buf, uint24_t val)
+{
+    return bcmolt_buf_write_u8(buf, val.low_hi.hi) &&
+           bcmolt_buf_write_u8(buf, val.low_hi.mid) &&
+           bcmolt_buf_write_u8(buf, val.low_hi.low);
+}
+
+/** Reads a uint32_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint32_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u32(bcmolt_buf *buf, uint32_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, *val);
+    return res;
+}
+
+/** Reads a uint32_t from a Big Endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint32_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u32_be(bcmolt_buf *buf, uint32_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOS_ENDIAN_BIG_TO_CPU_U32(*val);
+    return res;
+}
+
+/** Writes a uint32_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint32_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u32(bcmolt_buf *buf, uint32_t val)
+{
+    val = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Writes a uint32_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint32_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u32_be(bcmolt_buf *buf, uint32_t val)
+{
+    val = BCMOS_ENDIAN_CPU_TO_BIG_U32(val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Reads a int32_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int32_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s32(bcmolt_buf *buf, int32_t *val)
+{
+    return bcmolt_buf_read_u32(buf, (uint32_t *)val);
+}
+
+/** Reads a int32_t from a big endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int32_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s32_be(bcmolt_buf *buf, int32_t *val)
+{
+    return bcmolt_buf_read_u32_be(buf, (uint32_t *)val);
+}
+
+/** Writes a int32_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int32_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s32(bcmolt_buf *buf, int32_t val)
+{
+    return bcmolt_buf_write_u32(buf, (uint32_t)val);
+}
+
+/** Writes a int32_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int32_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s32_be(bcmolt_buf *buf, int32_t val)
+{
+    return bcmolt_buf_write_u32_be(buf, (uint32_t)val);
+}
+
+/** Reads a uint64_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint64_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u64(bcmolt_buf *buf, uint64_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U64, *val);
+    return res;
+}
+
+/** Reads a uint64_t from a Big Endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val uint64_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_u64_be(bcmolt_buf *buf, uint64_t *val)
+{
+    bcmos_bool res = bcmolt_buf_read(buf, val, sizeof(*val));
+    *val = BCMOS_ENDIAN_BIG_TO_CPU_U64(*val);
+    return res;
+}
+
+/** Writes a uint64_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint64_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u64(bcmolt_buf *buf, uint64_t val)
+{
+    val = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U64, val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Writes a uint64_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    uint64_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_u64_be(bcmolt_buf *buf, uint64_t val)
+{
+    val = BCMOS_ENDIAN_CPU_TO_BIG_U64(val);
+    return bcmolt_buf_write(buf, &val, sizeof(val));
+}
+
+/** Reads a int64_t from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int64_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s64(bcmolt_buf *buf, int64_t *val)
+{
+    return bcmolt_buf_read_u64(buf, (uint64_t *)val);
+}
+
+/** Reads a int64_t from a Big Endian buffer
+ *
+ * \param buf Buffer to read from
+ * \param val int64_t to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_s64_be(bcmolt_buf *buf, int64_t *val)
+{
+    return bcmolt_buf_read_u64_be(buf, (uint64_t *)val);
+}
+
+/** Writes a int64_t to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int64_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s64(bcmolt_buf *buf, int64_t val)
+{
+    return bcmolt_buf_write_u64(buf, (uint64_t)val);
+}
+
+/** Writes a int64_t to a Big Endian buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    int64_t to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_s64_be(bcmolt_buf *buf, int64_t val)
+{
+    return bcmolt_buf_write_u64_be(buf, (uint64_t)val);
+}
+
+/** Reads a float from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val float to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_float(bcmolt_buf *buf, float *val)
+{
+    return bcmolt_buf_read_u32(buf, (uint32_t *)val);
+}
+
+/** Writes a float to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    float to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_float(bcmolt_buf *buf, float val)
+{
+    uint32_t *num = (uint32_t *)&val;
+    return bcmolt_buf_write_u32(buf, *num);
+}
+
+/** Reads a double from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val double to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_double(bcmolt_buf *buf, double *val)
+{
+    return bcmolt_buf_read_u64(buf, (uint64_t *)val);
+}
+
+/** Writes a double to a buffer
+ *
+ * \param buf    Buffer to write to
+ * \param val    double to write
+ *
+ * \return       BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_double(bcmolt_buf *buf, double val)
+{
+    uint64_t *num = (uint64_t *)&val;
+    return bcmolt_buf_write_u64(buf, *num);
+}
+
+/** Reads a bcmos_vlan_tag from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val bcmos_vlan_tag to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_vlan_tag(bcmolt_buf *buf, bcmos_vlan_tag *val)
+{
+    return bcmolt_buf_read_u16(buf, (uint16_t *)val);
+}
+
+/** Writes a bcmos_vlan_tag to a buffer
+ *
+ * \param buf Buffer to write to
+ * \param val bcmos_vlan_tag to write
+ *
+ * \return BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_vlan_tag(bcmolt_buf *buf, bcmos_vlan_tag val)
+{
+    return bcmolt_buf_write_u16(buf, (uint16_t)val);
+}
+
+/** Reads a bcmos_mac_address from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val bcmos_mac_address to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_mac_address(bcmolt_buf *buf, bcmos_mac_address *val)
+{
+    return bcmolt_buf_read(buf, val, sizeof(bcmos_mac_address));
+}
+
+/** Writes a bcmos_mac_address to a buffer
+ *
+ * \param buf Buffer to write to
+ * \param val bcmos_mac_address to write
+ *
+ * \return BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_mac_address(bcmolt_buf *buf, bcmos_mac_address val)
+{
+    return bcmolt_buf_write(buf, &val, sizeof(bcmos_mac_address));
+}
+
+/** Reads a bcmos_ipv4_address from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val bcmos_ipv4_address to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_ipv4_address(bcmolt_buf *buf, bcmos_ipv4_address *val)
+{
+    return bcmolt_buf_read(buf, val->u8, sizeof(bcmos_ipv4_address));
+}
+
+/** Writes a bcmos_ipv4_address to a buffer
+ *
+ * \param buf Buffer to write to
+ * \param val bcmos_ipv4_address to write
+ *
+ * \return BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_ipv4_address(bcmolt_buf *buf, bcmos_ipv4_address val)
+{
+    return bcmolt_buf_write(buf, val.u8, sizeof(bcmos_ipv4_address));
+}
+
+/** Reads a bcmos_ipv6_address from a buffer
+ *
+ * \param buf Buffer to read from
+ * \param val bcmos_ipv6_address to read
+ *
+ * \return BCMOS_TRUE if read successful
+ */
+static inline bcmos_bool bcmolt_buf_read_ipv6_address(bcmolt_buf *buf, bcmos_ipv6_address *val)
+{
+    return bcmolt_buf_read(buf, *val, sizeof(bcmos_ipv6_address));
+}
+
+/** Writes a bcmos_ipv6_address to a buffer
+ *
+ * \param buf Buffer to write to
+ * \param val bcmos_ipv6_address to write
+ *
+ * \return BCMOS_TRUE if write successful
+ */
+static inline bcmos_bool bcmolt_buf_write_ipv6_address(bcmolt_buf *buf, bcmos_ipv6_address val)
+{
+    return bcmolt_buf_write(buf, val, sizeof(bcmos_ipv6_address));
+}
+
+#endif /* BCMOLT_BUF_H_ */
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_conv.c b/bcm68620_release/release/host_driver/utils/bcmolt_conv.c
new file mode 100644
index 0000000..7472c21
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_conv.c
@@ -0,0 +1,59 @@
+/*
+<: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 <bcmolt_utils.h>
+#include "bcmolt_conv.h"
+
+char *bcmolt_strftime(char *time_str, time_t t, const char *timezone_str)
+{
+    struct tm ts;
+    int32_t tz_hour;
+    uint32_t tz_min;
+    
+    ts = *localtime(&t);
+    if (timezone_str && *timezone_str)
+    {
+        if (sscanf(timezone_str, "%03d:%02u", &tz_hour, &tz_min) < 2)
+        {
+            tz_hour = 0;
+            tz_min = 0;
+        }
+        else
+        {
+            ts.tm_hour += tz_hour;
+            ts.tm_min += tz_min;
+        }
+    }
+
+    strftime(time_str, BCMOLT_TIME_STR_MAX_LEN, "%a %Y-%m-%d %H:%M:%S", &ts);
+
+    return time_str;
+}
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_conv.h b/bcm68620_release/release/host_driver/utils/bcmolt_conv.h
new file mode 100644
index 0000000..50c8a0b
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_conv.h
@@ -0,0 +1,186 @@
+/*
+<: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 _BCMOLT_CONV_H_
+#define _BCMOLT_CONV_H_
+
+#ifndef CFE_BUILD
+#include <bcmolt_utils.h>
+#endif
+
+/* Macro for generating a generic conversion from type A to type B.
+ * Example:
+ *
+ *      BCMOLT_TYPE2TYPE(bws_dba_control_id, bws_dba_control_cb, static)
+ *
+ * will expand to:
+ *
+ *     typedef struct
+ *     {
+ *         bws_dba_control_id from;
+ *         bws_dba_control_cb to;
+ *     }
+ *     bws_dba_control_id2bws_dba_control_cb_t;
+ *     
+ *     static bws_dba_control_id2bws_dba_control_cb_t bws_dba_control_id2bws_dba_control_cb[];
+ *     
+ *     static inline bws_dba_control_cb bws_dba_control_id2bws_dba_control_cb_conv(bws_dba_control_id from)
+ *     {
+ *         const bws_dba_control_id2bws_dba_control_cb_t *arr = bws_dba_control_id2bws_dba_control_cb;
+ *         for (; arr->from != (bws_dba_control_id)-1 && arr->from != from; arr++);
+ *         return arr->to;
+ *     }
+ */
+#define BCMOLT_TYPE2TYPE(from_type, to_type, scope) \
+    typedef struct \
+    { \
+        from_type from; \
+        to_type to; \
+    } \
+    from_type##2##to_type##_t; \
+    scope from_type##2##to_type##_t from_type##2##to_type[]; \
+    static inline to_type from_type##2##to_type##_conv(from_type from) \
+    { \
+        const from_type##2##to_type##_t *arr = from_type##2##to_type; \
+        for (; arr->from != (from_type)-1 && arr->from != from; arr++); \
+        return arr->to; \
+    }
+
+/* Macro for generating a generic conversion from type A to a constant string.
+ * Example:
+ *
+ *      BCMOLT_TYPE2STR(pon_mode, extern)
+ *
+ * will expand to:
+ *
+ *     typedef struct
+ *     {
+ *         pon_mode from;
+ *         const char *to;
+ *     }
+ *     pon_mode2str_t;
+ *
+ *     extern pon_mode2str_t pon_mode2str[];
+ *
+ *     static inline const char *pon_mode2str_conv(pon_mode from)
+ *     {
+ *         const pon_mode2str_t *arr = pon_mode2str;
+ *         for (; arr->from != (pon_mode)-1 && arr->from != from; arr++);
+ *         return arr->to;
+ *     }
+ */
+#define BCMOLT_TYPE2STR(from_type, scope) \
+    typedef struct \
+    { \
+        from_type from; \
+        const char *to; \
+    } \
+    from_type##2str_t; \
+    scope from_type##2str_t from_type##2str[]; \
+    static inline const char *from_type##2str_conv(from_type from) \
+    { \
+        const from_type##2str_t *arr = from_type##2str; \
+        for (; arr->from != (from_type)-1 && arr->from != from; arr++); \
+        return arr->to; \
+    }
+
+/* Macro for generating a generic conversion from type A to an integer.
+ * Example:
+ *
+ *      BCMOLT_TYPE2INT(ploam_ds_gpon_message_id, repetitions, extern)
+ *
+ * will expand to:
+ * 
+ *     typedef struct
+ *     {
+ *         ploam_ds_gpon_message_id from;
+ *         int to;
+ *     }
+ *     ploam_ds_gpon_message_id2repetitions_t;
+ *
+ *     extern ploam_ds_gpon_message_id2repetitions_t ploam_ds_gpon_message_id2repetitions[];
+ *
+ *     static inline int ploam_ds_gpon_message_id2repetitions_conv(ploam_ds_gpon_message_id from)
+ *     {
+ *         const ploam_ds_gpon_message_id2repetitions_t *arr = ploam_ds_gpon_message_id2repetitions;
+ *         for (; arr->from != (ploam_ds_gpon_message_id)-1 && arr->from != from; arr++);
+ *         return arr->to;
+ *     }
+ */
+#define BCMOLT_TYPE2INT(from_type, to_name, scope) \
+    typedef struct \
+    { \
+        from_type from; \
+        int to; \
+    } \
+    from_type##2##to_name##_t; \
+    scope from_type##2##to_name##_t from_type##2##to_name[]; \
+    static inline int from_type##2##to_name##_conv(from_type from) \
+    { \
+        const from_type##2##to_name##_t *arr = from_type##2##to_name; \
+        for (; arr->from != (from_type)-1 && arr->from != from; arr++); \
+        return arr->to; \
+    }
+
+/* Although we have BCMOLT_TYPE2STR, int2str_t is still required when the same generic pointer needs to point to 2 different types (e.g: one specific for GPON and
+ * the other specific for XGPON). */
+typedef struct
+{
+    int from;
+    const char *to;
+}
+int2str_t;
+
+static inline const char *int2str(const int2str_t *arr, int from)
+{
+    for (; arr->from != -1 && arr->from != from; arr++);
+    return arr->to;
+}
+
+/* Although we have BCMOLT_TYPE2INT, int2int_t is still required when the same generic pointer needs to point to 2 different types (e.g: one specific for GPON and
+ * the other specific for XGPON). */
+typedef struct
+{
+    int from;
+    int to;
+}
+int2int_t;
+
+static inline int int2int(const int2int_t *arr, int from)
+{
+    for (; arr->from != -1 && arr->from != from; arr++);
+    return arr->to;
+}
+
+#ifndef CFE_BUILD
+char *bcmolt_strftime(char *time_str, time_t t, const char *timezone_str);
+#endif
+
+#endif
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_firmware_envelope.h b/bcm68620_release/release/host_driver/utils/bcmolt_firmware_envelope.h
new file mode 100644
index 0000000..fd4d6d0
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_firmware_envelope.h
@@ -0,0 +1,95 @@
+/*
+<: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 _BCMOLT_FIRMWARE_ENVELOPE_H_
+#define _BCMOLT_FIRMWARE_ENVELOPE_H_
+
+#include <bcmos_system.h>
+
+#define BCMOLT_FIRMWARE_ENVELOPE_DESC_MAX_SIZE 128
+#define BCMOLT_FIRMWARE_ENVELOPE_TIME_ZONE_SIZE 7
+#define BCMOLT_FIRMWARE_ENVELOPE_MD5_CHECKSUM_SIZE 16
+
+/* Normalized form of a firmware revision for comparison purposes. */
+#define DEVICE_MGMT_REVISION_RELEASE_MAJOR_ID_SHIFT 24
+#define DEVICE_MGMT_REVISION_RELEASE_MINOR_ID_SHIFT 16
+#define DEVICE_MGMT_REVISION_RELEASE_REVISION_ID_SHIFT 8
+#define DEVICE_MGMT_REVISION_MODEL_ID_SHIFT 0
+
+#define BCMOLT_FIRMWARE_ENVELOPE_NORMALIZE(rev_a) \
+    (((rev_a)->release_major_id << DEVICE_MGMT_REVISION_RELEASE_MAJOR_ID_SHIFT) | \
+    ((rev_a)->release_minor_id << DEVICE_MGMT_REVISION_RELEASE_MINOR_ID_SHIFT) | \
+    ((rev_a)->release_revision_id << DEVICE_MGMT_REVISION_RELEASE_REVISION_ID_SHIFT) | \
+    ((rev_a)->model_id << DEVICE_MGMT_REVISION_MODEL_ID_SHIFT))
+
+typedef struct __PACKED_ATTR_START__
+{
+    uint8_t release_major_id;
+    uint8_t release_minor_id;
+    uint8_t release_revision_id;
+    uint32_t model_id;
+} __PACKED_ATTR_END__ bcmolt_firmware_envelope_revision;
+
+typedef struct __PACKED_ATTR_START__
+{
+    uint8_t envelope_revision; /* The envelope itself can be changed over time, so this explains why we need an envelope revision field. */
+    bcmolt_firmware_envelope_revision revision; /* Revision information */
+    uint32_t block_issu_enforce; /* Every time a change in the code cannot be supported in ISSU and requires a regular upgrade (e.g.: SGB/SERDES firmware upgrade), this integer number will 
+                                  * be incremented. If revision validation function detects a change in this integer between two revisions, then it will block ISSU. */
+    uint32_t p4_change_set; /* This is purely informative field that should have no impact on validation. */
+    uint32_t build_time; /* This is purely informative field that should have no impact on validation. It contains the date/time of the image itself, expressed as seconds since the EPOCH. */
+    char build_time_zone[BCMOLT_FIRMWARE_ENVELOPE_TIME_ZONE_SIZE]; /* This is purely informative field that should have no impact on validation. It goes along with build time option and
+                                                                    * provides time zone information, as the embedded side does not know anything about time zone (without that, the build
+                                                                    * time converted to a string will always yield GMT time, not local time). */
+    uint8_t desc[BCMOLT_FIRMWARE_ENVELOPE_DESC_MAX_SIZE]; /* This is purely informative field that should have no impact on validation. */
+    uint8_t md5_checksum[BCMOLT_FIRMWARE_ENVELOPE_MD5_CHECKSUM_SIZE]; /* The MD5 checksum should be applied on the image itself, not on the envelope. This may be redundant because we
+                                                                       * automatically do CRC inherently as part of image transfer mechanism. However, this may have some future use. */
+    uint32_t image_len; /* The size in bytes of the image itself, not with the envelope. 4 bytes should be big enough to accommodate image length up to 4GB, which is far beyond what we
+                         * really need. */
+} __PACKED_ATTR_END__ bcmolt_firmware_envelope;
+
+#endif
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_math.h b/bcm68620_release/release/host_driver/utils/bcmolt_math.h
new file mode 100644
index 0000000..fb52a00
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_math.h
@@ -0,0 +1,71 @@
+/*
+<: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 _BCMOLT_MATH_H_
+#define _BCMOLT_MATH_H_
+
+#include <math.h>
+
+#define ROUND_U32(size_in_bytes) ((uint32_t)((size_in_bytes) + 0.5))
+#define CEIL_U32(size_in_bytes) (((size_in_bytes)-(uint32_t)(size_in_bytes)) > 0 ? ((uint32_t)(size_in_bytes)+1) : (uint32_t)(size_in_bytes))
+#define SQUARE(x) ((x) * (x))
+#define PERCENT(percent, x) (((float)(percent) * (x)) / 100)
+
+/*
+ * Unit Conversion
+ */
+#define BITS_TO_BYTES(bits) ((bits) >> 3)
+#define BYTES_TO_BITS(bytes) ((bytes) << 3)
+
+/* Quantization */
+
+/*
+ * VAL_TO_BIN classifies the value of val to the proper bin
+ * val - a value in the range [0, maxval]
+ * bin - a value in the range [0, bins-1] (result of macro)
+ */
+#define VAL_TO_BIN(val, maxval, bins) ((val) < (maxval) ? ((val) * (bins)) / (maxval) : (bins) - 1)
+
+/* If a value is in a certain bin, it is in the range [min_bin_val, max_bin_val]
+ * min_bin_val - minimum value that belongs to bin
+ * max_bin_val - maximum value that belongs to bin
+ */
+#define BIN_TO_MIN_BIN_VAL(bin, maxval, bins) ((bin) * ((double)(maxval) / (bins)))
+#define BIN_TO_MAX_BIN_VAL(bin, maxval, bins) (((bin) + 1) * ((double)(maxval) / (bins)))
+
+#define GET_MASK(width)             ((1 << (width)) - 1)
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX3(a, b, c) MAX(MAX(a, b), c)
+#define MIN3(a, b, c) MIN(MIN(a, b), c)
+
+#define CEILING(a, b)   (((a) + ((b) - 1)) / (b))
+
+#endif /* _BCMOLT_MATH_H_ */
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_module.h b/bcm68620_release/release/host_driver/utils/bcmolt_module.h
new file mode 100644
index 0000000..ad513e9
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_module.h
@@ -0,0 +1,52 @@
+/*
+<: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 _BCMOLT_MODULE_H_
+#define _BCMOLT_MODULE_H_
+
+#include <bcmos_system.h>
+#include <bcmolt_model_types.h>
+#include <bcm_dev_log.h>
+
+/* The following structure can be used by probably all modules in our system. */
+typedef struct
+{
+    bcmos_task task;
+    bcmos_bool is_enabled;
+    char task_name[MAX_TASK_NAME_SIZE];
+    dev_log_id log_id;
+    bcmolt_pon_ni pon_id;
+    char msg_queue_name[MAX_MSG_QUEUE_NAME_SIZE];
+    bcmos_msg_pool msg_pool;
+    bcmos_module_id module_id;
+    void *context;
+} bcmolt_module_gen_params;
+
+#endif
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_string.c b/bcm68620_release/release/host_driver/utils/bcmolt_string.c
new file mode 100644
index 0000000..a10fa20
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_string.c
@@ -0,0 +1,102 @@
+/*
+<: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 "bcmolt_string.h"
+#include "bcmolt_math.h"
+
+struct bcmolt_string
+{
+    char *str;
+    uint32_t max_len;
+    char *curr;
+    int32_t remaining;
+};
+
+int bcmolt_string_copy(bcmolt_string *str, const char *buf, uint32_t size)
+{
+    int to_copy = MIN(size, str->remaining);
+    memcpy(str->curr, buf, to_copy);
+    str->remaining -= to_copy;
+    str->curr += to_copy;
+    str->curr[0] = '\0';
+    return to_copy;
+}
+
+int bcmolt_string_append(bcmolt_string *str, const char *fmt, ...)
+{
+    int n;
+    va_list args;
+
+    va_start(args, fmt);
+    n = vsnprintf(str->curr, str->remaining, fmt, args);
+    va_end(args);
+    if (n > 0)
+    {
+        if (n > str->remaining)
+        {
+            n = str->remaining;
+        }
+        str->remaining -= n;
+        str->curr += n;
+    }
+
+    return n;
+}
+
+const char *bcmolt_string_get(bcmolt_string *str)
+{
+    return str->str;
+}
+
+void bcmolt_string_reset(bcmolt_string *str)
+{
+    str->str[0] = '\0';
+    str->curr = str->str;
+    str->remaining = str->max_len;
+}
+
+bcmos_errno bcmolt_string_create(bcmolt_string **str, uint32_t max_len)
+{
+    *str = bcmos_calloc(sizeof(bcmolt_string) + max_len + 1);
+    if (*str != NULL)
+    {
+        (*str)->str = (char*)((*str) + 1);
+        (*str)->max_len = max_len;
+        bcmolt_string_reset(*str);
+        return BCM_ERR_OK;
+    }
+
+    return BCM_ERR_NOMEM;
+}
+
+void bcmolt_string_destroy(bcmolt_string *str)
+{
+    bcmos_free(str);
+}
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_string.h b/bcm68620_release/release/host_driver/utils/bcmolt_string.h
new file mode 100644
index 0000000..01fcaa2
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_string.h
@@ -0,0 +1,49 @@
+/*
+<: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 _BCMOLT_STRING_H_
+#define _BCMOLT_STRING_H_
+
+#include "bcmos_system.h"
+
+typedef struct bcmolt_string bcmolt_string;
+
+int bcmolt_string_copy(bcmolt_string *str, const char *buf, uint32_t size);
+
+int bcmolt_string_append(bcmolt_string *str, const char *fmt, ...);
+
+const char *bcmolt_string_get(bcmolt_string *str);
+
+void bcmolt_string_reset(bcmolt_string *str);
+
+bcmos_errno bcmolt_string_create(bcmolt_string **str, uint32_t max_len);
+
+void bcmolt_string_destroy(bcmolt_string *str);
+
+#endif /* _BCMOLT_STRING_H_ */
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_utils.c b/bcm68620_release/release/host_driver/utils/bcmolt_utils.c
new file mode 100644
index 0000000..b8a8994
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_utils.c
@@ -0,0 +1,204 @@
+/*
+<: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 "bcmolt_utils.h"
+
+/* HexPrint a single line */
+#define BYTES_IN_LINE 16
+
+#define b2a(c)  (isprint(c)?c:'.')
+
+static void _hexprint1(bcmos_msg_print_cb print_cb, void *context, uint16_t o, const uint8_t *p_data, uint16_t count, const char *indent)
+{
+    int i;
+
+    if (indent)
+        print_cb(context, "%s", indent);
+
+    print_cb(context, "%04x: ", o);
+    for (i=0; i<count; i++)
+    {
+        print_cb(context, "%02x", p_data[i]);
+        if (!((i+1)%4))
+            print_cb(context, " ");
+    }
+    for (; i<BYTES_IN_LINE; i++)
+    {
+        if (!((i+1)%4))
+            print_cb(context, "   ");
+        else
+            print_cb(context, "  ");
+    }
+    for (i=0; i<count; i++)
+        print_cb(context, "%c", b2a(p_data[i]));
+    print_cb(context, "\n");
+}
+
+void bcmos_hexdump(bcmos_msg_print_cb print_cb, void *context, const void *buffer, uint32_t offset, uint32_t count, const char *indent)
+{
+    const uint8_t *p_data = buffer;
+    uint16_t n;
+
+    while (count)
+    {
+        n = (count > BYTES_IN_LINE) ? BYTES_IN_LINE : count;
+        _hexprint1(print_cb, context, offset, p_data, n, indent);
+        count -= n;
+        p_data += n;
+        offset += n;
+    }
+}
+
+void bcmos_hexdump_one_line(const char *funcname,     /* __FUNCTION__ */
+    uint32_t lineno,       /* __LINE__ */
+    bcmos_msg_print_cb print_cb,
+    void *context,
+    const void *buffer, /* start of memory region to dump */
+    uint32_t start_offset, /* start offset into the region */
+    uint32_t byte_count, /* number of bytes in region to dump */
+    const char *prefix, /* optional prefix string */
+    const char *suffix) /* optional suffix string */
+{
+    const uint8_t *p_data = buffer;
+    uint32_t data_offset = start_offset;
+    size_t max_buf_size = 8000; /* room enough to dump ~2600 bytes with shortish prefixes/suffixes */
+    char *out_buf = bcmos_calloc(max_buf_size);
+    size_t out_buf_offset = 0;
+    uint32_t tmp_num_chars = 0;
+
+    BUG_UNLESS(out_buf);
+
+    memset(out_buf, 0, max_buf_size);
+
+    if (prefix)
+    {
+        tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
+            max_buf_size - out_buf_offset, /* remaining space in out_buf */
+            "\n%40s:%-5u  %s", funcname, lineno, prefix);
+    }
+    else
+    {
+        tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
+            max_buf_size - out_buf_offset, /* remaining space in out_buf */
+            "\n");
+    }
+    out_buf_offset += tmp_num_chars;
+
+    while ((data_offset < (start_offset + byte_count)) && (out_buf_offset < max_buf_size))
+    {
+        tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
+            max_buf_size - out_buf_offset, /* remaining space in out_buf */
+            "%02x ",
+            p_data[data_offset++]); /* byte to dump */
+        BUG_UNLESS(3 == tmp_num_chars);
+        out_buf_offset += tmp_num_chars;
+    }
+
+    if (tmp_num_chars < max_buf_size)
+    {
+        if (suffix)
+        {
+            tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
+                max_buf_size - out_buf_offset, /* remaining space in out_buf */
+                "%s", suffix);
+        }
+        else
+        {
+            tmp_num_chars = snprintf(out_buf + out_buf_offset, /* out_buf start offset */
+                max_buf_size - out_buf_offset, /* remaining space in out_buf */
+                "\n");
+        }
+        out_buf_offset += tmp_num_chars;
+        BUG_UNLESS(out_buf_offset < max_buf_size);
+    }
+
+    print_cb(context, "%s", out_buf);
+    bcmos_free(out_buf);
+}
+
+static uint32_t eth_crc32_tab[] =
+{
+    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+    0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+    0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+    0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+    0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+    0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+    0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+    0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+    0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+    0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+    0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+    0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+    0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+    0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+    0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+    0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+    0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+    0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+uint32_t eth_calc_crc32(uint32_t crc, const void *buf, size_t size)
+{
+    const uint8_t *p;
+
+    p = buf;
+    crc = crc ^ ~0U;
+
+    while (size--)
+        crc = eth_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+
+    return crc ^ ~0U;
+}
+
diff --git a/bcm68620_release/release/host_driver/utils/bcmolt_utils.h b/bcm68620_release/release/host_driver/utils/bcmolt_utils.h
new file mode 100644
index 0000000..b8a5a2d
--- /dev/null
+++ b/bcm68620_release/release/host_driver/utils/bcmolt_utils.h
@@ -0,0 +1,134 @@
+/*
+<: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 _BCMOLT_UTILS_H_
+#define _BCMOLT_UTILS_H_
+
+#include "bcmos_system.h"
+
+#define BCMOS_MACADDR_FMT_STR "%02X:%02X:%02X:%02X:%02X:%02X"
+#define BCMOS_MACADDR_PARAMS(mac) (mac)->u8[0],(mac)->u8[1],(mac)->u8[2],(mac)->u8[3],(mac)->u8[4],(mac)->u8[5]
+
+#define MAC_STR_LEN 18
+
+#define BYTES_IN_MEGABYTE(bytes) ((bytes) / (1024 * 1024))
+
+static inline char *bcmos_mac_2_str(const bcmos_mac_address *mac, char *buf)
+{
+    snprintf(buf, MAC_STR_LEN, BCMOS_MACADDR_FMT_STR, BCMOS_MACADDR_PARAMS(mac));
+    return buf;
+}
+
+/** Swap a byte string of any length.
+ *
+ * \param[in]   ptr     pointer to a memory space.
+ * \param[in]   len     length
+ * \note
+ *      {0, 1, 2, 3} becomes {3, 2, 1, 0}
+ */
+static inline void bcmos_swap_bytes_in_place(uint8_t *ptr, uint32_t len)
+{
+    int  ii;
+    char tmp;
+
+    for (ii = 0; ii < (len / 2); ii++)
+    {
+        tmp = ptr[len - ii - 1];
+        ptr[len - ii - 1] = ptr[ii];
+        ptr[ii] = tmp;
+    }
+}
+
+/** Swap a byte string of any length.
+ *
+ * \param[out]      dst     pointer to a memory space for the swapped bytes.
+ * \param[in]       src     pointer to a memory space for bytes to be swapped.
+ * \param[in]       len     length in bytes
+ * \note
+ *      {0, 1, 2, 3} becomes {3, 2, 1, 0}
+ */
+static inline void bcmos_swap_bytes(uint8_t *dst, const uint8_t *src, const uint32_t len)
+{
+    int  ii;
+
+    for (ii = 0; ii < len; ii++)
+    {
+        dst[ii] = src[len - ii - 1];
+    }
+}
+
+/** Copy bits from a given range of the source to a different range of the
+ *  destination
+ *
+ * \param[in]   dst         destination value to be merged to
+ * \param[in]   dst_hi      high bit position
+ * \param[in]   dst_lo      low bit position
+ * \param[in]   src         source value to copy the bits from
+ * \param[in]   src_hi      high bit position
+ * \param[in]   src_lo      low bit position
+ *
+ * \return      destination value
+ */
+static inline uint32_t bcmos_bits_copy_u32(uint32_t dst, uint8_t dst_hi, uint8_t dst_lo,
+    uint32_t src, uint8_t src_hi, uint8_t src_lo)
+{
+    dst &= (~(((1 << ((dst_hi - dst_lo) + 1)) - 1) << dst_lo));
+    src &= (((1 << ((src_hi - src_lo) + 1)) - 1) << src_lo);
+    dst |= ((dst_lo >= src_lo)? (src << (dst_lo - src_lo)): (src >> (src_lo - dst_lo)));
+    return dst;
+}
+
+/* network to host on unaligned array of uint32_t elements. Treat pointer p as a pointer to an array of uint32_t elements. Get element i.  */
+#define N2H32(p, i) ((((const uint8_t *)(p))[(i) * 4]<<24) | (((const uint8_t *)(p))[(i) * 4+1]<<16) | (((const uint8_t *)(p))[(i) * 4+2]<<8) | (((const uint8_t *)(p))[(i) * 4+3]))
+/* network to host on unaligned array of uint16_t elements. Treat pointer p as a pointer to an array of uint16_t elements. Get element i. */
+#define N2H16(p, i) ((((const uint8_t *)(p))[(i) * 2]<<8) | (((const uint8_t *)(p))[(i) * 2+1]))
+/* network to host on unaligned array of uint8_t elements. Treat pointer p as a pointer to an array of uint8_t elements. Get element i. */
+#define N2H8(p, i) (((const uint8_t *)(p))[(i)])
+
+/* For internal use by the following H2N* macros */
+#define H2N8(p, v)   *((uint8_t *)p) = (uint8_t)(v)
+/* host to network conversion of a uint16_t with support for non 16 bit aligned destination address. p is a (uint8_t *) destination pointer. v is a uint16_t value. v can be written to p even if p is unaligned to 16 bits. */
+#define H2N16(p, v)  (H2N8((p), (v) >> 8), H2N8(((uint8_t *)(p) + 1), (v)))
+/* host to network conversion of a uint32_t with support for non 32 bit aligned destination address. p is a (uint8_t *) destination pointer. v is a uint32_t value. v can be written to p even if p is unaligned to 32 bits. */
+#define H2N32(p, v)  (H2N16((p), (v) >> 16), H2N16(((uint8_t *)(p) + 2), (v)))
+
+#define NUM_ELEM(array)     (sizeof(array) / sizeof((array)[0]))
+
+typedef void (*bcmos_msg_print_cb)(void *context, const char *fmt, ...);
+
+void bcmos_hexdump(bcmos_msg_print_cb print_cb, void *context, const void *buffer, uint32_t offset, uint32_t count, const char *indent);
+void bcmos_hexdump_one_line(const char *funcname, uint32_t lineno, bcmos_msg_print_cb print_cb, void *context, const void *buffer, uint32_t offset, uint32_t count, const char *prefix,
+    const char *suffix);
+
+uint32_t eth_calc_crc32(uint32_t crc, const void *buf, size_t size);
+
+#define BCMOLT_TIME_STR_MAX_LEN 80
+
+#endif /* BCMOLT_UTILS_H */
+