BAL and Maple Release 2.2

Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_driver/debug/Makefile b/bcm68620_release/release/host_driver/debug/Makefile
new file mode 100644
index 0000000..0e6e3e6
--- /dev/null
+++ b/bcm68620_release/release/host_driver/debug/Makefile
@@ -0,0 +1,10 @@
+# Common debug API
+#
+MOD_NAME = debug_common
+MOD_DEPS = os dev_log utils model transport common_api
+MOD_TYPE = lib
+
+srcs = bcmolt_debug_api_common.c
+
+USE_LINT=yes
+
diff --git a/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.c b/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.c
new file mode 100644
index 0000000..4fb6bcf
--- /dev/null
+++ b/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.c
@@ -0,0 +1,327 @@
+/*
+<: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_math.h"
+#include "bcmtr_debug.h"
+#include "bcmolt_msg.h"
+#include "bcmolt_debug_api_common.h"
+
+#define API_CFG_PROP_EXISTS(mask, prop)  (((mask) & (1ULL << (prop))) != 0)
+
+static void bcmolt_debug_api_common_capture_stats_update(bcmolt_devid device, bcmolt_debug_api_db *db)
+{
+    bcmos_errno err;
+    bcmtr_capture_info info;
+
+    err = bcmtr_capture_info_get(device, &info);
+    BUG_ON(BCM_ERR_OK != err);
+
+    db->cfg.api_capture_stats.buffer_used_bytes = info.used;
+    db->cfg.api_capture_stats.events_recorded = info.msgs;
+    db->cfg.api_capture_stats.events_dropped = info.lost;
+    db->cfg.api_capture_stats.buffer_wrap_count = info.wa;
+
+    err = bcmtr_capture_size_get(device, &db->cfg.api_capture_stats.readable_bytes);
+    BUG_ON(BCM_ERR_OK != err);
+}
+
+static bcmos_errno bcmolt_debug_api_common_capture_init(bcmolt_devid device, bcmolt_debug_api_db *db)
+{
+    bcmos_errno err;
+    bcmtr_capture_parm cap_parm = {};
+
+    cap_parm.size = db->cfg.api_capture_cfg.buffer_size_bytes;
+    cap_parm.ptr = db->capture_buffer;
+    cap_parm.stop_on_full = db->cfg.api_capture_cfg.buffer_mode == BCMOLT_API_CAPTURE_BUFFER_MODE_OVERFLOW;
+    cap_parm.activate = BCMOS_FALSE;
+
+    err = bcmtr_capture_init(device, &cap_parm);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+
+    bcmolt_debug_api_common_capture_stats_update(device, db);
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmolt_debug_api_common_get(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db)
+{
+    if (API_CFG_PROP_EXISTS(msg->presence_mask, BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER))
+    {
+        uint32_t to_read = 0;
+
+        if (bcmtr_capture_is_active(device))
+        {
+            return bcmolt_msg_err(
+                msg,
+                DEV_LOG_INVALID_ID,
+                BCM_ERR_STATE,
+                BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER,
+                "Cannot read capture buffer while capture is in progress");
+        }
+
+        if (db->cfg.api_capture_buffer_read.offset < db->cfg.api_capture_stats.readable_bytes)
+        {
+            to_read = MIN(
+                db->cfg.api_capture_buffer.len,
+                db->cfg.api_capture_stats.readable_bytes - db->cfg.api_capture_buffer_read.offset);
+        }
+        if ((db->cfg.api_capture_buffer.val != NULL) && (db->cfg.api_capture_buffer.len > 0))
+        {
+            bcmtr_capture_read(
+                device,
+                db->cfg.api_capture_buffer.val,
+                db->cfg.api_capture_buffer_read.offset,
+                &to_read);
+            memset(db->cfg.api_capture_buffer.val + (db->cfg.api_capture_buffer.len - to_read), 0, to_read);
+        }
+    }
+
+    return BCM_ERR_OK;
+}
+
+debug_trans_handle *bcmolt_debug_api_common_cfg_trans_start(bcmolt_debug_api_db *db)
+{
+    debug_trans_handle *handle = bcmos_calloc(sizeof(*handle));
+    handle->old_db = *db;
+    handle->new_db = db;
+    return handle;
+}
+
+void bcmolt_debug_api_common_cfg_trans_fail(bcmolt_debug_api_db *db, debug_trans_handle *handle)
+{
+    if (handle->old_db.capture_buffer != handle->new_db->capture_buffer)
+    {
+        bcmos_free(handle->new_db->capture_buffer);
+    }
+    if (handle->old_db.cfg.api_capture_buffer.val != handle->new_db->cfg.api_capture_buffer.val)
+    {
+        bcmos_free(handle->new_db->cfg.api_capture_buffer.val);
+    }
+    *db = handle->old_db;
+    bcmos_free(handle);
+}
+
+void bcmolt_debug_api_common_cfg_trans_succeed(bcmolt_devid device, debug_trans_handle *handle)
+{
+    bcmos_errno err;
+
+    if (handle->old_db.capture_buffer != handle->new_db->capture_buffer)
+    {
+        bcmos_free(handle->old_db.capture_buffer);
+        bcmtr_capture_destroy(device);
+        err = bcmolt_debug_api_common_capture_init(device, handle->new_db);
+        if (BCM_ERR_OK != err) /* cfg_set should have validated that this won't fail */
+        {
+            BCMOS_TRACE_ERR("Capture init failed (%s)!\n", bcmos_strerror(err));
+        }
+    }
+    if (handle->old_db.cfg.api_capture_buffer.val != handle->new_db->cfg.api_capture_buffer.val)
+    {
+        bcmos_free(handle->old_db.cfg.api_capture_buffer.val);
+    }
+    bcmos_free(handle);
+}
+
+bcmos_errno bcmolt_debug_api_common_set(
+    bcmolt_devid device,
+    bcmolt_msg *msg,
+    const bcmolt_debug_cfg_data *data,
+    debug_trans_handle *handle,
+    bcmolt_api_capture_location local)
+{
+    if (API_CFG_PROP_EXISTS(msg->presence_mask, BCMOLT_DEBUG_CFG_ID_API_CAPTURE_CFG))
+    {
+        if (bcmtr_capture_is_active(device))
+        {
+            return bcmolt_msg_err(
+                msg,
+                DEV_LOG_INVALID_ID,
+                BCM_ERR_STATE,
+                BCMOLT_DEBUG_CFG_ID_API_CAPTURE_CFG,
+                "Cannot change capture configuration while capture is in progress");
+        }
+        handle->new_db->cfg.api_capture_cfg = data->api_capture_cfg;
+    }
+
+    if (API_CFG_PROP_EXISTS(msg->presence_mask, BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER_READ))
+    {
+        handle->new_db->cfg.api_capture_buffer_read = data->api_capture_buffer_read;
+    }
+
+    /* Once all the properties are handled, we need to take care of a few things that could depend on multiple
+       properties */
+    if ((handle->new_db->cfg.api_capture_cfg.location == local) &&
+        /* If we just switched to the device ... */
+        ((handle->new_db->cfg.api_capture_cfg.location != handle->old_db.cfg.api_capture_cfg.location) ||
+         /* ... or either the buffer size ... */
+        (handle->new_db->cfg.api_capture_cfg.buffer_size_bytes !=
+         handle->old_db.cfg.api_capture_cfg.buffer_size_bytes) ||
+         /* ... or the buffer mode have changed */
+        (handle->new_db->cfg.api_capture_cfg.buffer_mode != handle->old_db.cfg.api_capture_cfg.buffer_mode)))
+    {
+        handle->new_db->capture_buffer = bcmos_alloc(handle->new_db->cfg.api_capture_cfg.buffer_size_bytes);
+        if (handle->new_db->capture_buffer == NULL)
+        {
+            return bcmolt_msg_err(
+                msg,
+                DEV_LOG_INVALID_ID,
+                BCM_ERR_NOMEM,
+                BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER_READ,
+                "Failed to allocate new capture buffer");
+        }
+    }
+
+    if ((handle->new_db->cfg.api_capture_cfg.location == local) &&
+        /* If we just switched to the device ... */
+        ((handle->new_db->cfg.api_capture_cfg.location != handle->old_db.cfg.api_capture_cfg.location) ||
+         /* ... or the read size has changed */
+        (handle->old_db.cfg.api_capture_buffer_read.size != handle->new_db->cfg.api_capture_buffer_read.size)))
+    {
+        handle->new_db->cfg.api_capture_buffer.len = handle->new_db->cfg.api_capture_buffer_read.size;
+        if (handle->new_db->cfg.api_capture_buffer.len != 0)
+        {
+            handle->new_db->cfg.api_capture_buffer.val = bcmos_alloc(handle->new_db->cfg.api_capture_buffer_read.size);
+            if (handle->new_db->cfg.api_capture_buffer.val == NULL)
+            {
+                return bcmolt_msg_err(
+                    msg,
+                    DEV_LOG_INVALID_ID,
+                    BCM_ERR_NOMEM,
+                    BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER_READ,
+                    "Failed to allocate new read buffer");
+            }
+        }
+        else
+        {
+            handle->new_db->cfg.api_capture_buffer.val = NULL;
+        }
+    }
+
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmolt_debug_api_common_oper_start_api_capture(bcmolt_devid device, bcmolt_msg *msg)
+{
+    bcmos_errno err;
+    bcmtr_cld_filter filter;
+
+    if (bcmtr_capture_is_active(device))
+    {
+        return bcmolt_msg_err(
+            msg,
+            DEV_LOG_INVALID_ID,
+            BCM_ERR_ALREADY,
+            BCMOLT_ERR_FIELD_NONE,
+            "Capture already in progress");
+    }
+
+    /* capture everything */
+    filter.object = BCMOLT_OBJECT_ANY;
+    filter.group = BCMOLT_MGT_GROUP_ANY;
+    filter.subgroup = BCMOLT_SUBGROUP_ANY;
+    err = bcmtr_cld_level_set(device, &filter, BCMTR_CLD_CAPTURE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+    /* for now filter out start/stop operations and keep-alives */
+    filter.object = BCMOLT_OBJ_ID_DEBUG;
+    filter.group = BCMOLT_MGT_GROUP_OPER;
+    filter.subgroup = BCMOLT_DEBUG_OPER_ID_START_API_CAPTURE; /*lint !e633 */
+    err = bcmtr_cld_level_set(device, &filter, BCMTR_CLD_NONE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+    filter.subgroup = BCMOLT_DEBUG_OPER_ID_STOP_API_CAPTURE;  /*lint !e633 */
+    err = bcmtr_cld_level_set(device, &filter, BCMTR_CLD_NONE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+    filter.object = BCMOLT_OBJ_ID_DEVICE;
+    filter.group = BCMOLT_MGT_GROUP_OPER;
+    filter.subgroup = BCMOLT_DEVICE_OPER_ID_HOST_KEEP_ALIVE;  /*lint !e633 */
+    err = bcmtr_cld_level_set(device, &filter, BCMTR_CLD_NONE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+    filter.group = BCMOLT_MGT_GROUP_AUTO;
+    filter.subgroup = BCMOLT_DEVICE_AUTO_ID_DEVICE_KEEP_ALIVE;  /*lint !e633 */
+    err = bcmtr_cld_level_set(device, &filter, BCMTR_CLD_NONE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+
+    return bcmtr_capture_start_stop(device, BCMOS_TRUE);
+}
+
+bcmos_errno bcmolt_debug_api_common_oper_stop_api_capture(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db)
+{
+    bcmos_errno err;
+
+    if (!bcmtr_capture_is_active(device))
+    {
+        return bcmolt_msg_err(
+            msg,
+            DEV_LOG_INVALID_ID,
+            BCM_ERR_ALREADY,
+            BCMOLT_ERR_FIELD_NONE,
+            "No capture in progress");
+    }
+
+    err = bcmtr_capture_start_stop(device, BCMOS_FALSE);
+    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != err, err);
+
+    bcmolt_debug_api_common_capture_stats_update(device, db);
+
+    return BCM_ERR_OK;
+}
+
+bcmos_errno bcmolt_debug_api_common_oper_reset_api_capture(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db)
+{
+    bcmos_errno err;
+
+    if (bcmtr_capture_is_active(device))
+    {
+        return bcmolt_msg_err(
+            msg,
+            DEV_LOG_INVALID_ID,
+            BCM_ERR_STATE,
+            BCMOLT_ERR_FIELD_NONE,
+            "Cannot reset capture while capture is running");
+    }
+
+    bcmtr_capture_destroy(device);
+    err = bcmolt_debug_api_common_capture_init(device, db);
+
+    return err;
+}
+
+void bcmolt_debug_api_common_init(bcmolt_devid device, bcmolt_debug_api_db *db)
+{
+    bcmos_errno err;
+
+#if ENABLE_LOG
+    db->log_id = bcm_dev_log_id_register("mh_debug", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+#endif
+
+    bcmolt_debug_cfg_data_set_default(&db->cfg, BCMOLT_PRESENCE_MASK_ALL);
+    db->capture_buffer = bcmos_alloc(db->cfg.api_capture_cfg.buffer_size_bytes);
+    err = bcmolt_debug_api_common_capture_init(device, db);
+    BUG_ON(BCM_ERR_OK != err);
+}
+
diff --git a/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.h b/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.h
new file mode 100644
index 0000000..a1f28ab
--- /dev/null
+++ b/bcm68620_release/release/host_driver/debug/bcmolt_debug_api_common.h
@@ -0,0 +1,73 @@
+/*
+<: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_DEBUG_API_COMMON_H_
+#define BCMOLT_DEBUG_API_COMMON_H_
+
+#include "bcmolt_model_types.h"
+#include "bcm_dev_log.h"
+
+typedef struct
+{
+    bcmolt_debug_cfg_data cfg;
+    uint8_t *capture_buffer;
+    dev_log_id log_id;
+} bcmolt_debug_api_db;
+
+typedef struct
+{
+    bcmolt_debug_api_db old_db;
+    bcmolt_debug_api_db *new_db;
+} debug_trans_handle;
+
+bcmos_errno bcmolt_debug_api_common_get(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db);
+
+debug_trans_handle *bcmolt_debug_api_common_cfg_trans_start(bcmolt_debug_api_db *db);
+
+void bcmolt_debug_api_common_cfg_trans_fail(bcmolt_debug_api_db *db, debug_trans_handle *handle);
+
+void bcmolt_debug_api_common_cfg_trans_succeed(bcmolt_devid device, debug_trans_handle *handle);
+
+bcmos_errno bcmolt_debug_api_common_set(
+    bcmolt_devid device,
+    bcmolt_msg *msg,
+    const bcmolt_debug_cfg_data *data,
+    debug_trans_handle *handle,
+    bcmolt_api_capture_location local);
+
+bcmos_errno bcmolt_debug_api_common_oper_start_api_capture(bcmolt_devid device, bcmolt_msg *msg);
+
+bcmos_errno bcmolt_debug_api_common_oper_stop_api_capture(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db);
+
+bcmos_errno bcmolt_debug_api_common_oper_reset_api_capture(bcmolt_devid device, bcmolt_msg *msg, bcmolt_debug_api_db *db);
+
+void bcmolt_debug_api_common_init(bcmolt_devid device, bcmolt_debug_api_db *db);
+
+#endif /* BCMOLT_DEBUG_API_COMMON_H_ */
+