/*
<: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 <bcmtr_interface.h>
#include <bcmtr_debug.h>

#include "bcmtr_header.h"
#include "bcmtr_internal.h"

typedef struct
{
    bcmtr_conn *conn; /**< Connection dynamic info (allocated on connect) */
    bcmtr_handler msg_handler[BCMOLT_GROUP_ID__NUM_OF][BCMTR_MAX_INSTANCES];
    F_bcmtr_tx_overflow overflow_cb;    /**< Callback to be called in case of tx drop because of queue overflow */
} bcmtr_conn_info;

static bcmtr_conn_info conn_info[BCMTR_MAX_OLTS]; /* Store connection info separately per OLT */

static bcmos_errno _bcmtr_connect(bcmolt_devid device, bcmtr_conn **conn, bcmos_bool raw_mode);

static bcmos_mutex conn_lock;

/* Get existing connection. If none - setup new.
 * If raw_mode is TRUE, the connection is intended for use by raw interface
 * bcmtr_proxy_xx(). In this case RX task is not created
 */
static bcmos_errno _bcmtr_conn_get_any(bcmolt_devid device, bcmtr_conn **conn, bcmos_bool is_raw)
{
    bcmos_errno err;
    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }
    *conn = conn_info[device].conn;
    if (*conn)
    {
        return BCM_ERR_OK;
    }
    err = _bcmtr_connect(device, &conn_info[device].conn, is_raw);
    *conn = conn_info[device].conn;
    return err;
}

/* Get existing connection. If none - setup new */
bcmos_errno _bcmtr_conn_get(bcmolt_devid device, bcmtr_conn **conn)
{
    return _bcmtr_conn_get_any(device, conn, BCMOS_FALSE);
}

/* Free reassemble block */
static void _bcmtr_reass_block_free(bcmtr_reass **prb)
{
    bcmtr_reass *reass = *prb;
    int i;

    for (i=0; i<reass->num_fragments; i++)
    {
        bcmolt_buf_free(&reass->fragments[i]);
    }
    bcmos_free(reass);
    *prb = NULL;
}

/* Free transport header. Called under transport lock */
static void _bcmtr_tmsg_free(bcmtr_msg *tmsg, bcmtr_msg_list *cur_list)
{
    /* Remove from the list it is in, if any */
    if (cur_list)
        TAILQ_REMOVE(cur_list, tmsg, l);

    bcmolt_buf_free(&tmsg->tx_buf);
    bcmolt_buf_free(&tmsg->rx_buf);
    if (tmsg->reass)
        _bcmtr_reass_block_free(&tmsg->reass);
    memset(tmsg, 0, BCMTR_HDR_CLEAR_SIZE);

    /* Request-response or autonomous ? */
    TAILQ_INSERT_TAIL(tmsg->free_list, tmsg, l);
}

/* Unpack message. *unpacked is set=NULL in case of error */
static inline bcmos_errno _bcmtr_msg_unpack(bcmtr_conn *conn, bcmolt_buf *buf, bcmtr_hdr *hdr, uint32_t ts, bcmolt_msg **msg)
{
    int16_t err;
    uint8_t *packed = buf->curr;
    uint32_t packed_length = bcmolt_buf_get_remaining_size(buf);

    /* Unpack */
    BUG_ON(!buf->start);
    err = bcmolt_msg_unpack(buf, msg);
    if (err < 0)
    {
        BCMTR_CLD_CHECK_NOTIFY(conn->device, hdr, BCMTR_CLD_EV_RECV_DISCARD, ts, packed, packed_length, NULL);
        ++conn->stat.unpack_errors;
        return err;
    }

    BCMTR_CLD_CHECK_NOTIFY(conn->device, hdr, BCMTR_CLD_EV_RECV, ts, packed, packed_length, *msg);

    return BCM_ERR_OK;
}

/* Transport IPC release callback */
static void _bcmtr_ipc_msg_release(bcmos_msg *m)
{
    BCMOS_TRACE_ERR("We shouldn't be here!\n");
}

/* Transport IPC message handler.
 * Called in context of the target module as part
 * of dispatching message to the user task.
 * It unpacks message, releases transport header and calls user callback
 */
static void _bcmtr_ipc_msg_handler(bcmos_module_id module_id, bcmos_msg *m)
{
    bcmos_errno err;

    bcmtr_msg *tmsg = m->data;
    bcmtr_conn *conn = tmsg->conn;
    bcmolt_msg *msg = NULL;

    /* Unpack */
    err = _bcmtr_msg_unpack(conn, &tmsg->rx_buf, &tmsg->hdr, tmsg->timestamp, &msg);
    if (err != BCM_ERR_OK)
    {
        BCMOS_TRACE_ERR(
            "Unpack error for module %d. Error %s (%d)\n",
            module_id,
            bcmos_strerror(err),
            err);
        msg = NULL;
    }

    if (msg != NULL)
    {
        bcmtr_handler *h = &conn_info[conn->device].msg_handler[tmsg->hdr.msg_id][tmsg->hdr.instance];
        msg->subch = tmsg->subch;
        if (h->app_cb)
        {
            msg->corr_tag = tmsg->hdr.corr_tag;
            h->app_cb(conn->device, msg);
        }
        else
        {
            bcmolt_msg_free(msg);
            ++conn->stat.no_rx_handler;
        }
    }

    /* Release transport header under conn lock */
    bcmos_mutex_lock(&conn->mutex);
    _bcmtr_tmsg_free(tmsg, NULL);
    bcmos_mutex_unlock(&conn->mutex);
}

/* Init IPC header in transport message */
static void _bcmtr_tmsg_ipc_init(bcmtr_msg *tmsg)
{
    tmsg->ipc_hdr.start = tmsg->ipc_hdr.data = tmsg;
    tmsg->ipc_hdr.type = BCMOS_MSG_ID_INTERNAL_IPC;
    tmsg->ipc_hdr.release = _bcmtr_ipc_msg_release;
    tmsg->ipc_hdr.handler = _bcmtr_ipc_msg_handler;
}

/* Pre-allocate transport header array, put all blocks on free lists */
static int _bcmtr_tmsg_list_alloc(bcmtr_conn *conn)
{
    int n_hdr, i;
    bcmtr_msg *tmsg;

    n_hdr = conn->cfg.max_requests + conn->cfg.max_autos;
    conn->tmsg_array = bcmos_calloc(sizeof(bcmtr_msg) * n_hdr);
    if (!conn->tmsg_array)
        return BCM_ERR_NOMEM;

    tmsg = conn->tmsg_array;
    for (i=0; i<conn->cfg.max_requests; i++, tmsg++)
    {
        bcmos_errno rc;

        TAILQ_INSERT_TAIL(&conn->free_req_list, tmsg, l);
        tmsg->free_list = &conn->free_req_list;
        rc = bcmos_sem_create(&tmsg->sem, 0, 0, NULL);
        if (rc != BCM_ERR_OK)
            return rc;
        _bcmtr_tmsg_ipc_init(tmsg);
        tmsg->conn = conn;
    }
    for (i=0; i<conn->cfg.max_autos; i++, tmsg++)
    {
        TAILQ_INSERT_TAIL(&conn->free_auto_list, tmsg, l);
        tmsg->free_list = &conn->free_auto_list;
        _bcmtr_tmsg_ipc_init(tmsg);
        tmsg->conn = conn;
    }
    return BCM_ERR_OK;
}

/* Cleanup function - free transport headers */
static void _bcmtr_tmsg_list_free(bcmtr_conn *conn)
{
    bcmtr_msg *tmsg, *tmp_tmsg;

    if (!conn->tmsg_array)
        return;

    TAILQ_FOREACH_SAFE(tmsg, &conn->msg_list, l, tmp_tmsg)
    {
        bcmolt_msg *msg = tmsg->msg;
        /* Release waiting task if request-response */
        if (msg && tmsg->err == BCM_ERR_IN_PROGRESS)
        {
            msg->err = BCM_ERR_COMM_FAIL;
            bcmos_sem_post(&tmsg->sem);
        }
    }
    TAILQ_FOREACH_SAFE(tmsg, &conn->free_req_list, l, tmp_tmsg)
    {
        bcmos_sem_destroy(&tmsg->sem);
    }
    bcmos_free(conn->tmsg_array);
}

/* Allocate transport header from the given free list.
 * Must be called under lock
 */
static inline bcmtr_msg *_bcmtr_msg_get_free(bcmtr_msg_list *free_list)
{
    bcmtr_msg *tmsg = TAILQ_FIRST(free_list);
    if (tmsg)
        TAILQ_REMOVE(free_list, tmsg, l);
    return tmsg;
}

/* Find message by correlation tag
 * Called under lock
 */
static bcmtr_msg *_bcmtr_msg_get_by_corr_tag(const bcmtr_conn *conn, const bcmtr_hdr *hdr)
{
    bcmtr_msg *tmsg;

    TAILQ_FOREACH(tmsg, &conn->msg_list, l)
    {
        if (tmsg->hdr.corr_tag==hdr->corr_tag && tmsg->hdr.msg_id==hdr->msg_id && tmsg->err == BCM_ERR_IN_PROGRESS)
            break;
    }
    return tmsg;
}

/* Message reassembler. Returns TRUE if message reassembling is completed */
static bcmos_bool _bcmtr_reassemble(bcmtr_conn *conn, bcmtr_msg *tmsg, bcmolt_buf *buf)
{
    bcmtr_hdr *hdr = &tmsg->hdr;
    uint16_t frag_num = hdr->frag_number;
    bcmos_bool done = BCMOS_FALSE;
    bcmos_bool is_last;

    is_last = !hdr->more_fragments;

    /* Single-buffer message ? */
    if (is_last && !frag_num)
    {
        tmsg->rx_buf = *buf;
        tmsg->err = BCM_ERR_OK;
        buf->start = NULL;
        return BCMOS_TRUE;
    }

    /*
     * Multi-part message
     */

    /* Discard if invalid fragment number or duplicate */
    if (frag_num >= conn->cfg.max_fragments ||
        (tmsg->reass && tmsg->reass->fragments[frag_num].start) )
    {
        bcmolt_buf_free(buf);
        /* If last out-of range fragment was received report it.
         * We want to avoid request retransmission in this case */
        if (frag_num >= conn->cfg.max_fragments)
        {
            tmsg->err = BCM_ERR_TOO_MANY_FRAGS;
            return is_last;
        }
        ++conn->stat.frag_invalid;
        return BCMOS_FALSE;
    }

    /* Allocate reassembly buffer if not done yet and store fragment */
    if (!tmsg->reass)
    {
        tmsg->reass = bcmos_calloc(sizeof(bcmtr_reass) + conn->cfg.max_fragments * sizeof(bcmolt_buf));
        if (!tmsg->reass)
        {
            tmsg->err = BCM_ERR_NOMEM;
            ++conn->stat.msg_no_mem;
            bcmolt_buf_free(buf);
            return BCMOS_FALSE;
        }
        tmsg->reass->fragments = (bcmolt_buf *)((long)tmsg->reass + sizeof(bcmtr_reass));
    }
    tmsg->reass->total_size += bcmolt_buf_get_remaining_size(buf);
    tmsg->reass->fragments[frag_num] = *buf;
    buf->start = NULL;
    tmsg->reass->num_fragments++;
    if (is_last)
        tmsg->reass->max_fragment = frag_num;
    done = (tmsg->reass->max_fragment && (tmsg->reass->num_fragments > tmsg->reass->max_fragment));
    ++conn->stat.frag_received;

    /* Reassemble if done */
    if (done)
    {
        /* Allocate big flat buffer */
        if (bcmolt_buf_alloc(&tmsg->rx_buf, tmsg->reass->total_size, BCMTR_BUF_ENDIAN) == BCM_ERR_OK)
        {
            int i;
            uint8_t *body = tmsg->rx_buf.start;

            for (i=0; i<tmsg->reass->num_fragments; i++)
            {
                uint32_t frag_size = bcmolt_buf_get_remaining_size(&tmsg->reass->fragments[i]);
                BUG_ON(!tmsg->reass->fragments[i].curr);
                memcpy(body, tmsg->reass->fragments[i].curr, frag_size);
                body += frag_size;
            }
            tmsg->err = BCM_ERR_OK;
        }
        else
        {
            /* Reassembly buffer allocation failed */
            tmsg->err = BCM_ERR_NOMEM;
        }
    }
    else
    {
        /* More fragments expected. Update timestamp to prolong timing out */
        tmsg->timestamp = bcmos_timestamp();
    }

    return done;
}

/* Notify application that message is ready */
static inline void _bcmtr_notify_ready(bcmtr_conn *conn, bcmtr_msg *tmsg)
{
    bcmos_sem_post(&tmsg->sem);
}

/* Notify rx request/response message
 * called under connection lock
 */
static inline void _bcmtr_notify_rx_response(bcmtr_conn *conn, bcmtr_msg *tmsg)
{
    ++conn->stat.msg_resp_received;

    /* Now unlock and notify application. Autonomous handler is only called if message is OK.
       The lock has been taken in _bcmtr_rx_packet */
    bcmos_mutex_unlock(&conn->mutex);

    /* Release waiting application. It will take care of unpacking */
    _bcmtr_notify_ready(conn, tmsg);
}

/* Notify rx autonomous message
 * called under connection lock
 */
static inline void _bcmtr_notify_rx_req_auto(bcmtr_conn *conn, bcmtr_msg *tmsg)
{
    bcmolt_buf rx_buf;
    bcmolt_msg *msg = NULL;
    bcmolt_group_id msg_id = tmsg->hdr.msg_id;
    bcmtr_handler *h;
    uint16_t corr_tag;
    bcmtr_hdr hdr = tmsg->hdr;
    uint32_t ts = tmsg->timestamp;
    bcmolt_subchannel subch = tmsg->subch;
    bcmos_errno err;

    if (msg_id >= BCMOLT_GROUP_ID__NUM_OF)
    {
        BCMOS_TRACE_ERR("Unexpected msg group id: %u\n", tmsg->hdr.msg_id);
        _bcmtr_tmsg_free(tmsg, NULL);
        bcmos_mutex_unlock(&conn->mutex);
        return;
    }
    if (tmsg->hdr.instance >= BCMTR_MAX_INSTANCES)
    {
        BCMOS_TRACE_ERR("Unexpected instance id: %u\n", tmsg->hdr.instance);
        _bcmtr_tmsg_free(tmsg, NULL);
        bcmos_mutex_unlock(&conn->mutex);
        return;
    }
    h = &conn_info[conn->device].msg_handler[tmsg->hdr.msg_id][tmsg->hdr.instance];
    BUG_ON(!h->app_cb);
    ++conn->stat.msg_req_auto_received;

    /* If dispatch is required - do it.
     * The message will be unpacked in the context of the receiver
     */
    if ((h->flags & BCMOLT_AUTO_FLAGS_DISPATCH))
    {
        err = bcmos_msg_send_to_module(h->module, &tmsg->ipc_hdr, 0);
        if (err)
        {
            BCMOS_TRACE_ERR("Can't deliver message to module %d. Error %s(%d)\n",
                h->module, bcmos_strerror(err), err);
            _bcmtr_tmsg_free(tmsg, NULL);
        }
        bcmos_mutex_unlock(&conn->mutex);
        return;
    }

    /* No dispatch. Unpacking in the context of rx thread */
    corr_tag = tmsg->hdr.corr_tag;
    /* Make sure that rx_buf is not released by the following _bcmtr_msg_free.
     * It is needed for unpack and will be released separately later. */
    rx_buf = tmsg->rx_buf;
    tmsg->rx_buf.start = NULL;
    _bcmtr_tmsg_free(tmsg, NULL);

    /* Release connection lock taken in _bcmtr_rx_packet */
    bcmos_mutex_unlock(&conn->mutex);

    /* Unpack and deliver */
    _bcmtr_msg_unpack(conn, &rx_buf, &hdr, ts, &msg);

    bcmolt_buf_free(&rx_buf);

    if (msg)
    {
        msg->corr_tag = corr_tag;
        msg->subch = subch;
        h->app_cb(conn->device, msg);
    }
}

/* Handle rx data. Returns number of messages that was identified and reassembled. Can be 0 or 1 */
static int _bcmtr_rx_packet(bcmtr_conn *conn, bcmolt_subchannel subch, bcmolt_buf *buf)
{
    bcmtr_hdr hdr;
    bcmtr_msg *tmsg;
    bcmos_bool msg_done;
    bcmos_bool is_response;

    /* Transport lock. This lock is needed to
     * - allocate/release transport header
     * - update statistics
     */
    bcmos_mutex_lock(&conn->mutex);

    /* If some data was received - handle it */
    if (buf->len < BCMTR_HDR_SIZE)
    {
        /* Message is too short */
        ++conn->stat.msg_comm_err;
        goto rx_free_buf_and_error_exit;
    }

    if (NULL == buf->curr)
    {
        BCMOS_TRACE_ERR("Invalid buffer received!\n");
        goto rx_done;
    }

    bcmtr_header_unpack(buf->curr, &hdr);
    bcmolt_buf_skip(buf, BCMTR_HDR_SIZE);
    is_response = (hdr.dir == BCMOLT_MSG_DIR_RESPONSE);

    /* Find transport header. If not found - allocate new for autonomous message */
    tmsg = _bcmtr_msg_get_by_corr_tag(conn, &hdr);
    if (!tmsg)
    {
        if (!is_response)
        {
            /* Allocate new transport block */
            tmsg = _bcmtr_msg_get_free(&conn->free_auto_list);
            if (!tmsg)
            {
                ++conn->stat.msg_too_many_auto;
                goto rx_free_buf_and_error_exit;
            }
            tmsg->err = BCM_ERR_IN_PROGRESS;
            TAILQ_INSERT_TAIL(&conn->msg_list, tmsg, l);
        }
        else
        {
            /* Response, but no request - discard */
            ++conn->stat.msg_no_req;
            BCMTR_CLD_CHECK_NOTIFY(conn->device, &hdr, BCMTR_CLD_EV_RECV_DISCARD,
                bcmos_timestamp(), buf->curr, bcmolt_buf_get_remaining_size(buf), NULL);
            goto rx_free_buf_and_error_exit;
        }
    }

    /* Reassemble. "buf" should not be used following this call */
    tmsg->hdr = hdr;
    tmsg->subch = subch;
    msg_done = _bcmtr_reassemble(conn, tmsg, buf);

    /* If expects more parts - nothing more to do here */
    if (!msg_done)
        goto rx_done;

    if (tmsg->err && !is_response)
    {
        _bcmtr_tmsg_free(tmsg, &conn->msg_list);
        goto rx_done;
    }

    /* Done with the message. Get it out of pending message queue to avoid race condition
     * when timeout happens while the message is in flight to the destination task.
     */
    TAILQ_REMOVE(&conn->msg_list, tmsg, l);

    /* Notify rx. conn->mutex is still taken. It will be released
       inside _bcmtr_notify_rx_response(), _bcmtr_notify_rx_req_auto() */
    tmsg->timestamp = bcmos_timestamp();
    if (is_response)
    {
        _bcmtr_notify_rx_response(conn, tmsg);
    }
    else
    {
        _bcmtr_notify_rx_req_auto(conn, tmsg);
    }

    return 1;

    /* Error return */
rx_free_buf_and_error_exit:
    bcmos_mutex_unlock(&conn->mutex);
    bcmolt_buf_free(buf);
    return 0;

    /* return without a buffer */
rx_done:
    bcmos_mutex_unlock(&conn->mutex);
    return 0;
}

/*
 * Low-level fragment and send function.
 * It allocates a series of buffers up to MAX_MTU size, copies original data into them and sends.
 * The original buffer stays intact - in case it should be retransmitted
 */
static bcmos_errno _bcmtr_fragment_and_send(bcmtr_conn *conn, bcmtr_msg *tmsg, bcmtr_send_flags flags)
{
    uint32_t frag_number = 0;
    bcmos_errno err = BCM_ERR_OK;
    uint32_t data_offset = conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE;
    uint32_t data_len = bcmolt_buf_get_used(&tmsg->tx_buf) - data_offset;
    uint8_t *data = tmsg->tx_buf.start + data_offset;

    do
    {
        uint32_t send_len = data_len + BCMTR_HDR_SIZE;
        bcmolt_buf frag;

        if (send_len > conn->cfg.max_mtu)
        {
            send_len = conn->cfg.max_mtu;
            tmsg->hdr.more_fragments = BCMOS_TRUE;
        }
        else
        {
            tmsg->hdr.more_fragments = BCMOS_FALSE;
        }

        err = bcmolt_buf_alloc(&frag, send_len + conn->cfg.plugin_cfg.headroom, BCMTR_BUF_ENDIAN);
        if (err)
            break;

        tmsg->hdr.frag_number = frag_number++;

        /* Pack correlation tag, command and length */
        bcmtr_header_pack(&tmsg->hdr, frag.start + conn->cfg.plugin_cfg.headroom);
        bcmolt_buf_skip(&frag, data_offset);
        if (bcmolt_buf_write(&frag, data, send_len - BCMTR_HDR_SIZE))
        {
            /* Send using customer-provided driver */
            err = conn->driver.send(conn->drv_priv, tmsg->msg->subch, &frag, flags);
        }
        else
        {
            err = BCM_ERR_OVERFLOW;
        }
        bcmolt_buf_free(&frag);
        if (err)
        {
            break;
        }

        data_len -= (send_len - BCMTR_HDR_SIZE);
        data += (send_len - BCMTR_HDR_SIZE);

    } while (data_len);

    return err;
}

/* Check for time-outs. returns number of messages timed out */
static int _bcmtr_check_timeout(bcmtr_conn *conn)
{
    bcmtr_msg *tmsg, *tmp;
    uint32_t now;
    int nmsg = 0;
    bcmos_errno err;

    /* Transport lock */
    bcmos_mutex_lock(&conn->mutex);

    now = bcmos_timestamp();
    TAILQ_FOREACH_SAFE(tmsg, &conn->msg_list, l, tmp)
    {
        bcmolt_msg *msg = tmsg->msg;

        if (now - tmsg->timestamp <= conn->cfg.msg_timeout)
            continue;

        /* Retransmit ? */
        if (msg && tmsg->tx_count <= conn->cfg.max_retries)
        {
            tmsg->timestamp = bcmos_timestamp();
            BCMTR_CLD_CHECK_NOTIFY(
                conn->device,
                &tmsg->hdr,
                BCMTR_CLD_EV_RESEND,
                tmsg->timestamp,
                tmsg->tx_buf.start + conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE,
                tmsg->tx_buf.len - (conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE),
                msg);

            /* Fragment and send or send directly, depending on message length */
            if (bcmolt_buf_get_used(&tmsg->tx_buf) > conn->cfg.max_mtu)
            {
                err = _bcmtr_fragment_and_send(conn, tmsg, BCMTR_SEND_FLAGS_PRI_NORMAL);
            }
            else
            {
                err = conn->driver.send(conn->drv_priv, msg->subch, &tmsg->tx_buf, BCMTR_SEND_FLAGS_PRI_NORMAL);
            }
            if (err)
            {
                ++conn->stat.msg_comm_err;
            }
            ++tmsg->tx_count;
            continue;
        }

        /* Giving up */
        /* Release waiting task if request-response - unless it has already been done */
        if (msg)
        {
            if (tmsg->err == BCM_ERR_IN_PROGRESS)
            {
                tmsg->err = BCM_ERR_TIMEOUT;
            }
            BCMTR_CLD_CHECK_NOTIFY(
                conn->device,
                &tmsg->hdr,
                BCMTR_CLD_EV_TIMEOUT,
                bcmos_timestamp(),
                tmsg->tx_buf.start + conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE,
                tmsg->tx_buf.len - (conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE),
                msg);
            TAILQ_REMOVE(&conn->msg_list, tmsg, l);
            _bcmtr_notify_ready(conn, tmsg);
            ++conn->stat.msg_req_timeout;
        }
        else
        {
            _bcmtr_tmsg_free(tmsg, &conn->msg_list);
            ++conn->stat.msg_reass_timeout;
        }
        ++nmsg;
    }
    conn->last_timeout_check = bcmos_timestamp();

    /* Release transport lock */
    bcmos_mutex_unlock(&conn->mutex);

    return nmsg;
}

/* Check for receive and timeouts */
static int _bcmtr_rx_poll(bcmtr_conn *conn, int *pnmsg)
{
    bcmolt_buf buf;
    int nmsg = 0, nmsg_prev;
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_subchannel subch;

    do
    {
        nmsg_prev = nmsg;

        /* Plugin driver's recv - get pending rx packet is any.
         * The function is not allowed to block for more then BCMTR_MSG_TIMEOUT ms
         */
        rc = conn->driver.recv(conn->drv_priv, &subch, &buf);
        if (rc != BCM_ERR_OK)
        {
            if (rc == BCM_ERR_NOMEM)
            {
                ++conn->stat.msg_no_mem;
            }
        }
        else
        {
            nmsg += _bcmtr_rx_packet(conn, subch, &buf);
        }

        /* Check for timeouts if any */
        if (bcmos_timestamp() - conn->last_timeout_check > conn->timeout_check_period)
        {
            /* Check requests waiting for acknowledge and multy-part messages for timeout.
             * Timed-out requests are retransmitted.
             */
            nmsg += _bcmtr_check_timeout(conn);
        }
    } while(nmsg_prev != nmsg);

    *pnmsg = nmsg;

    return rc;
}

/* Rx thread handler */
static int _bcmtr_rx_thread_handler(long arg)
{
    bcmtr_conn *conn = (bcmtr_conn *)arg;
    int nmsgs;
    int rc;

    while(!conn->kill_request)
    {
        rc = _bcmtr_rx_poll(conn, &nmsgs);
        if (rc == BCM_ERR_COMM_FAIL)
            bcmos_usleep(1000);
    }
    conn->kill_done = 1;

    return 0;
}

/*
 * Internal transport interface
 */


/** Default message handler - discard */
static void _bcmtr_dft_msg_handler(bcmolt_devid olt, bcmolt_msg *msg)
{
    bcmtr_conn *conn = conn_info[olt].conn;

    /* ToDo: log */

    if (conn)
        ++conn->stat.no_rx_handler;

    bcmolt_msg_free(msg);
}

static bcmos_errno _bcmtr_create_rx_thread(bcmtr_conn *conn, bcmos_bool raw_mode)
{
    bcmos_errno err = BCM_ERR_OK;

    if (conn->cfg.rx_thread_priority >= 0 && !raw_mode)
    {
        bcmos_task_parm parm = {
            .priority = conn->cfg.rx_thread_priority,
            .stack_size = BCMTR_RX_THREAD_STACK,
            .handler = _bcmtr_rx_thread_handler,
            .name = conn->name,
            .data = (long)conn
        };
        conn->kill_request = BCMOS_FALSE;
        conn->kill_done = BCMOS_FALSE;
        err = bcmos_task_create(&conn->rx_thread, &parm);
        if (err == BCM_ERR_OK)
            conn->rx_thread_created = BCMOS_TRUE;
    }

    return err;
}

static void _bcmtr_destroy_rx_thread(bcmtr_conn *conn)
{
    /* Kill rx thread if any */
    if (conn->rx_thread_created)
    {
        conn->kill_request = 1;
        while(!conn->kill_done)
            bcmos_usleep(1000);
        bcmos_task_destroy(&conn->rx_thread);
    }
}

static bcmos_errno _bcmtr_connect(bcmolt_devid device, bcmtr_conn **pconn, bcmos_bool raw_mode)
{
    bcmtr_conn *conn;
    bcmos_errno err = BCM_ERR_OK;

    /* Init OS abstraction - just in case */
    err = bcmos_init();
    if (err != BCM_ERR_OK && err != BCM_ERR_ALREADY)
    {
        return err;
    }

    bcmos_mutex_lock(&conn_lock);

    /* Allocate */
    conn = bcmos_calloc(sizeof(*conn));
    if (!conn)
    {
        bcmos_mutex_unlock(&conn_lock);
        return BCM_ERR_NOMEM;
    }

    /* Get configuration */
    err = bcmtr_cfg_get(device, &conn->cfg, &conn->driver);
    if (err)
    {
        bcmos_mutex_unlock(&conn_lock);
        bcmos_free(conn);
        return err;
    }

    snprintf(conn->name, sizeof(conn->name), "tr_rx%u", device);
    TAILQ_INIT(&conn->free_req_list);
    TAILQ_INIT(&conn->free_auto_list);
    TAILQ_INIT(&conn->msg_list);
    bcmos_mutex_create(&conn->mutex, 0, NULL);

    /* Convert timeouts to us */
    conn->cfg.msg_timeout *= 1000;
    conn->cfg.msg_ready_timeout *= 1000;
    conn->cfg.msg_wait_timeout *= 1000;

    /* Set defaults */
    conn->timeout_check_period = conn->cfg.msg_wait_timeout;
    conn->last_timeout_check = bcmos_timestamp();

    /* Allocate and initialize transport blocks and put onto free request and autonomous lists */
    err = _bcmtr_tmsg_list_alloc(conn);

    /* Open/connect on driver level */
    err = err ? err : conn->driver.open(device, &conn->cfg.plugin_cfg, &conn->drv_priv);
    if (err)
    {
        bcmos_mutex_destroy(&conn->mutex);
        goto cleanup;
    }

    conn->connected = BCMOS_TRUE;

    /* Create rx thread if necessary */
    err = _bcmtr_create_rx_thread(conn, raw_mode);
    if (err)
    {
        conn->driver.close(conn->drv_priv);
        bcmos_mutex_destroy(&conn->mutex);
        goto cleanup;
    }
    conn->device = device;

    *pconn = conn;
    bcmos_mutex_unlock(&conn_lock);

    return BCM_ERR_OK;

cleanup:
    _bcmtr_tmsg_list_free(conn);
    bcmos_free(conn);
    bcmos_mutex_unlock(&conn_lock);
    return err;
}

/** Query whether or not the device is currently connected */
bcmos_errno bcmtr_is_connected(bcmolt_devid device, bcmos_bool *is_connected)
{
    bcmtr_conn *conn;
    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }
    conn = conn_info[device].conn;
    *is_connected = (conn != NULL && conn->connected);
    return BCM_ERR_OK;
}

/** Open transport channel */
bcmos_errno bcmtr_connect(bcmolt_devid device)
{
    bcmtr_conn *conn;
    return _bcmtr_conn_get(device, &conn);
}

/** Close transport channel */
bcmos_errno bcmtr_disconnect(bcmolt_devid device)
{
    bcmtr_conn *conn;

    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }
    bcmos_mutex_lock(&conn_lock);
    conn = conn_info[device].conn;
    if (!conn)
    {
        bcmos_mutex_unlock(&conn_lock);
        return BCM_ERR_NOT_CONNECTED;
    }
    conn_info[device].conn = NULL;

    /* Kill rx thread if any */
    _bcmtr_destroy_rx_thread(conn);

    bcmos_mutex_lock(&conn->mutex);
    /* Close connection */
    if (conn->driver.close)
    {
        conn->driver.close(conn->drv_priv);
    }

    /* Release all pending messages */
    bcmos_usleep(100000);
    _bcmtr_tmsg_list_free(conn);

    bcmos_mutex_unlock(&conn->mutex);
    bcmos_mutex_destroy(&conn->mutex);
    bcmos_free(conn);

    bcmos_mutex_unlock(&conn_lock);

    return BCM_ERR_OK;
}

/* Low-level disconnect that breaks "physical" connection, but doesn't destroy connection structure and registrations */
bcmos_errno bcmtr_driver_disconnect(bcmolt_devid device)
{
    bcmtr_conn *conn;
    bcmos_errno err = BCM_ERR_OK;

    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }

    bcmos_mutex_lock(&conn_lock);

    conn = conn_info[device].conn;
    if (conn == NULL || !conn->connected)
    {
        bcmos_mutex_unlock(&conn_lock);
        return BCM_ERR_NOT_CONNECTED;
    }

    _bcmtr_destroy_rx_thread(conn);

    bcmos_mutex_lock(&conn->mutex);

    /* Close driver connection */
    if (conn->driver.close != NULL)
    {
        err = conn->driver.close(conn->drv_priv);
        if (err != BCM_ERR_OK)
        {
            BCMOS_TRACE_ERR("Failed to close transport driver: %s (%d)\n", bcmos_strerror(err), err);
        }
    }

    conn->connected = BCMOS_FALSE;

    bcmos_mutex_unlock(&conn->mutex);

    bcmos_mutex_unlock(&conn_lock);

    return err;
}

/* Repair/reconnect the driver-level connection for an already-connected device */
bcmos_errno bcmtr_driver_reconnect(bcmolt_devid device)
{
    bcmtr_conn *conn;
    bcmos_errno err;

    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }
    bcmos_mutex_lock(&conn_lock);
    conn = conn_info[device].conn;
    if (conn == NULL)
    {
        bcmos_mutex_unlock(&conn_lock);
        return BCM_ERR_NOT_CONNECTED;
    }

    if (conn->connected)
    {
        bcmtr_driver_disconnect(device);
    }
    bcmos_mutex_lock(&conn->mutex);

    /* Re-open driver connection */
    err = conn->driver.open(device, &conn->cfg.plugin_cfg, &conn->drv_priv);
    if (err != BCM_ERR_OK)
    {
        BCMOS_TRACE_ERR("Failed to re-open transport driver: %s (%d)\n", bcmos_strerror(err), err);
    }

    err = _bcmtr_create_rx_thread(conn, BCMOS_FALSE);
    if (err != BCM_ERR_OK)
    {
        BCMOS_TRACE_ERR("Failed to create RX transport task: %s (%d)\n", bcmos_strerror(err), err);
        conn->driver.close(conn->drv_priv);
    }
    conn->connected = BCMOS_TRUE;

    bcmos_mutex_unlock(&conn->mutex);

    bcmos_mutex_unlock(&conn_lock);

    return err;
}

/* Register for notification that transmit failed because tx_queue was full */
bcmos_errno bcmtr_tx_overflow_cb_register(bcmolt_devid device, F_bcmtr_tx_overflow cb)
{
    if (device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_RANGE;
    }

    conn_info[device].overflow_cb = cb;
    return BCM_ERR_OK;
}

/* Send message.
 * Internal function. Called under connection lock
 */
static bcmos_errno _bcmtr_send(bcmtr_conn *conn, bcmolt_msg *msg, bcmolt_buf *tx_buf, bcmtr_send_flags flags, bcmtr_msg **ptmsg)
{
    bcmtr_msg *tmsg;
    bcmos_errno err;

    if (!conn->connected)
    {
        ++conn->stat.not_connected;
        return BCM_ERR_NOT_CONNECTED;
    }

    /* Allocate message transport header */
    tmsg = _bcmtr_msg_get_free(&conn->free_req_list);
    if (!tmsg)
    {
        ++conn->stat.msg_no_mem;
        return BCM_ERR_TOO_MANY_REQS;
    }
    tmsg->msg = msg;

    /* Fill transport header */
    err = bcmtr_header_fill(tmsg->msg, &tmsg->hdr);
    if (err)
        return err;

    tmsg->err = BCM_ERR_IN_PROGRESS;
    tmsg->tx_count = 1;

    /* Save transmit buffer. It will be released together with transport header */
    tmsg->tx_buf = *tx_buf;

    tmsg->timestamp = bcmos_timestamp();

    if (bcmolt_buf_get_used(tx_buf) > conn->cfg.max_mtu)
    {
        err = _bcmtr_fragment_and_send(conn, tmsg, flags);
    }
    else
    {
        /* Pack correlation tag, command and length */
        bcmtr_header_pack(&tmsg->hdr, tmsg->tx_buf.start + conn->cfg.plugin_cfg.headroom);

        /* Send using customer-provided driver */
        err = conn->driver.send(conn->drv_priv, msg->subch, &tmsg->tx_buf, flags);
    }
    BCMTR_CLD_CHECK_NOTIFY(
        conn->device,
        &tmsg->hdr,
        BCMTR_CLD_EV_SEND,
        tmsg->timestamp,
        tmsg->tx_buf.start + conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE,
        tmsg->tx_buf.len - (conn->cfg.plugin_cfg.headroom + BCMTR_HDR_SIZE),
        msg);
    if (err != BCM_ERR_OK)
    {
        ++conn->stat.msg_comm_err;
        goto cleanup;
    }

    tx_buf->start = NULL; /* Ownership passed to tmsg */
    ++conn->stat.msg_sent;

    if (ptmsg)
    {
        *ptmsg = tmsg;
    }
    else
    {
        _bcmtr_tmsg_free(tmsg, NULL);
    }

    return BCM_ERR_OK;

    /* error */
cleanup:
    tmsg->tx_buf.start = NULL; /* prevent tx buffer de-allocation */
    _bcmtr_tmsg_free(tmsg, NULL);
    return err;
}


/* Allocate tx buffer and pack */
static bcmos_errno _bcmtr_pack(const bcmtr_conn *conn, bcmolt_msg *msg, bcmolt_buf *buf)
{
    int32_t len = bcmolt_msg_get_packed_length(msg);
    uint32_t headroom = conn->cfg.plugin_cfg.headroom;
    bcmos_errno err;

    if (len < 0)
        return (bcmos_errno)len;

    /* Reallocate if too big */
    len += BCMTR_HDR_SIZE + headroom;
    if (buf->start)
    {
        if (buf->len < len)
        {
            /* ToDo: reallocate */
            return BCM_ERR_OVERFLOW;
        }
        else
        {
            bcmolt_buf_init(buf, len, buf->start, BCMTR_BUF_ENDIAN);
        }
    }
    else
    {
        err = bcmolt_buf_alloc(buf, len, BCMTR_BUF_ENDIAN);
        if (err)
        {
            return err;
        }
    }

    /* Reserve room for header */
    buf->curr = buf->start + BCMTR_HDR_SIZE + headroom;

    /* Pack */
    err = bcmolt_msg_pack(msg, buf);

    return err;
}

/*
 * External message interface
 */

/* Send message. Don't expect response. */
bcmos_errno bcmtr_send(bcmolt_devid device, bcmolt_msg *msg, bcmtr_send_flags flags)
{
    bcmtr_conn *conn;
    bcmos_errno err;
    bcmolt_buf tx_buf = {};

    err = _bcmtr_conn_get(device, &conn);
    if (err)
        return err;

    /* Allocate transport buffer and pack */
    err = _bcmtr_pack(conn, msg, &tx_buf);
    if (err)
    {
        bcmolt_buf_free(&tx_buf);
        return err;
    }

    bcmos_mutex_lock(&conn->mutex);
    err = _bcmtr_send(conn, msg, &tx_buf, flags, NULL);
    bcmos_mutex_unlock(&conn->mutex);
    if (err)
    {
        bcmolt_buf_free(&tx_buf);
        if (err == BCM_ERR_QUEUE_FULL && conn_info[device].overflow_cb)
            conn_info[device].overflow_cb(conn->device, flags);
    }

    return err;
}

static bcmos_errno bcmtr_call_err(bcmolt_msg *msg, bcmos_errno err, const char *err_text)
{
    msg->dir = BCMOLT_MSG_DIR_RESPONSE;
    msg->err = err;
    if (err_text != NULL)
    {
        strncpy(msg->err_text, err_text, BCMOLT_MAX_ERR_TEXT_LENGTH-1);
        msg->err_text[BCMOLT_MAX_ERR_TEXT_LENGTH-1] = 0;
    }
    return err;
}

/* Send message and wait for response */
bcmos_errno bcmtr_call(bcmolt_devid device, bcmolt_msg *msg)
{
    static uint32_t corr_tag = 0;
    bcmos_task *task;
    bcmtr_msg *tmsg = NULL;
    bcmtr_conn *conn;
    bcmolt_buf tx_buf = {};
    bcmos_errno err;
    uint8_t instance;

    msg->err = BCM_ERR_OK;
    msg->dir = BCMOLT_MSG_DIR_REQUEST;
    msg->corr_tag = ++corr_tag;

    err = _bcmtr_conn_get(device, &conn);
    if (err)
    {
        return bcmtr_call_err(msg, err, NULL);
    }

    /* prevent sleeping in RX thread (this would cause it to never wake up) */
    task = bcmos_task_current();
    if (task == &conn->rx_thread)
    {
        return bcmtr_call_err(msg, BCM_ERR_COMM_FAIL, "Cannot call API functions from PCI RX thread");
    }

    instance = bcmolt_msg_instance(msg);
    if (instance >= BCMTR_MAX_INSTANCES)
    {
        return bcmtr_call_err(msg, BCM_ERR_KEY_RANGE, "Invalid PON index");
    }

    /* Allocate transport buffer and pack */
    err = _bcmtr_pack(conn, msg, &tx_buf);
    if (err)
    {
        bcmolt_buf_free(&tx_buf);
        return bcmtr_call_err(msg, err, NULL);
    }

    /* transmit request under connection lock */
    bcmos_mutex_lock(&conn->mutex);
    err = _bcmtr_send(conn, msg, &tx_buf, BCMTR_SEND_FLAGS_CALL, &tmsg);
    if (!tmsg)
    {
        bcmos_mutex_unlock(&conn->mutex);
        bcmolt_buf_free(&tx_buf);
        return bcmtr_call_err(msg, err, NULL);
    }
    TAILQ_INSERT_TAIL(&conn->msg_list, tmsg, l);
    bcmos_mutex_unlock(&conn->mutex);

    /* Wait for response or timeout.
     * Message timeout is enforced by audit rather than semaphore timeout option
     */
    bcmos_sem_wait(&tmsg->sem, BCMOS_WAIT_FOREVER);

    /* Connection could've been killed while we are waiting here.
     * It is indicated by COMM_FAILURE in msg->err.
     * In this case transport header (tmsg) is already released
     */
    if (msg->err == BCM_ERR_COMM_FAIL)
    {
        return bcmtr_call_err(msg, msg->err, NULL);
    }

    err = tmsg->err;
    if (!err)
    {
        err = _bcmtr_msg_unpack(conn, &tmsg->rx_buf, &tmsg->hdr, tmsg->timestamp, &msg);
    }

    /* Take connection lock again in order to release transport header safely */
    bcmos_mutex_lock(&conn->mutex);
    _bcmtr_tmsg_free(tmsg, NULL);
    bcmos_mutex_unlock(&conn->mutex);

    return bcmtr_call_err(msg, err ? err : msg->err, NULL);
}


#ifdef BCM_SUBSYSTEM_HOST
/* Send (un)registration info to the mux */
static bcmos_errno _bcmtr_send_to_mux(bcmtr_conn *conn, bcmtr_hdr *hdr)
{
    bcmolt_buf buf;
    uint8_t packed_hdr[BCMTR_HDR_SIZE];
    bcmos_errno err;

    err = bcmolt_buf_alloc(&buf, BCMTR_HDR_SIZE + conn->cfg.plugin_cfg.headroom, BCMTR_BUF_ENDIAN);
    if (err)
    {
        return err;
    }
    bcmolt_buf_skip(&buf, conn->cfg.plugin_cfg.headroom);
    bcmtr_header_pack(hdr, packed_hdr);
    if (bcmolt_buf_write(&buf, packed_hdr, BCMTR_HDR_SIZE))
        err = conn->driver.send(conn->drv_priv, 0, &buf, BCMTR_SEND_FLAGS_PRI_NORMAL);
    else
        err = BCM_ERR_OVERFLOW;
    bcmolt_buf_free(&buf);
    return err;
}
#endif

/** Register message handler
 *
 * \param[in]   device          OLT device index
 * \param[in]   parm            Registration parameters
 * \returns BCM_ERR_OK or error code
 */
bcmos_errno bcmtr_msg_handler_register(bcmolt_devid device, const bcmtr_handler_parm *parm)
{
    bcmtr_conn *conn;
    bcmos_errno err = BCM_ERR_OK;
    bcmolt_group_id msg_id;
    bcmtr_handler *h;

    if (device >= BCMTR_MAX_OLTS || !parm || !parm->app_cb || parm->instance >= BCMTR_MAX_INSTANCES)
    {
        return BCM_ERR_PARM;
    }

    if ((unsigned)parm->object >= BCMOLT_OBJ_ID__NUM_OF)
    {
        bcmtr_handler_parm p1 = *parm;

        for (p1.object = 0; p1.object < BCMOLT_OBJ_ID__NUM_OF && !err; p1.object++)
        {
            err = bcmtr_msg_handler_register(device, &p1);
            /* Ignore RANGE error that indicates that the object being iterated doesn't have this group */
            /* Ignore ALREADY error that indicates that registration is already present for specific message and was skipped */
            if ((err == BCM_ERR_RANGE) || (err == BCM_ERR_ALREADY))
            {
                err = BCM_ERR_OK;
            }
        }
        return err;
    }

    if ((unsigned)parm->subgroup == BCMOLT_SUBGROUP_ANY)
    {
        bcmtr_handler_parm p1 = *parm;

        for (p1.subgroup = 0;
            bcmolt_group_id_combine(p1.object, p1.group, p1.subgroup, &msg_id) == BCM_ERR_OK &&
                (err == BCM_ERR_OK || err == BCM_ERR_ALREADY);
            p1.subgroup++)
        {
            err = bcmtr_msg_handler_register(device, &p1);
        }
        if (err == BCM_ERR_ALREADY)
        {
            err = BCM_ERR_OK;
        }
        return err;
    }

    /* Specific object/group/subgroup */
    err = bcmolt_group_id_combine(parm->object, parm->group, parm->subgroup, &msg_id);
    if (err)
        return err;
    h = &conn_info[device].msg_handler[msg_id][parm->instance];

    /* Refuse new registration if already registered */
    if (h->app_cb != _bcmtr_dft_msg_handler)
    {
        return BCM_ERR_ALREADY;
    }

    h->app_cb = parm->app_cb;
    h->flags = parm->flags;
    if ((parm->flags & BCMOLT_AUTO_FLAGS_DISPATCH))
    {
        if (parm->module != BCMOS_MODULE_ID_NONE)
        {
            h->module = parm->module;
        }
        else
        {
            h->module = bcmos_module_current();
        }
    }
    else
    {
        h->module = BCMOS_MODULE_ID_NONE;
    }

#ifdef BCM_SUBSYSTEM_HOST
    /* On the host, automatically connect on message handler registration */
    err = _bcmtr_conn_get(device, &conn);
    if (err)
        return err;

    /* Registration with tr-mux is per device, per-instance, per-object */
    if (!parm->subgroup)
    {
        /* Send registration info to the mux driver. It is just a header */
        bcmtr_hdr hdr;
        memset(&hdr, 0, sizeof(hdr));
        hdr.msg_id = msg_id;
        hdr.auto_proxy_reg = 1;
        hdr.instance = parm->instance;
        err = _bcmtr_send_to_mux(conn, &hdr);
        if (err)
        {
            bcmtr_msg_handler_unregister(device, parm);
        }
    }
#else
    (void)conn;
#endif

    return err;
}

/* Unregister autonomous message handler */
bcmos_errno bcmtr_msg_handler_unregister(bcmolt_devid device, const bcmtr_handler_parm *parm)
{
    bcmtr_conn *conn;
    bcmos_errno err = BCM_ERR_OK;
    bcmolt_group_id msg_id;
    bcmtr_handler *h;

    if (device >= BCMTR_MAX_OLTS || !parm || parm->instance >= BCMTR_MAX_INSTANCES)
    {
        return BCM_ERR_PARM;
    }

    if ((unsigned)parm->object >= BCMOLT_OBJ_ID__NUM_OF)
    {
        bcmtr_handler_parm p1 = *parm;
        for (p1.object = 0; p1.object < BCMOLT_OBJ_ID__NUM_OF && !err; p1.object++)
        {
            err = bcmtr_msg_handler_unregister(device, &p1);
            /* Ignore RANGE error that indicates that the object being iterated doesn't have this group */
            if (err == BCM_ERR_RANGE)
            {
                err = BCM_ERR_OK;
            }
        }
        return err;
    }

    if ((unsigned)parm->subgroup == BCMOLT_SUBGROUP_ANY)
    {
        bcmtr_handler_parm p1 = *parm;

        for (p1.subgroup = 0;
            bcmolt_group_id_combine(p1.object, p1.group, p1.subgroup, &msg_id) == BCM_ERR_OK && !err;
            p1.subgroup++)
        {
            err = bcmtr_msg_handler_unregister(device, &p1);
        }
        return err;
    }

    err = bcmolt_group_id_combine(parm->object, parm->group, parm->subgroup, &msg_id);
    if (err)
        return err;

    h = &conn_info[device].msg_handler[msg_id][parm->instance];
    h->app_cb = _bcmtr_dft_msg_handler;
    h->flags = BCMOLT_AUTO_FLAGS_NONE;
    h->module = BCMOS_MODULE_ID_NONE;

#ifdef BCM_SUBSYSTEM_HOST
    /* On the host, automatically connect on message handler (de)registration */
    err = _bcmtr_conn_get(device, &conn);
    if (err)
        return err;

    /* Registration with tr-mux is per device, per-instance, per-object */
    if (!parm->subgroup)
    {
        /* Send un-registration info to the mux driver. It is just a header */
        bcmtr_hdr hdr;
        memset(&hdr, 0, sizeof(hdr));
        hdr.msg_id = msg_id;
        hdr.auto_proxy_unreg = 1;
        hdr.instance = parm->instance;
        err = _bcmtr_send_to_mux(conn, &hdr);
    }
#else
    (void)conn;
#endif

    return err;
}

/** Get registration info
 *
 * \param[in]           device          OLT device index
 * \param[in,out]       parm            Registration parameters.
 *                                      instance, group, object, subgroup must be set
 * \returns BCM_ERR_OK or error code
 */
bcmos_errno bcmtr_msg_handler_register_get(bcmolt_devid device, bcmtr_handler_parm *parm)
{
    bcmos_errno err;
    bcmolt_group_id msg_id;
    bcmtr_handler *h;

    if (device >= BCMTR_MAX_OLTS ||
        !parm ||
        parm->instance >= BCMTR_MAX_INSTANCES ||
        (unsigned)parm->object >= BCMOLT_OBJ_ID__NUM_OF ||
        (unsigned)parm->subgroup == BCMOLT_SUBGROUP_ANY)
    {
        return BCM_ERR_PARM;
    }

    err = bcmolt_group_id_combine(parm->object, parm->group, parm->subgroup, &msg_id);
    if (err)
        return err;

    h = &conn_info[device].msg_handler[msg_id][parm->instance];
    parm->app_cb = (h->app_cb == _bcmtr_dft_msg_handler) ? NULL : h->app_cb;
    parm->flags = h->flags;
    parm->module = h->module;

    return BCM_ERR_OK;
}

/* Get transport statistics */
bcmos_errno bcmtr_stat_get(bcmolt_devid device, bcmtr_stat *stat)
{
    bcmtr_conn *conn;
    bcmos_errno err;

    if (!stat)
    {
        return BCM_ERR_PARM;
    }
    err = _bcmtr_conn_get(device, &conn);
    if (err)
    {
        return err;
    }
    bcmos_mutex_lock(&conn->mutex);
    *stat = conn->stat;
    memset(&conn->stat, 0, sizeof(conn->stat));
    bcmos_mutex_unlock(&conn->mutex);

    return BCM_ERR_OK;
}

#if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) && defined(BCM_SUBSYSTEM_EMBEDDED) && defined(BCMTR_UDP_SUPPORT)
static int _bcmtr_assign_random_port(void)
{
    int port;

    srand(bcmos_timestamp());
    port = rand() % 50000;
    if (port < 20000)
    {
        port += 20000;
    }

    return port;
}
#endif

/* Connect device in raw mode. Receive task is NOT created */
bcmos_errno bcmtr_proxy_connect(bcmolt_devid device, uint32_t *headroom)
{
    bcmtr_conn *conn;
    bcmos_errno rc;

    rc = _bcmtr_conn_get_any(device, &conn, BCMOS_TRUE);
    if (!rc)
    {
        *headroom = conn->cfg.plugin_cfg.headroom;
    }
    return rc;
}

/* Send data to device in raw mode */
bcmos_errno bcmtr_proxy_send(bcmolt_devid device, bcmolt_buf *tx_buf)
{
    bcmtr_conn *conn;
    bcmos_errno rc;
    rc = _bcmtr_conn_get_any(device, &conn, BCMOS_TRUE);
    if (rc)
        return rc;
    rc = conn->driver.send(conn->drv_priv, 0, tx_buf, BCMTR_SEND_FLAGS_NONE);
    return rc;
}

/* Receive data from device in raw mode */
bcmos_errno bcmtr_proxy_receive(bcmolt_devid device, bcmolt_buf *rx_buf)
{
    bcmtr_conn *conn;
    bcmolt_subchannel subch;
    bcmos_errno rc;
    rc = _bcmtr_conn_get_any(device, &conn, BCMOS_TRUE);
    if (rc)
        return rc;
    rc = conn->driver.recv(conn->drv_priv, &subch, rx_buf);
    return rc;
}

/** Initialize transport library.
 * \returns BCM_ERR_OK or error code
 */
bcmos_errno bcmtr_init(void)
{
    bcmos_errno err = BCM_ERR_OK;
    bcmolt_devid device;

    bcmos_printf("bcmtr_init: init transport library\n");

#if defined(BCMTR_UDP_SUPPORT)

    /* Set defaults and add configuration command */
    if (!bcmtr_host_ip)
        bcmtr_host_ip = BCMTR_TR_UDP_HOST_IP;
    if (!bcmtr_host_udp_port)
        bcmtr_host_udp_port = BCMTR_TR_UDP_HOST_PORT;
    for (device = 0; device < BCMTR_MAX_OLTS; device++)
    {
        if (!bcmtr_olt_ip[device])
            bcmtr_olt_ip[device] = BCMTR_TR_UDP_OLT_IP + device;
        if (!bcmtr_olt_udp_port[device])
            bcmtr_olt_udp_port[device] = BCMTR_TR_UDP_OLT_PORT;
    }

    /* A hack to allow multiple simulations run on the same PC */
#if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) && defined(BCM_SUBSYSTEM_EMBEDDED)
    {
        bcmtr_olt_udp_port[0] = _bcmtr_assign_random_port();
    }
#endif
#endif

    /* Initialize handlers */
    for (device = 0; device < BCMTR_MAX_OLTS; device++)
    {
        bcmolt_group_id group;
        for (group = 0; group < BCMOLT_GROUP_ID__NUM_OF; group++)
        {
            int inst;
            for (inst = 0; inst < BCMTR_MAX_INSTANCES; inst++)
            {
                conn_info[device].msg_handler[group][inst].app_cb = _bcmtr_dft_msg_handler;
            }
        }
    }

    bcmos_mutex_create(&conn_lock, 0, NULL);

    return err;
}

/** Release resources used by transport library.
 * \returns BCM_ERR_OK or error code
 */
bcmos_errno bcmtr_exit(void)
{
    int i;

    for (i = 0; i < BCMTR_MAX_OLTS; i++)
        bcmtr_disconnect(i);

    bcmos_mutex_destroy(&conn_lock);

    return BCM_ERR_OK;
}
