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

:>
 */

/*
 * bcmtr_mux.c
 *
 * Transport Multiplexer
 * - PCIe/in-band channel multiplexer
 * - locally/remotely - terminated message multiplexer
 * - autonomous messages de-multiplexer
 */
#include <bcmos_system.h>
#include <bcmolt_msg.h>
#include <bcmolt_buf.h>
#include <bcmolt_msg_pack.h>
#include <bcmtr_header.h>
#include <bcmolt_tr_mux.h>
#ifdef IN_BAND
#include <bcmtr_inband.h>
#else
#include <bcmtr_pcie.h>
#include <bcmolt_llpcie.h>
#include <bcmolt_fld.h>
#include <bcm_fld_common.h>
#include <bcmtr_pcie_sw_queue.h>
#endif
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcmolt_model_ids.h>

#define BCMTRMUX_MAX_TX_DELAY   500     /* max transmit delay (us) */
#define BCMTRMUX_MAX_RX_DELAY   5000    /* max receive delay (us) */

#ifdef __KERNEL__
#define BCMTRMUX_LOG printk
#else
#define BCMTRMUX_LOG BCMOS_TRACE_INFO
#endif

/* Channel registration info */
typedef struct
{
    f_bcmtr_rx_handler rx;
    void *data;
} bcmtrmux_rx_info;

typedef struct
{
    f_bcmtr_local_rx_handler rx;
    void *data;
} bcmtrmux_local_rx_info;

/* Registration arrays */
static bcmtrmux_rx_info bcmtrmux_rx_info_array[BCMTR_MAX_OLTS][BCMTRMUX_MAX_CHANNELS];
static bcmtrmux_local_rx_info bcmtrmux_local_rx_info_array[BCMTR_MAX_OLTS];
static bcmtrmux_channel bcmtrmux_auto_channels[BCMTR_MAX_OLTS][BCMTR_MAX_INSTANCES][BCMOLT_OBJ_ID__NUM_OF];
static bcmtrmux_channel bcmtrmux_proxy_channels[BCMTR_MAX_OLTS][BCMTR_MAX_INSTANCES][BCMOLT_OBJ_ID__NUM_OF];
static bcmos_bool bcmtr_mux_connected[BCMTR_MAX_OLTS];
static bcmos_bool bcmtr_mux_terminated[BCMTR_MAX_OLTS];
static bcmos_bool bcmtrmux_dev_ctrl_intercept[BCMTR_MAX_OLTS][BCMOLT_GROUP_ID__NUM_OF];

#ifndef IN_BAND

/* Number of registered high-priority channels */
static bcmtrmux_channel num_urgent_channels[BCMTR_MAX_OLTS];

/* Receive semaphore */
static bcmos_sem bcmtrmux_rx_lock[BCMTR_MAX_OLTS];

#endif

/* Statistics */
static bcmtrmux_stat bcmtrmux_stat_array[BCMTR_MAX_OLTS];

/* Receive tasks */
static bcmos_task bcmtrmux_rx_task[BCMTR_MAX_OLTS];

/* Registration protection */
static bcmos_fastlock bcmtrmux_lock;

static void bcmtrmux_rx_auto_proxy(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data);
static void bcmtrmux_rx_local(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data);

static bcmtrmux_msg_filter_cb_t bcmtrmux_msg_filter_cb;

/* discard packet for which there is no registration */
static void bcmtrmux_rx_discard(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data)
{
    uint32_t *counter = (uint32_t *)data;
    ++(*counter);
    bcmos_buf_free(buf);
}

/* discard unpacked message for which there is no registration */
static void bcmtrmux_local_rx_discard(bcmolt_devid device, bcmolt_msg *msg, void *data)
{
    uint32_t *counter = (uint32_t *)data;
    ++(*counter);
    bcmolt_msg_free(msg);
}

/* Find free channel. returns channel id >= 0 or BCMTRMUX_MAX_CHANNELS if no free channels */
static int bcmtrmux_channel_get_free(bcmolt_devid device)
{
    int i;
    /* Start from BCMTRMUX_CHANNEL_FIRST_FREE. Channel 0 is reserved for indications/proxy , Channel 1 is for Keep Alive*/
    for (i=BCMTRMUX_CHANNEL_FIRST_FREE; i<BCMTRMUX_FIRST_URGENT_CHANNEL; i++)
    {
        if (bcmtrmux_rx_info_array[device][i].rx == bcmtrmux_rx_discard)
            break;
    }
    return i;
}

#ifndef IN_BAND
/* PCIe Receive handler */
static int _bcmtrmux_pcie_rx_handler(long device)
{
    bcmos_errno rc;
    bcmos_buf *buf;
    uint32_t nbuf[BCMTR_PCIE_PRTY__NUM_OF] = {};
    uint8_t ch;

    BUG_ON(device >= BCMTR_MAX_OLTS);

    BCMTRMUX_LOG("rx_task(%ld) - started\n", device);

    /* Enable rx interrupt */

    while (1)
    {
        bcmtr_pcie_rxint_enable(device);
        bcmos_sem_wait(&bcmtrmux_rx_lock[device], BCMTRMUX_MAX_RX_DELAY);

        if (!bcmtr_mux_connected[device])
        {
            break;
        }
        /* Wait for receive */
        do
        {
            buf = NULL;
            rc = bcmtr_swq_receive(device, BCMTR_PCIE_PRTY_NORMAL, &ch, &buf);
            if (rc)
            {
                /* If DMA is not shared with urgent service, poll RXQ here,
                 * don't wait for interrupt
                 */
                if (rc == BCM_ERR_QUEUE_EMPTY && !num_urgent_channels[device])
                {
                    bcmtr_pcie_rxint_disable(device);
                    bcmtr_swq_rx_poll(device, nbuf);
                    bcmtrmux_stat_array[device].rx_poll_normal += nbuf[BCMTR_PCIE_PRTY_NORMAL];
                }
                /* Wait for interrupt or semaphore timeout */
                break;
            }
            bcmtrmux_rx_from_line((bcmolt_devid)device, (bcmtrmux_channel)ch, buf);
        } while (bcmtr_mux_connected[device]);
    }
    BCMTRMUX_LOG("rx_task(%ld) - terminated\n", device);
    bcmtr_mux_terminated[device] = BCMOS_TRUE;

    return 0;
}

static void bcmtrmux_rx_irq(bcmolt_devid device)
{
    bcmos_buf *buf;
    uint8_t ch;
    uint32_t nbuf[BCMTR_PCIE_PRTY__NUM_OF] = {};

    bcmtr_pcie_rxint_disable(device);
    bcmtr_pcie_rxint_clear(device);
    bcmtr_swq_rx_poll(device, nbuf);

    /* Got some packets. Deliver high priority from interrupt level */
    if (nbuf[BCMTR_PCIE_PRTY_URGENT])
    {
        bcmtrmux_stat_array[device].rx_poll_urgent += nbuf[BCMTR_PCIE_PRTY_URGENT];
        while (bcmtr_swq_receive(device, BCMTR_PCIE_PRTY_URGENT, &ch, &buf) == BCM_ERR_OK)
        {
            bcmtrmux_rx_from_line(device, ch, buf);
        }
    }

    /* Check normal priority */
    if (nbuf[BCMTR_PCIE_PRTY_NORMAL])
    {
        bcmtrmux_stat_array[device].rx_poll_normal += nbuf[BCMTR_PCIE_PRTY_NORMAL];
        bcmos_sem_post(&bcmtrmux_rx_lock[device]);
    }

    /* Enable rx interrupt */
    bcmtr_pcie_rxint_enable(device);

    return;
}

/* Tx confirmation interrupt handler.
 * Used only if there are urgent channels
 */
static void bcmtrmux_tx_irq(bcmolt_devid device)
{
    /* Disable and clear transmit completion interrupts */
    bcmtr_pcie_txint_disable(device);
    bcmtr_pcie_txint_clear(device);
    /* Submit buffers pending in sw queue to the h/w queue */
    bcmtr_swq_tx_submit(device);
    /* Re-enable tx completion interrupt */
    bcmtr_pcie_txint_enable(device);
    return;
}

/* Init PCIE transport */
static bcmos_errno bcmtrmux_pcie_init(bcmolt_devid device, uint32_t txq_size, uint32_t rxq_size)
{
    uint32_t pcie_cookie[BCMOS_ROUND_UP(PCIE_OPAQUE_DATA_SIZE, sizeof(uint32_t))/sizeof(uint32_t)];
    bcmtr_pcie_pre_connect_cfg cfg;
    bcm_ll_dev_info ll_info;
    int niter = 0;
    bcmos_errno err;
    bcmos_bool status;

#ifndef SIMULATION_BUILD
    err = bcm_ll_pcie_query(device, &ll_info);
    if (err)
    {
        BCMOS_TRACE_RETURN(err, "bcm_ll_pcie_query() failed\n");
    }
#endif

    BCMTRMUX_LOG("Waiting for BCM68620 application\n");
    bcm_fld_set_rings_size(device, txq_size, rxq_size);
    status = bcm_fld_test_device_bootrecord_flag(device);

    /* Wait for embedded handshake. BCMTR_PCIE_START_TIMEOUT is in ms */
    for (niter = 0;
         niter < BCMTR_PCIE_START_TIMEOUT / 10 && !(status = bcm_fld_test_device_bootrecord_flag(device));
         niter++)
    {
        bcmos_usleep(10000);
    }
    if (!status)
    {
        BCMOS_TRACE_RETURN(BCM_ERR_IO, "BCM68620 application timeout\n");
    }

    err = bcm_fld_get_device_bootrecord(device, pcie_cookie);
    if (err != BCM_ERR_OK)
    {
        BCMOS_TRACE_RETURN(err, "bcm_fld_get_device_bootrecord() failed\n");
    }

    /* set host prm bit - indicate host ready to send/receive DMA */
    bcm_fld_clear_device_bootrecord_flag(device);

    cfg.txq_size = txq_size;             /* Transmit queue size */
    cfg.rxq_size = rxq_size;             /* Receive queue size */
    cfg.max_mtu = BCMTR_MAX_MTU_SIZE;    /* Max MTU size */
    cfg.pcie_reg_base = ll_info.soc_regs_base;
    cfg.ddr_win_base = ll_info.soc_ddr_base;
    cfg.rx_irq = ll_info.irq;

    err = bcmtr_pcie_pre_connect(device, &cfg, (bcmtr_pcie_opaque_data *)pcie_cookie);
    if (err)
    {
        BCMOS_TRACE_RETURN(err, "bcmtr_pcie_pre_connect() failed\n");
    }

    err = bcmtr_pcie_connect(device,(bcmtr_pcie_opaque_data *)pcie_cookie);
    if (err)
    {
        BCMOS_TRACE_RETURN(err, "bcmtr_pcie_connect() failed\n");
    }

    bcm_fld_set_host_bootrecord_flag(device);

    /* Wait for embedded handshake. BCMTR_PCIE_CONNECT_TIMEOUT is in ms */
    for (niter = 0;
         niter < BCMTR_PCIE_CONNECT_TIMEOUT / 10 && (status = bcm_fld_test_host_bootrecord_flag(device));
         niter++)
    {
        bcmos_usleep(10000);
    }
    if (status)
    {
        BCMOS_TRACE_RETURN(BCM_ERR_IO, "BCM68620 connect timeout\n");
    }

    BCMTRMUX_LOG("PCI transport: initialized\n");

    return BCM_ERR_OK;
}

#else /* #ifndef IN_BAND */

/* IN-BAND receive handler */
static int _bcmtrmux_ib_rx_handler(long device)
{
    bcmos_errno rc;
    bcmos_buf *buf;
    uint8_t ch;

    BUG_ON(device >= BCMTR_MAX_OLTS);

    BCMTRMUX_LOG("rx_task(%ld) - started\n", device);

    while (bcmtr_mux_connected[device])
    {
        /* Wait for receive */
        buf = NULL;
        rc = bcmtr_ib_receive(device, &ch, &buf);
        if (rc == BCM_ERR_OK)
        {
            bcmtrmux_rx_from_line((bcmolt_devid)device, (bcmtrmux_channel)ch, buf);
        }
    }

    BCMTRMUX_LOG("rx_task(%ld) - terminated\n", device);
    bcmtr_mux_terminated[device] = BCMOS_TRUE;

    return 0;
}

static bcmos_errno bcmtrmux_ib_connect(bcmolt_devid device,  bcmos_ipv4_address ip_address, uint16_t udp_port)
{
    bcmos_errno rc;

    rc = bcmtr_ib_connect((uint8_t)device, ip_address, udp_port);
    if (rc)
    {
        BCMTRMUX_LOG("%s: Failed to connect. Error %d\n", __FUNCTION__, rc);
        return rc;
    }
    return rc;
}

#endif /* #ifndef IN_BAND */


/** Initialize mux service
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtrmux_init(bcmtrmux_msg_filter_cb_t msg_filter_cb)
{
    static bcmos_bool initialized = BCMOS_FALSE;
    int i, j;
    bcmos_errno rc;

    bcmtrmux_msg_filter_cb = msg_filter_cb;

    BCMTRMUX_LOG("Initialising transport MUX subsystem\n");
    if (initialized)
    {
        return BCM_ERR_ALREADY;
    }

    for (i=0; i<BCMTR_MAX_OLTS; i++)
    {
        for (j=0; j<BCMTRMUX_MAX_CHANNELS; j++)
        {
            bcmtrmux_rx_info_array[i][j].rx = bcmtrmux_rx_discard;
            bcmtrmux_rx_info_array[i][j].data = &bcmtrmux_stat_array[i].rx_disc_remote;
        }
        bcmtrmux_rx_info_array[i][BCMTRMUX_CHANNEL_AUTO_PROXY].rx = bcmtrmux_rx_auto_proxy;
        bcmtrmux_rx_info_array[i][BCMTRMUX_CHANNEL_AUTO_PROXY].data = NULL;
        bcmtrmux_rx_info_array[i][BCMTRMUX_CHANNEL_DEV_CONTROL].rx = bcmtrmux_rx_local;
        bcmtrmux_rx_info_array[i][BCMTRMUX_CHANNEL_DEV_CONTROL].data = NULL;
        for (j=0; j<BCMTR_MAX_INSTANCES; j++)
        {
            bcmolt_obj_id k;
            for (k=0; k<BCMOLT_OBJ_ID__NUM_OF; k++)
            {
                bcmtrmux_auto_channels[i][j][k] = BCMTRMUX_MAX_CHANNELS;
                bcmtrmux_proxy_channels[i][j][k] = BCMTRMUX_MAX_CHANNELS;
            }
        }
        bcmtrmux_local_rx_info_array[i].rx = bcmtrmux_local_rx_discard;
        bcmtrmux_local_rx_info_array[i].data = &bcmtrmux_stat_array[i].tx_disc_local;
    }

    bcmos_fastlock_init(&bcmtrmux_lock, 0);

    /*Don't initialize at this time for User Space dev ctrl,
      don't have enough information*/
#ifndef IN_BAND
    rc = bcmtr_pcie_init(BCMTR_MAX_OLTS);
    if (rc)
    {
        BCMOS_TRACE_RETURN(rc, "bcmtr_pcie_init() failed\n");
    }

    rc = bcmtr_swq_init();
    if (rc)
    {
        BCMOS_TRACE_RETURN(rc, "bcmtr_swq_init() failed\n");
    }

    /* Register rx callback in PCIe driver */
    bcmtr_pcie_rx_irq_cblk_register(bcmtrmux_rx_irq);
    bcmtr_pcie_tx_irq_cblk_register(bcmtrmux_tx_irq);
#else

    rc = bcmtr_ib_init();
    if (rc)
    {
        BCMOS_TRACE_RETURN(rc, "bcmtr_ib_init() failed\n");
    }

#endif /* #ifndef IN_BAND */

    BCMTRMUX_LOG("Transport MUX init done\n");

    return rc;
}

/** Notify mux driver that low-level transport connection is ready
 * \returns: 0 in case of success or error code < 0
 */
#ifdef IN_BAND
bcmos_errno bcmtrmux_connect(bcmolt_devid device,  bcmos_ipv4_address ip_address, uint16_t udp_port)
#else
bcmos_errno bcmtrmux_connect(bcmolt_devid device, uint32_t txq_size, uint32_t rxq_size)
#endif
{
    static char task_name[BCMTR_MAX_OLTS][16];
    bcmos_task_parm taskp = {};
    bcmos_errno rc;

    if (bcmtr_mux_connected[device])
    {
        return BCM_ERR_ALREADY;
    }

    snprintf(task_name[device], sizeof(task_name[device]), "bcmtr_rx%d", device);
    taskp.data = (long)device;
    taskp.name = task_name[device];

#ifdef IN_BAND
    rc = bcmtrmux_ib_connect(device, ip_address, udp_port);
    if (rc)
    {
        BCMTRMUX_LOG("%s: Failed to init inband device. Error %d\n", __FUNCTION__, rc);
        return rc;
    }
    taskp.handler = _bcmtrmux_ib_rx_handler;
#else
    rc = bcmos_sem_create(&bcmtrmux_rx_lock[device], 0, 0, NULL);
    if (rc)
    {
        BCMTRMUX_LOG("%s: Failed to create rx lock. Error %d\n", __FUNCTION__, rc);
        return rc;
    }

    /* Initialize low-level PCIe transport */
    rc = bcmtrmux_pcie_init(device, txq_size, rxq_size);
    if (rc)
    {
        bcmos_sem_destroy(&bcmtrmux_rx_lock[device]);
        BCMTRMUX_LOG("%s: Failed to init low-level PCIe transport. Error %d\n", __FUNCTION__, rc);
        return rc;
    }
    taskp.handler = _bcmtrmux_pcie_rx_handler;

    rc = bcmtr_swq_device_init(device);
    if (rc)
    {
        bcmos_sem_destroy(&bcmtrmux_rx_lock[device]);
        BCMTRMUX_LOG("%s: Failed to init pcie_swq. Error %d\n", __FUNCTION__, rc);
        return rc;
    }

#endif
    bcmtr_mux_connected[device] = BCMOS_TRUE;
    bcmtr_mux_terminated[device] = BCMOS_FALSE;

    rc = bcmos_task_create(&bcmtrmux_rx_task[device], &taskp);
    if (rc)
    {
#ifndef IN_BAND
        bcmos_sem_destroy(&bcmtrmux_rx_lock[device]);
#endif
        bcmtr_mux_connected[device] = BCMOS_FALSE;
        BCMTRMUX_LOG("%s: Failed to create rx task. Error %d\n", __FUNCTION__, rc);
        return rc;
    }

    return BCM_ERR_OK;
}

/** Notify mux driver that low-level transport connection is disconnected
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtrmux_disconnect(bcmolt_devid device)
{
    if (!bcmtr_mux_connected[device])
    {
        return BCM_ERR_ALREADY;
    }
    bcmtr_mux_connected[device] = BCMOS_FALSE;
#ifdef IN_BAND
    bcmtr_ib_disconnect((uint8_t)device);
#else
    bcmos_sem_post(&bcmtrmux_rx_lock[device]);
#endif
    while (!bcmtr_mux_terminated[device])
    {
        bcmos_usleep(10000);
    }
    bcmos_task_destroy(&bcmtrmux_rx_task[device]);
#ifndef IN_BAND
    bcmos_sem_destroy(&bcmtrmux_rx_lock[device]);
    bcmtr_swq_device_exit(device);
    bcmtr_pcie_disconnect((uint8_t)device);
#endif
    return BCM_ERR_OK;
}

/** Cleanup and exit
 */
void bcmtrmux_exit(void)
{
    int i;

    BCMTRMUX_LOG("Cleaning up transport MUX subsystem\n");
#ifndef IN_BAND
    bcmtr_swq_exit();
    bcmtr_pcie_rx_irq_cblk_unregister();
    bcmtr_pcie_tx_irq_cblk_unregister();
#endif
    /* kill receive tasks */
    for (i=0; i<BCMTR_MAX_OLTS; i++)
    {
        bcmtrmux_disconnect((bcmolt_devid)i);
    }
#ifdef IN_BAND
    bcmtr_ib_exit();
#else
    bcmtr_pcie_exit();
#endif
    BCMTRMUX_LOG("Transport MUX cleanup done\n");
}

/** Register PCIe channel owner */
bcmos_errno bcmtrmux_channel_register(bcmolt_devid device, bcmtrmux_channel *channel,
    f_bcmtr_rx_handler rx, void *data)
{
    bcmtrmux_channel ch;
    long flags;

    if ((unsigned)device >= BCMTR_MAX_OLTS || !channel || !rx)
    {
        return BCM_ERR_PARM;
    }
    ch = *channel;

    flags = bcmos_fastlock_lock(&bcmtrmux_lock);

    if (ch == BCMTRMUX_CHANNEL_AUTO_ASSIGN)
    {
        /* Auto-assign free channel */
        ch = (bcmtrmux_channel)bcmtrmux_channel_get_free(device);
        if (ch >= BCMTRMUX_MAX_CHANNELS)
        {
            bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
            return BCM_ERR_NORES;
        }
    }

    /* Make sure that channel is valid and not busy */
    if ((unsigned)ch >= BCMTRMUX_MAX_CHANNELS)
    {
        bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
        return BCM_ERR_PARM;
    }
    if (bcmtrmux_rx_info_array[device][ch].rx != bcmtrmux_rx_discard)
    {
        bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
        return BCM_ERR_ALREADY;
    }

    /* Assign channel */
    bcmtrmux_rx_info_array[device][ch].rx = rx;
    bcmtrmux_rx_info_array[device][ch].data = data;

#ifndef IN_BAND
    /* Urgent channels are not supported for IN-BAND management */
    if (ch >= BCMTRMUX_FIRST_URGENT_CHANNEL)
    {
        /* We use transmit confirmation interrupt to kick transmission
         * if PCI bus is shared between high and low-priority channels
         */
        if (!num_urgent_channels[device])
            bcmtr_pcie_txint_enable(device);
        ++num_urgent_channels[device];
    }
#endif

    bcmos_fastlock_unlock(&bcmtrmux_lock, flags);

    *channel = ch;

    return BCM_ERR_OK;
}


/** Release PCIe channel allocated by bcmtrmux_channel_register()
 *
 * \param[in]   device  Maple device index
 * \param[in]   channel
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtrmux_channel_unregister(bcmolt_devid device, bcmtrmux_channel channel)
{
    long flags;

    if ((unsigned)device >= BCMTR_MAX_OLTS || (unsigned)channel >= BCMTRMUX_MAX_CHANNELS)
    {
        return BCM_ERR_PARM;
    }

    flags = bcmos_fastlock_lock(&bcmtrmux_lock);

    if (bcmtrmux_rx_info_array[device][channel].rx == bcmtrmux_rx_discard)
    {
        bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
        return BCM_ERR_NOENT;
    }

    bcmtrmux_rx_info_array[device][channel].rx = bcmtrmux_rx_discard;
    bcmtrmux_rx_info_array[device][channel].data = &bcmtrmux_stat_array[device].rx_disc_remote;

#ifndef IN_BAND
    /* Urgent channels are not supported for IN-BAND management */
    if (channel >= BCMTRMUX_FIRST_URGENT_CHANNEL)
    {
        --num_urgent_channels[device];
        /* If PCI bus is not shared between normal and urgent channels,
         * transmit confirmation mechanism is not needed
         */
        if (!num_urgent_channels[device])
            bcmtr_pcie_txint_disable(device);
    }
#endif

    bcmos_fastlock_unlock(&bcmtrmux_lock, flags);

    return BCM_ERR_OK;
}

/*
 * Local termination handler
 */

/* Register local termination handler. */
bcmos_errno bcmtrmux_local_handler_register(bcmolt_devid device, f_bcmtr_local_rx_handler rx, void *data)
{
    long flags;

    if ((unsigned)device >= BCMTR_MAX_OLTS || !rx)
    {
        return BCM_ERR_PARM;
    }
    flags = bcmos_fastlock_lock(&bcmtrmux_lock);
    if (bcmtrmux_local_rx_info_array[device].rx != bcmtrmux_local_rx_discard)
    {
        bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
        return BCM_ERR_ALREADY;
    }
    bcmtrmux_local_rx_info_array[device].rx = rx;
    bcmtrmux_local_rx_info_array[device].data = data;
    bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
    return BCM_ERR_OK;
}


/* Unregister local termination handler registered by bcmtrmux_local_handler_register() */
bcmos_errno bcmtrmux_local_handler_unregister(bcmolt_devid device)
{
    long flags;

    if ((unsigned)device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_PARM;
    }
    flags = bcmos_fastlock_lock(&bcmtrmux_lock);
    if (bcmtrmux_local_rx_info_array[device].rx == bcmtrmux_local_rx_discard)
    {
        bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
        return BCM_ERR_NOENT;
    }
    bcmtrmux_local_rx_info_array[device].data = &bcmtrmux_stat_array[device].tx_disc_local;
    bcmtrmux_local_rx_info_array[device].rx = bcmtrmux_local_rx_discard;
    bcmos_fastlock_unlock(&bcmtrmux_lock, flags);
    return BCM_ERR_OK;
}

/* Deliver message to local destination */
static bcmos_bool bcmtrmux_deliver_to_local(bcmolt_devid device, bcmtrmux_channel channel, bcmos_buf *buf, bcmtr_hdr *hdr)
{
    bcmtrmux_local_rx_info *rx_info;
    bcmolt_msg *msg = NULL;
    bcmolt_buf ubuf;
    bcmos_errno err;

    /* Unpack */
    bcmolt_buf_init(&ubuf, bcmos_buf_length(buf), bcmos_buf_data(buf), BCMTR_BUF_ENDIAN);
    bcmolt_buf_skip(&ubuf, BCMTR_HDR_SIZE);
    err = bcmolt_msg_unpack(&ubuf, &msg);
    bcmos_buf_free(buf);
    if (err < 0)
    {
        BCMOS_TRACE_ERR("Message unpack error %s (%d)\n", bcmos_strerror(err), err);
        ++bcmtrmux_stat_array[device].tx_disc_local;
        return BCMOS_TRUE;
    }
    msg->corr_tag = hdr->corr_tag;
    msg->subch = (bcmolt_subchannel)channel;
    ++bcmtrmux_stat_array[device].tx_local;

    rx_info = &bcmtrmux_local_rx_info_array[device];
    rx_info->rx(device, msg, rx_info->data);
    return BCMOS_TRUE;
}

/* send to line with repetitive attempts if pcie buffer is full */
static void bcmtrmux_send_to_line(bcmolt_devid device, bcmtrmux_channel channel, bcmos_buf *buf)
{
    bcmos_errno rc;

#ifdef IN_BAND
    rc = bcmtr_ib_send((uint8_t)device, (uint8_t)channel, buf);
#else
    rc = bcmtr_swq_send((uint8_t)device, channel, buf);
#endif
    if (rc != BCM_ERR_OK)
    {
        /* Failed */
        ++bcmtrmux_stat_array[device].tx_disc_remote;
        bcmos_buf_free(buf);
    }
}

/* Receive message from host application */
void bcmtrmux_rx_from_host(bcmolt_devid device, bcmtrmux_channel channel, bcmos_buf *buf)
{
    bcmtr_hdr hdr;
    bcmolt_obj_id obj;
    bcmolt_mgt_group group;
    uint16_t subgroup;
    bcmos_errno rc;

    /* Validate parameters */
    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);
    BUG_ON((unsigned)channel >= BCMTRMUX_MAX_CHANNELS);

    /* Peek in transport header. It contains enough info to decide what to do with the message */
    bcmtr_header_unpack(bcmos_buf_data(buf), &hdr);

    rc = bcmolt_group_id_split(hdr.msg_id, &obj, &group, &subgroup);
    if (rc)
    {
        BCMOS_TRACE_ERR("Can't decode group_id %u. Error %s (%d)\n", hdr.msg_id, bcmos_strerror(rc), rc);
        ++bcmtrmux_stat_array[device].tx_disc_remote;
        bcmos_buf_free(buf);
        return;
    }

    /* Filter auto/proxy (un)registration.
     * This message is terminated here.
     */
    if (hdr.auto_proxy_reg || hdr.auto_proxy_unreg)
    {
        bcmtrmux_channel *p_ch = (group == BCMOLT_MGT_GROUP_AUTO) ?
            &bcmtrmux_auto_channels[device][hdr.instance][obj] : &bcmtrmux_proxy_channels[device][hdr.instance][obj];

        bcmos_buf_free(buf);

        /* Sanity check */
        if (hdr.instance >= BCMTR_MAX_INSTANCES || obj >= BCMOLT_OBJ_ID__NUM_OF)
        {
            BCMOS_TRACE_ERR("Instance %u or object %d is insane\n", hdr.instance, obj);
            return;
        }

        /* Do not override bcmolt_dev_ctrl filters */
        if (*p_ch != BCMTRMUX_CHANNEL_DEV_CONTROL)
        {
            *p_ch = hdr.auto_proxy_reg ? channel : BCMTRMUX_MAX_CHANNELS;
        }

        return;
    }

    /* Filter message that should go to local destination (device control) */
    if (bcmtrmux_msg_filter_cb && bcmtrmux_msg_filter_cb(device, obj, group, subgroup) == BCMTRMUX_DEST_LOCAL)
    {
        if (bcmtrmux_deliver_to_local(device, channel, buf, &hdr) == BCMOS_TRUE)
            return;
    }

    /* Handle Remote message */
    ++bcmtrmux_stat_array[device].tx_remote;
    bcmtrmux_send_to_line(device, channel, buf);
}


/* Receive packet from the line or local control process.
 * Parameters are expected to be checked beforehand.
 * The function de-muxes
 * - replies based on channel
 * - autonomous/proxy messages based on registration info
 */
static void bcmtrmux_rx(bcmolt_devid device, bcmtrmux_channel channel, bcmos_buf *buf)
{
    bcmtrmux_rx_info *rx_info;
    rx_info = &bcmtrmux_rx_info_array[device][channel];
    rx_info->rx(device, buf, channel, rx_info->data);
}


/* Receive packet from PCIe interface */
void bcmtrmux_rx_from_line(bcmolt_devid device, bcmtrmux_channel channel, bcmos_buf *buf)
{
    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);

    if ((unsigned)channel >= BCMTRMUX_MAX_CHANNELS)
    {
        ++bcmtrmux_stat_array[device].rx_disc_inv_ch;
        bcmos_buf_free(buf);
        return;
    }

    ++bcmtrmux_stat_array[device].rx_remote;

    bcmtrmux_rx(device, channel, buf);
}

/* Handle message received via Auto/Proxy channel */
static void bcmtrmux_rx_auto_proxy(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data)
{
    bcmtr_hdr hdr;
    bcmolt_obj_id obj;
    bcmolt_mgt_group group;
    uint16_t subgroup;
    bcmos_errno rc;

    /* Peek in transport header. It contains enough info to decide what to do with the message */
    bcmtr_header_unpack(bcmos_buf_data(buf), &hdr);

    rc = bcmolt_group_id_split(hdr.msg_id, &obj, &group, &subgroup);
    if (rc)
    {
        BCMOS_TRACE_ERR("Can't decode group_id %u. Error %s (%d)\n", hdr.msg_id, bcmos_strerror(rc), rc);
        ++bcmtrmux_stat_array[device].rx_disc_auto;
        bcmos_buf_free(buf);
        return;
    }

    /* Sanity check */
    if (hdr.instance >= BCMTR_MAX_INSTANCES || obj >= BCMOLT_OBJ_ID__NUM_OF)
    {
        BCMOS_TRACE_ERR("Instance %u or object %d is insane\n", hdr.instance, obj);
        ++bcmtrmux_stat_array[device].rx_disc_auto;
        bcmos_buf_free(buf);
        return;
    }

    /* Dispatch based on object id */
    /* Handle dev_ctrl intercept */
    if (bcmtrmux_dev_ctrl_intercept[device][hdr.msg_id])
    {
        channel = BCMTRMUX_CHANNEL_DEV_CONTROL;
    }
    else
    {
        channel = (group == BCMOLT_MGT_GROUP_AUTO) ?
            bcmtrmux_auto_channels[device][hdr.instance][obj] : bcmtrmux_proxy_channels[device][hdr.instance][obj];
    }

    /* If no registration - discard */
    if (channel >= BCMTRMUX_MAX_CHANNELS)
    {
        ++bcmtrmux_stat_array[device].rx_disc_auto;
        bcmos_buf_free(buf);
        return;
    }
    bcmtrmux_rx(device, channel, buf);
}

/* Handle message received via DEV_CONTROL channel */
static void bcmtrmux_rx_local(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data)
{
    bcmtrmux_local_rx_info *rx_info;
    bcmtr_hdr hdr;
    bcmolt_buf ubuf;
    bcmolt_msg *msg = NULL;
    bcmos_errno err;

    bcmtr_header_unpack(bcmos_buf_data(buf), &hdr);

    bcmolt_buf_init(&ubuf, bcmos_buf_length(buf), bcmos_buf_data(buf), BCMTR_BUF_ENDIAN);
    bcmolt_buf_skip(&ubuf, BCMTR_HDR_SIZE);
    err = bcmolt_msg_unpack(&ubuf, &msg);
    bcmos_buf_free(buf);
    if (err < 0)
    {
        BCMOS_TRACE_ERR("Message unpack error %s (%d)\n", bcmos_strerror(err), err);
        ++bcmtrmux_stat_array[device].rx_disc_remote;
        return;
    }

    msg->corr_tag = hdr.corr_tag;
    msg->subch = (bcmolt_subchannel)channel;
    ++bcmtrmux_stat_array[device].rx_local;

    rx_info = &bcmtrmux_local_rx_info_array[device];
    rx_info->rx(device, msg, rx_info->data);
}

static bcmos_errno bcmtrmux_msg_pack(bcmolt_devid device, bcmolt_msg *msg, bcmos_buf **p_buf)
{
    int32_t len = bcmolt_msg_get_packed_length(msg);
    bcmos_buf *buf;
    bcmolt_buf ubuf;
    bcmos_errno rc = BCM_ERR_OK;
    bcmtr_hdr thdr = {};

    if (len < 0)
    {
        BCMOS_TRACE_ERR("Can't calculate packet length. Error %s (%d)\n", bcmos_strerror(rc), len);
        return BCM_ERR_PARM;
    }
    rc = bcmtr_header_fill(msg, &thdr);
    if (rc)
    {
        BCMOS_TRACE_ERR("Can't create transport header. Error %s (%d)\n", bcmos_strerror(rc), rc);
        return BCM_ERR_PARM;
    }

    len += BCMTR_HDR_SIZE;
    buf = bcmos_buf_alloc(len);
    if (!buf)
    {
        BCMOS_TRACE_ERR("Can't allocate packet buffer\n");
        return BCM_ERR_NOMEM;
    }
    bcmolt_buf_init(&ubuf, len, bcmos_buf_data(buf), BCMTR_BUF_ENDIAN);
    bcmolt_buf_skip(&ubuf, BCMTR_HDR_SIZE);

    /* Pack transport header */
    bcmtr_header_pack(&thdr, ubuf.start);

    /* Pack message */
    rc = bcmolt_msg_pack(msg, &ubuf);
    if (rc)
    {
        BCMOS_TRACE_ERR("Message pack failed. Error %s (%d)\n", bcmos_strerror(rc), rc);
        bcmos_buf_free(buf);
        return BCM_ERR_PARM;
    }
    bcmos_buf_length_set(buf, len);

    *p_buf = buf;

    return BCM_ERR_OK;
}

/* Send packet from local control process to the host application */
bcmos_errno bcmtrmux_control_to_host(bcmolt_devid device, bcmolt_msg *msg)
{
    bcmtrmux_channel channel = (bcmtrmux_channel)msg->subch;
    bcmos_buf *buf;
    bcmos_errno rc;

    BUG_ON((unsigned)channel >= BCMTRMUX_MAX_CHANNELS);
    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);

    ++bcmtrmux_stat_array[device].control_to_host;

    rc = bcmtrmux_msg_pack(device, msg, &buf);
    if (rc)
    {
        return rc;
    }
    bcmtrmux_rx(device, channel, buf);
    return BCM_ERR_OK;
}

/* Send packet from local control process to the embedded system */
bcmos_errno bcmtrmux_control_to_line(bcmolt_devid device, bcmolt_msg *msg)
{
    bcmos_buf *buf;
    bcmos_errno err;

    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);

    ++bcmtrmux_stat_array[device].control_to_line;

    err = bcmtrmux_msg_pack(device, msg, &buf);
    if (err)
    {
        return err;
    }

    bcmtrmux_send_to_line(device, BCMTRMUX_CHANNEL_DEV_CONTROL, buf);

    return err;
}

/* Register message for intercept by bcmolt_dev_ctrl */
bcmos_errno bcmtrmux_control_auto_intercept_filter(bcmolt_devid device,  bcmolt_obj_id object, uint16_t subgroup)
{
    bcmos_errno err;
    bcmolt_group_id msg_id;

    if ((unsigned)device >= BCMTR_MAX_OLTS)
    {
        return BCM_ERR_PARM;
    }
    err = bcmolt_group_id_combine(object, BCMOLT_MGT_GROUP_AUTO, subgroup, &msg_id);
    if (err)
    {
        BCMOS_TRACE_ERR("Can't identify operation %d for object %d. Error %s (%d)\n",
            (int)subgroup, (int)object, bcmos_strerror(err), err);
        return err;
    }
    bcmtrmux_dev_ctrl_intercept[device][msg_id] = BCMOS_TRUE;
    return BCM_ERR_OK;
}


/** Get transport mux statistics.
 *
 * \param[in]   device  Maple device index
 * \param[out]  stat    Statistics
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtrmux_stat_get(bcmolt_devid device, bcmtrmux_stat *stat)
{
    if ((unsigned)device >= BCMTR_MAX_OLTS || !stat)
    {
        return BCM_ERR_PARM;
    }
    *stat = bcmtrmux_stat_array[device];
    return BCM_ERR_OK;
}

#ifdef __KERNEL__

EXPORT_SYMBOL(bcmtrmux_init);
EXPORT_SYMBOL(bcmtrmux_connect);
EXPORT_SYMBOL(bcmtrmux_disconnect);
EXPORT_SYMBOL(bcmtrmux_channel_register);
EXPORT_SYMBOL(bcmtrmux_channel_unregister);
EXPORT_SYMBOL(bcmtrmux_local_handler_register);
EXPORT_SYMBOL(bcmtrmux_local_handler_unregister);
EXPORT_SYMBOL(bcmtrmux_rx_from_host);
EXPORT_SYMBOL(bcmtrmux_rx_from_line);
EXPORT_SYMBOL(bcmtrmux_control_to_host);
EXPORT_SYMBOL(bcmtrmux_control_to_line);
EXPORT_SYMBOL(bcmtrmux_control_auto_intercept_filter);
EXPORT_SYMBOL(bcmtrmux_stat_get);

#endif
