/*
<: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);
}

