/*
<: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.

:>
 */

#define HOST_API_CAPTURE 0

#include "bcmos_system.h"
#include "bcmolt_api.h"
#include "bcmolt_msg.h"
#include "bcmolt_tr_mux.h"
#if HOST_API_CAPTURE
#include "bcmolt_debug_api_common.h"
#endif
#include "bcmolt_dev_ctrl.h"
#include "bcmolt_debug_ctrl.h"

#define API_CAPTURE_PROP_MASK\
    ((1ULL << BCMOLT_DEBUG_CFG_ID_API_CAPTURE_CFG) |\
     (1ULL << BCMOLT_DEBUG_CFG_ID_API_CAPTURE_STATS) |\
     (1ULL << BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER_READ) |\
     (1ULL << BCMOLT_DEBUG_CFG_ID_API_CAPTURE_BUFFER))

typedef struct
{
    bcmos_bool waiting_for_ack;
    bcmolt_msg *last_message;
    bcmos_timer ack_timeout;
#if HOST_API_CAPTURE
    bcmolt_debug_api_db db;
    debug_trans_handle *handle;
#endif
} debug_ctrl_ctxt;

static debug_ctrl_ctxt debug_ctrl[BCMTR_MAX_OLTS];

static void send_to_host(bcmolt_devid device, bcmolt_msg *msg)
{
    msg->dir = BCMOLT_MSG_DIR_RESPONSE;
    bcmtrmux_control_to_host(device, msg);
    bcmolt_msg_free(msg);
}

static void send_to_device(bcmolt_devid device, bcmolt_msg *msg)
{
    debug_ctrl[device].waiting_for_ack = BCMOS_TRUE;
    debug_ctrl[device].last_message = msg;
    bcmtrmux_control_to_line(device, msg);
    bcmos_timer_start(&debug_ctrl[device].ack_timeout, DEVICE_RESPONSE_TIMEOUT_LENGTH);
}

static bcmos_bool bcmolt_debug_ctrl_cfg_requires_connection(bcmolt_msg *msg, const bcmolt_debug_cfg_data *cfg)
{
    return (((msg->presence_mask & ~API_CAPTURE_PROP_MASK) != 0) || /* includes non-API capture elements, or ... */
            (((msg->presence_mask & API_CAPTURE_PROP_MASK) != 0) && /* includes API captue elements and ... */
             (cfg->api_capture_cfg.location == BCMOLT_API_CAPTURE_LOCATION_DEVICE))); /* capture location is device */
}

static void bcmolt_debug_ctrl_send_cfg_get_response(bcmolt_devid device, bcmolt_msg *msg)
{
#if HOST_API_CAPTURE
    if (debug_ctrl[device].db.cfg.api_capture_cfg.location == BCMOLT_API_CAPTURE_LOCATION_HOST)
    {
        bcmolt_debug_api_common_get(device, msg, &debug_ctrl[device].db);
    }
#endif
    send_to_host(device, msg);
}

static void bcmolt_debug_ctrl_handle_cfg_get(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
#if HOST_API_CAPTURE
    if (bcmolt_debug_ctrl_cfg_requires_connection(msg, &debug_ctrl[device].db.cfg))
#endif
    {
        if (connected)
        {
            send_to_device(device, msg);
            return;
        }

        bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_NOT_CONNECTED,
            BCMOLT_ERR_FIELD_NONE,
            "Cannot access embedded parameters while disconnected");
    }

    bcmolt_debug_ctrl_send_cfg_get_response(device, msg);
}

static void bcmolt_debug_ctrl_send_cfg_set_response(bcmolt_devid device, bcmolt_msg *msg)
{
#if HOST_API_CAPTURE
    if (msg->err == BCM_ERR_OK)
    {
        bcmolt_debug_api_common_cfg_trans_succeed(device, debug_ctrl[device].handle);
    }
    else
    {
        bcmolt_debug_api_common_cfg_trans_fail(&debug_ctrl[device].db, debug_ctrl[device].handle);
    }
#endif

    send_to_host(device, msg);
}

static void bcmolt_debug_ctrl_handle_cfg_set(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
    bcmolt_debug_cfg *cfg = (bcmolt_debug_cfg*)msg;
    bcmolt_debug_cfg_id prop_id;
    bcmos_errno err;

    if (!bcmolt_debug_cfg_data_bounds_check(&cfg->data, msg->presence_mask, &prop_id))
    {
        err = BCM_ERR_RANGE;
        msg->err_field_idx = (uint16_t)prop_id;
        send_to_host(device, msg);
        return;
    }

#if HOST_API_CAPTURE
    debug_ctrl[device].handle = bcmolt_debug_api_common_cfg_trans_start(&debug_ctrl[device].db);
    err = bcmolt_debug_api_common_set(device, msg, &cfg->data, debug_ctrl[device].handle, BCMOLT_API_CAPTURE_LOCATION_HOST);
#else
    if (BCMOLT_CFG_PROP_IS_SET(cfg, debug, api_capture_cfg) &&
        (cfg->data.api_capture_cfg.location == BCMOLT_API_CAPTURE_LOCATION_HOST))
    {
        err = bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_NOT_SUPPORTED,
            BCMOLT_ERR_FIELD_NONE,
            "Host API capture not supported yet");
    }
    else
    {
        err = BCM_ERR_OK;
    }
#endif
    if (err == BCM_ERR_OK)
    {
        if (bcmolt_debug_ctrl_cfg_requires_connection(msg, &cfg->data))
        {
            if (connected)
            {
                send_to_device(device, msg);
                return;
            }

            bcmolt_msg_err(
                msg,
                DEV_LOG_INVALID_ID,
                BCM_ERR_NOT_CONNECTED,
                BCMOLT_ERR_FIELD_NONE,
                "Cannot access embedded parameters while disconnected");
        }
    }

    bcmolt_debug_ctrl_send_cfg_set_response(device, msg);
}

static void bcmolt_debug_ctrl_handle_cfg_clear(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
#if HOST_API_CAPTURE
    bcmolt_debug_cfg *cfg = (bcmolt_debug_cfg*)msg;
#endif
    bcmos_errno err;

    if (!connected)
    {
        bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_NOT_CONNECTED,
            BCMOLT_ERR_FIELD_NONE,
            "Cannot access embedded parameters while disconnected");
        send_to_host(device, msg);
        return;
    }

#if HOST_API_CAPTURE
    debug_ctrl[device].handle = bcmolt_debug_api_common_cfg_trans_start(&debug_ctrl[device].db);
    bcmolt_debug_cfg_data_set_default(&debug_ctrl[device].db.cfg, BCMOLT_PRESENCE_MASK_ALL);
    msg->presence_mask = BCMOLT_PRESENCE_MASK_ALL;
    err = bcmolt_debug_api_common_set(device, msg, &cfg->data, debug_ctrl[device].handle, BCMOLT_API_CAPTURE_LOCATION_HOST);
#else
    err = BCM_ERR_OK;
#endif
    if (err == BCM_ERR_OK)
    {
        send_to_device(device, msg);
    }
    else
    {
        bcmolt_debug_ctrl_send_cfg_set_response(device, msg);
    }
}

static void bcmolt_debug_ctrl_handle_cfg(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
    switch (msg->type)
    {
        case BCMOLT_MSG_TYPE_GET:
            bcmolt_debug_ctrl_handle_cfg_get(device, msg, connected);
            break;
        case BCMOLT_MSG_TYPE_SET:
            bcmolt_debug_ctrl_handle_cfg_set(device, msg, connected);
            break;
        case BCMOLT_MSG_TYPE_CLEAR:
            bcmolt_debug_ctrl_handle_cfg_clear(device, msg, connected);
            break;
        default:
            bcmolt_msg_err(
                msg,
                DEV_LOG_INVALID_ID,
                BCM_ERR_NOT_SUPPORTED,
                BCMOLT_ERR_FIELD_NONE,
                "Unsupported message type (%u)",
                msg->type);
            send_to_host(device, msg);
            break;
    }
}

static void bcmolt_debug_ctrl_handle_oper(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
#if HOST_API_CAPTURE
    bcmos_bool host_api_capture =
        (debug_ctrl[device].db.cfg.api_capture_cfg.location == BCMOLT_API_CAPTURE_LOCATION_HOST);

    switch (msg->subgroup)
    {
        case BCMOLT_DEBUG_OPER_ID_START_API_CAPTURE:
            if (host_api_capture)
            {
                msg->err = bcmolt_debug_api_common_oper_start_api_capture(device, msg);
                send_to_host(device, msg);
                return;
            }
            break;
        case BCMOLT_DEBUG_OPER_ID_STOP_API_CAPTURE:
            if (host_api_capture)
            {
                msg->err = bcmolt_debug_api_common_oper_stop_api_capture(device, msg, &debug_ctrl[device].db);
                send_to_host(device, msg);
                return;
            }
            break;
        case BCMOLT_DEBUG_OPER_ID_RESET_API_CAPTURE:
            if (host_api_capture)
            {
                msg->err = bcmolt_debug_api_common_oper_reset_api_capture(device, msg, &debug_ctrl[device].db);
                send_to_host(device, msg);
                return;
            }
            break;
        default:
            break;
    }
#endif

    if (!connected)
    {
        bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_NOT_CONNECTED,
            BCMOLT_ERR_FIELD_NONE,
            "Cannot perform embedded operations while disconnected");
        send_to_host(device, msg);
        return;
    }

    send_to_device(device, msg);
}

static void bcmolt_debug_ctrl_handle_auto_cfg(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
    if (!connected)
    {
        bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_NOT_CONNECTED,
            BCMOLT_ERR_FIELD_NONE,
            "Cannot access embedded parameters while disconnected");
        send_to_host(device, msg);
        return;
    }

    send_to_device(device, msg);
}

static void bcmolt_debug_ctrl_handle_request(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
    if (debug_ctrl[device].waiting_for_ack)
    {
        bcmolt_msg_err(
            msg,
            DEV_LOG_INVALID_ID,
            BCM_ERR_TOO_MANY_REQS,
            BCMOLT_ERR_FIELD_NONE,
            "Transaction in progress on debug object");
        send_to_host(device, msg);
        return;
    }

    switch (msg->group)
    {
        case BCMOLT_MGT_GROUP_CFG:
            bcmolt_debug_ctrl_handle_cfg(device, msg, connected);
            break;
        case BCMOLT_MGT_GROUP_OPER:
            bcmolt_debug_ctrl_handle_oper(device, msg, connected);
            break;
        case BCMOLT_MGT_GROUP_AUTO_CFG:
            bcmolt_debug_ctrl_handle_auto_cfg(device, msg, connected);
            break;
        default:
            bcmolt_msg_err(
                msg,
                DEV_LOG_INVALID_ID,
                BCM_ERR_NOT_SUPPORTED,
                BCMOLT_ERR_FIELD_NONE,
                "Unsupported group (%u)",
                msg->group);
            send_to_host(device, msg);
            break;
    }
}

static void bcmolt_debug_ctrl_handle_response(bcmolt_devid device, bcmolt_msg *msg)
{
    if (!debug_ctrl[device].waiting_for_ack || (msg->corr_tag != debug_ctrl[device].last_message->corr_tag))
    {
        msg->subch = BCMTRMUX_CHANNEL_AUTO_PROXY;
        send_to_host(device, msg);
        return;
    }

    msg->subch = debug_ctrl[device].last_message->subch;
    bcmos_timer_stop(&debug_ctrl[device].ack_timeout);
    debug_ctrl[device].waiting_for_ack = BCMOS_FALSE;
    bcmolt_msg_free(debug_ctrl[device].last_message);

    if (msg->err != BCM_ERR_OK)
    {
        send_to_host(device, msg);
        return;
    }

    switch (msg->group)
    {
        case BCMOLT_MGT_GROUP_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    bcmolt_debug_ctrl_send_cfg_get_response(device, msg);
                    break;
                case BCMOLT_MSG_TYPE_SET:
                    bcmolt_debug_ctrl_send_cfg_set_response(device, msg);
                    break;
                case BCMOLT_MSG_TYPE_CLEAR:
                    bcmolt_debug_ctrl_send_cfg_set_response(device, msg);
                    break;
                default:
                    BCMOS_TRACE_ERR("Got unexpected response type (%u) from embedded\n", msg->group);
                    send_to_host(device, msg);
                    break;
            }
            break;
        case BCMOLT_MGT_GROUP_OPER:
        case BCMOLT_MGT_GROUP_AUTO_CFG:
            send_to_host(device, msg);
            break;
        default:
            BCMOS_TRACE_ERR("Got unexpected response group (%u) from embedded\n", msg->group);
            send_to_host(device, msg);
            break;
    }
}

static bcmos_timer_rc bcmolt_debug_ctrl_handle_ack_timeout(bcmos_timer *timer, long data)
{
    bcmolt_devid device = (bcmolt_devid)data;

    if (debug_ctrl[device].last_message == NULL)
    {
        BCMOS_TRACE_ERR("Waiting with no message!\n");
        return BCMOS_TIMER_OK;
    }

    bcmolt_msg_err(
        debug_ctrl[device].last_message,
        DEV_LOG_INVALID_ID,
        BCM_ERR_INTERNAL,
        BCMOLT_ERR_FIELD_NONE,
        "Did not receive response from embedded");
    send_to_host(device, debug_ctrl [device].last_message);

    return BCMOS_TIMER_OK;
}

void bcmolt_debug_ctrl_process_msg(bcmolt_devid device, bcmolt_msg *msg, bcmos_bool connected)
{
    switch (msg->dir)
    {
        case BCMOLT_MSG_DIR_REQUEST:
            bcmolt_debug_ctrl_handle_request(device, msg, connected);
            break;
        case BCMOLT_MSG_DIR_RESPONSE:
            bcmolt_debug_ctrl_handle_response(device, msg);
            break;
        default:
            BCMOS_TRACE_ERR("Unsupported direction: %u\n", msg->dir);
            bcmolt_msg_free(msg);
            break;
    }
}

void bcmolt_debug_ctrl_init(void)
{
    bcmolt_devid i;

    for (i = 0; i < BCMTR_MAX_OLTS; i++)
    {
        bcmos_timer_parm tp =
        {
            .name = "debug_ctrl_ack_timeout",
            .owner = BCMOS_MODULE_ID_DEV_CTRL_DEV0 + i,
            .periodic = BCMOS_FALSE,
            .handler = bcmolt_debug_ctrl_handle_ack_timeout,
            .data = (long)i,
            .flags = BCMOS_TIMER_PARM_FLAGS_URGENT,
        };

        debug_ctrl[i].waiting_for_ack = BCMOS_FALSE;
        bcmos_timer_create(&debug_ctrl[i].ack_timeout, &tp);
#if HOST_API_CAPTURE
        bcmolt_debug_api_common_init(i, &debug_ctrl[i].db);
#endif
    }
}
