/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *
 *     Copyright (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 <bcm_dev_log.h>
#include <bcmolt_math.h>
#include "bcm_topo.h"

#define BCM_TOPO_MAX_LINE_SIZE 256
#define BCM_TOPO_MAX_NNI_DEVICES 1

uint32_t g_max_nni_ports[BCM_TOPO_MAX_NNI_DEVICES] = {BCM_TOPO_MAX_NNI_PORTS};

typedef struct bcm_topo_dev_context_t bcm_topo_dev_context_t;

typedef struct
{
    bcm_topo_dev_context_t *dev; /* Back pointer to the physical device this PON belongs to */
    bcmos_bool is_initialized;
    uint32_t pon_id;
    uint32_t logical_pon;
    bcm_topo_pon_mode pon_mode;
    uint32_t max_num_of_onus;
    void *contexts[BCM_TOPO_PON_CONTEXT_ID__NUM_OF]; /* User context - 1 entry per user */
} bcm_topo_pon_context_t;

struct bcm_topo_dev_context_t
{
    bcm_topo_pon_mode pon_mode; /* Currently we do not allow more than one PON mode per device (e.g: GPONx8 + XGPONx4) */
    bcmos_bool is_initialized;
    uint32_t device_id;
    uint32_t max_num_of_pons;
    bcm_topo_pon_context_t pons[BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV];
};

typedef struct
{
    bcmos_bool is_initialized;
    bcm_topo_dev_context_t devs[BCM_TOPO_MAX_NUM_OF_DEVS];
    bcm_topo_pon_context_t *logical_pon2physical_pon[BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS];
} bcm_topo_context_t;

static bcm_topo_context_t bcm_topo_context;

#ifdef ENABLE_LOG
static dev_log_id topo_log_id = DEV_LOG_INVALID_ID;
#endif

static int2str_t pon_mode2str[] =
{
    {BCM_TOPO_PON_MODE_GPON, "gpon"},
    {BCM_TOPO_PON_MODE_XGPON, "xgpon"},
    {BCM_TOPO_PON_MODE_XGS, "xgs"},
    {BCM_TOPO_PON_MODE_EPON_TDMA, "epon_tdma"},
    {BCM_TOPO_PON_MODE_EPON_1G, "epon_1g"},
    {BCM_TOPO_PON_MODE_EPON_10G, "epon_10g"},
    {-1},
};

static int2int_t pon_mode2max_num_of_pons[] =
{
    {BCM_TOPO_PON_MODE_GPON, 16},
    {BCM_TOPO_PON_MODE_XGPON, 8},
    {BCM_TOPO_PON_MODE_XGS, 2},
    {BCM_TOPO_PON_MODE_EPON_TDMA, 8},
    {BCM_TOPO_PON_MODE_EPON_1G, 16},
    {BCM_TOPO_PON_MODE_EPON_10G, 8},
    {-1},
};

const char *bcm_topo_dev_get_pon_mode_str(bcmolt_devid device_id)
{
    return int2str(pon_mode2str, bcm_topo_context.devs[device_id].pon_mode);
}

int bcm_topo_dev_get_max_pon(bcmolt_devid device_id)
{
    return int2int(pon_mode2max_num_of_pons, bcm_topo_context.devs[device_id].pon_mode);
}

bcm_topo_pon_mode bcm_topo_pon_get_pon_mode(uint32_t pon)
{
    bcmolt_devid device_id;
    uint32_t physical_pon;
    bcmos_errno rc;

    rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
    if (rc != BCM_ERR_OK)
        return BCM_TOPO_PON_MODE_INVALID;

    return bcm_topo_context.devs[device_id].pons[physical_pon].pon_mode;
}

bcm_topo_pon_family bcm_topo_pon_get_pon_family(uint32_t pon)
{
    switch (bcm_topo_pon_get_pon_mode(pon))
    {
    case BCM_TOPO_PON_MODE_GPON:
    case BCM_TOPO_PON_MODE_XGPON:
    case BCM_TOPO_PON_MODE_XGS:
        return BCM_TOPO_PON_FAMILY_GPON;
    case BCM_TOPO_PON_MODE_EPON_TDMA:
    case BCM_TOPO_PON_MODE_EPON_1G:
    case BCM_TOPO_PON_MODE_EPON_10G:
        return BCM_TOPO_PON_FAMILY_EPON;
    default:
        return BCM_TOPO_PON_FAMILY_INVALID;
    }
}

bcm_topo_pon_sub_family bcm_topo_pon_get_pon_sub_family(uint32_t pon)
{
    switch (bcm_topo_pon_get_pon_mode(pon))
    {
    case BCM_TOPO_PON_MODE_GPON:
        return BCM_TOPO_PON_SUB_FAMILY_GPON;
    case BCM_TOPO_PON_MODE_XGPON:
    case BCM_TOPO_PON_MODE_XGS:
        return BCM_TOPO_PON_SUB_FAMILY_XGPON;
    case BCM_TOPO_PON_MODE_EPON_TDMA:
    case BCM_TOPO_PON_MODE_EPON_1G:
    case BCM_TOPO_PON_MODE_EPON_10G:
        return BCM_TOPO_PON_SUB_FAMILY_EPON;
    default:
        return BCM_TOPO_PON_SUB_FAMILY_INVALID;
    }
}

uint32_t bcm_topo_pon_get_max_num_of_onus(uint32_t pon)
{
    bcmolt_devid device_id;
    uint32_t physical_pon;
    bcmos_errno rc;

    rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
    if (rc != BCM_ERR_OK)
        return BCM_TOPO_ERR_INVALID;

    return bcm_topo_context.devs[device_id].pons[physical_pon].max_num_of_onus;
}

bcmos_bool bcm_topo_pon_is_valid(uint32_t pon)
{
    bcmolt_devid device_id;
    uint32_t physical_pon;

    if (bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon) != BCM_ERR_OK)
        return BCMOS_FALSE;

    return BCMOS_TRUE;
}

bcmolt_devid bcm_topo_dev_get_next(bcmolt_devid device_id)
{
    if (device_id == BCM_TOPO_DEV_INVALID)
        device_id = 0;
    else
        device_id++;

    for (; device_id < BCM_TOPO_MAX_NUM_OF_DEVS && !bcm_topo_context.devs[device_id].is_initialized; device_id++);

    return device_id == BCM_TOPO_MAX_NUM_OF_DEVS ? BCM_TOPO_DEV_INVALID : device_id;
}

uint32_t bcm_topo_pon_get_next(bcmolt_devid device_id, uint32_t pon)
{
    uint32_t physical_pon;
    bcmos_errno rc;

    if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
    {
        BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
        return BCM_TOPO_PON_INVALID;
    }

    if (pon == BCM_TOPO_PON_INVALID)
        physical_pon = 0;
    else
    {
        bcmolt_devid dummy;

        rc = bcm_topo_pon_get_logical2physical(pon, &dummy, &physical_pon);
        if (rc != BCM_ERR_OK)
        {
            return BCM_TOPO_PON_INVALID;
        }
        else
        {
            physical_pon++;
        }
    }

    if (physical_pon < bcm_topo_context.devs[device_id].max_num_of_pons)
    {
        rc = bcm_topo_pon_get_physical2logical(device_id, physical_pon, &pon);
        if (rc != BCM_ERR_OK)
        {
            return BCM_TOPO_PON_INVALID;
        }
        else
        {
            return pon;
        }
    }

    return BCM_TOPO_PON_INVALID;
}

bcmos_errno bcm_topo_pon_get_logical2physical(uint32_t logical_pon, bcmolt_devid *device_id, uint32_t *physical_pon)
{
    if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
    {
        BCM_LOG(ERROR, topo_log_id, "Logical PON ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
        return BCM_ERR_RANGE;
    }

    if (!bcm_topo_context.logical_pon2physical_pon[logical_pon])
    {
        BCM_LOG(ERROR, topo_log_id, "Logical PON=%u was not associated with a physical PON\n", logical_pon);
        return BCM_ERR_RANGE;
    }

    *physical_pon = bcm_topo_context.logical_pon2physical_pon[logical_pon]->pon_id;
    *device_id = bcm_topo_context.logical_pon2physical_pon[logical_pon]->dev->device_id;

    return BCM_ERR_OK;
}

bcmos_errno bcm_topo_pon_get_physical2logical(bcmolt_devid device_id, uint32_t physical_pon, uint32_t *logical_pon)
{
    if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
    {
        BCM_LOG(ERROR, topo_log_id, "Device ID must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS - 1);
        return BCM_ERR_RANGE;
    }

    if (physical_pon >= bcm_topo_context.devs[device_id].max_num_of_pons)
    {
        BCM_LOG(ERROR, topo_log_id, "Physical PON ID must be in the range 0 .. %u\n", bcm_topo_context.devs[device_id].max_num_of_pons - 1);
        return BCM_ERR_RANGE;
    }

    if (bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon == BCM_TOPO_PON_INVALID)
    {
        BCM_LOG(ERROR, topo_log_id, "Physical PON=%u on device=%u was not associated with a logical PON\n", physical_pon, device_id);
        return BCM_ERR_RANGE;
    }

    *logical_pon = bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon;

    return BCM_ERR_OK;
}

bcmos_errno bcm_topo_pon_set_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id, void *context)
{
    bcmolt_devid device_id;
    uint32_t physical_pon;
    bcmos_errno rc;

    if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
    {
        BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
        return BCM_ERR_RANGE;
    }

    rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
    if (rc != BCM_ERR_OK)
        return rc;

    bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id] = context;

    return BCM_ERR_OK;
}

void *bcm_topo_pon_get_context(uint32_t pon, bcm_topo_pon_context_id pon_context_id)
{
    bcmolt_devid device_id;
    uint32_t physical_pon;
    bcmos_errno rc;

    if (pon_context_id >= BCM_TOPO_PON_CONTEXT_ID__NUM_OF)
    {
        BCM_LOG(ERROR, topo_log_id, "Invalid PON context ID\n");
        return NULL;
    }

    rc = bcm_topo_pon_get_logical2physical(pon, &device_id, &physical_pon);
    if (rc != BCM_ERR_OK)
        return NULL;

    return bcm_topo_context.devs[device_id].pons[physical_pon].contexts[pon_context_id];
}

static void bcm_topo_init_context(void)
{
    uint32_t device_id;

    for (device_id = 0; device_id < BCM_TOPO_MAX_NUM_OF_DEVS; device_id++)
    {
        bcm_topo_dev_context_t *dev;
        uint32_t pon_id;

        dev = &bcm_topo_context.devs[device_id];
        dev->device_id = device_id;
        dev->pon_mode = BCM_TOPO_PON_MODE_INVALID;
        for (pon_id = 0; pon_id < BCM_TOPO_MAX_NUM_OF_PONS_PER_DEV; pon_id++)
        {
            bcm_topo_pon_context_t *pon;

            pon = &dev->pons[pon_id];
            pon->dev = dev;
            pon->pon_id = pon_id;
            pon->pon_mode = BCM_TOPO_PON_MODE_INVALID;
            pon->logical_pon = BCM_TOPO_PON_INVALID;
        }
    }
}

static bcmos_errno bcm_topo_init_line_parse(const char *line, const char *filename, uint32_t line_num, bcmos_bool *is_skipped, uint32_t *logical_pon, bcm_topo_pon_mode *pon_mode,
    uint32_t *device_id, uint32_t *physical_pon)
{
    int rc;
    char logical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
    char pon_mode_str[BCM_TOPO_MAX_LINE_SIZE];
    char device_id_str[BCM_TOPO_MAX_LINE_SIZE];
    char physical_pon_str[BCM_TOPO_MAX_LINE_SIZE];
    int2str_t *p;

    /* Skip blank lines and comments. */
    if (!*line || *line == '\n' || *line == '#')
    {
        *is_skipped = BCMOS_TRUE;
        return BCM_ERR_OK;
    }

    *is_skipped = BCMOS_FALSE;

    /* Read the tokens separated by commas. */
    rc = sscanf(line, "%[^,],%*[ ]%[^,],%[^,],%[^\n]", logical_pon_str, pon_mode_str, device_id_str, physical_pon_str);
    if (rc < 4)
    {
        BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
        return BCM_ERR_PARSE;
    }

    if (sscanf(logical_pon_str, "%u", logical_pon) < 1)
    {
        BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
        return BCM_ERR_PARSE;
    }

    if (sscanf(device_id_str, "%u", device_id) < 1)
    {
        BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
        return BCM_ERR_PARSE;
    }

    if (sscanf(physical_pon_str, "%u", physical_pon) < 1)
    {
        BCM_LOG(ERROR, topo_log_id, "Error parsing line %s:%u (rc=%u)\n", filename, line_num, rc);
        return BCM_ERR_PARSE;
    }

    BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical Pon ID=%u, PON mode='%s')\n", *logical_pon, *device_id, *physical_pon, pon_mode_str);

    for (p = pon_mode2str; p->from != -1 && strcmp(pon_mode_str, p->to); p++);

    if (p->from == -1)
    {
        BCM_LOG(ERROR, topo_log_id, "Error parsing PON mode at %s:%u\n", filename, line_num);
        return BCM_ERR_PARSE;
    }

    *pon_mode = p->from;

    return BCM_ERR_OK;
}

static void bcm_topo_init_dev(bcm_topo_dev_context_t *dev, bcm_topo_pon_mode pon_mode)
{
    dev->pon_mode = pon_mode;
    dev->max_num_of_pons = int2int(pon_mode2max_num_of_pons, pon_mode);
}

static void bcm_topo_init_pon(bcm_topo_pon_context_t *pon, bcm_topo_pon_mode pon_mode)
{
    pon->pon_mode = pon_mode;
    switch (pon_mode)
    {
    case BCM_TOPO_PON_MODE_GPON:
        pon->max_num_of_onus = 128;
        break;
    case BCM_TOPO_PON_MODE_XGPON:
    case BCM_TOPO_PON_MODE_XGS:
        pon->max_num_of_onus = 256;
        break;
    case BCM_TOPO_PON_MODE_EPON_TDMA:
    case BCM_TOPO_PON_MODE_EPON_1G:
    case BCM_TOPO_PON_MODE_EPON_10G:
        pon->max_num_of_onus = 0; /* There is no "ONU" in EPON, but LLIDs. */
        break;
    default:
        break;
    }
}

static bcmos_errno bcm_topo_init_by_file(FILE *fp, const char *filename)
{
    char line[BCM_TOPO_MAX_LINE_SIZE];
    uint32_t line_num;

    /* Read next line. */
    line_num = 1;
    while (fgets(line, sizeof(line), fp))
    {
        bcmos_bool is_skipped;
        uint32_t logical_pon, device_id, physical_pon;
        bcm_topo_pon_mode pon_mode;
        bcm_topo_dev_context_t *dev;
        bcm_topo_pon_context_t *pon;

        if (bcm_topo_init_line_parse(line, filename, line_num, &is_skipped, &logical_pon, &pon_mode, &device_id, &physical_pon) != BCM_ERR_OK)
            return BCM_ERR_PARSE;

        if (is_skipped)
        {
            line_num++;
            continue;
        }

        if (logical_pon >= BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS)
        {
            BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_LOGICAL_PONS - 1);
            return BCM_ERR_RANGE;
        }

        if (bcm_topo_context.logical_pon2physical_pon[logical_pon])
        {
            BCM_LOG(ERROR, topo_log_id, "Logical PON ID at %s:%u has already been set before\n", filename, line_num);
            return BCM_ERR_ALREADY;
        }

        if (device_id >= BCM_TOPO_MAX_NUM_OF_DEVS)
        {
            BCM_LOG(ERROR, topo_log_id, "Physical device ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, BCM_TOPO_MAX_NUM_OF_DEVS - 1);
            return BCM_ERR_RANGE;
        }

        dev = &bcm_topo_context.devs[device_id];
        if (!dev->is_initialized)
        {
            bcm_topo_init_dev(dev, pon_mode);
            dev->is_initialized = BCMOS_TRUE;
        }
        else if (dev->pon_mode != pon_mode)
        {
            BCM_LOG(ERROR, topo_log_id, "PON mode at %s:%u conflicts with PON mode='%s' that has already been set for this device\n", filename, line_num,
                int2str(pon_mode2str, dev->pon_mode));
            return BCM_ERR_NOT_SUPPORTED;
        }

        if (physical_pon >= dev->max_num_of_pons)
        {
            BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u must be in the range 0 .. %u\n", filename, line_num, dev->max_num_of_pons - 1);
            return BCM_ERR_RANGE;
        }

        pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
        if (!pon->is_initialized)
        {
            bcm_topo_init_pon(pon, pon_mode);
            pon->is_initialized = BCMOS_TRUE;
        }
        else
        {
            BCM_LOG(ERROR, topo_log_id, "Physical PON ID at %s:%u has already been set before\n", filename, line_num);
            return BCM_ERR_ALREADY;
        }

        bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
        bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;

        line_num++;
    }

    return BCM_ERR_OK;
}

static bcmos_errno bcm_topo_init_by_args(bcm_topo_params *params)
{
    uint32_t device_id;
    uint32_t max_num_of_pons_per_dev;

    if (params->num_of_devs > BCM_TOPO_MAX_NUM_OF_DEVS)
    {
        BCM_LOG(ERROR, topo_log_id, "Number of devices must be in the range 0 .. %u\n", BCM_TOPO_MAX_NUM_OF_DEVS);
        return BCM_ERR_RANGE;
    }

    max_num_of_pons_per_dev = int2int(pon_mode2max_num_of_pons, params->pon_mode);

    if (params->num_of_pons_per_dev > max_num_of_pons_per_dev)
    {
        BCM_LOG(ERROR, topo_log_id, "Number of PONs per device for PON mode '%s' must be in the range 0 .. %u\n", int2str(pon_mode2str, params->pon_mode), BCM_TOPO_MAX_NUM_OF_DEVS);
        return BCM_ERR_RANGE;
    }

    for (device_id = 0; device_id < params->num_of_devs; device_id++)
    {
        uint32_t physical_pon;
        bcm_topo_dev_context_t *dev;
        bcm_topo_pon_context_t *pon;

        dev = &bcm_topo_context.devs[device_id];
        bcm_topo_init_dev(dev, params->pon_mode);
        dev->is_initialized = BCMOS_TRUE;

        for (physical_pon = 0; physical_pon < params->num_of_pons_per_dev; physical_pon++)
        {
            uint32_t logical_pon;

            logical_pon = (device_id * params->num_of_pons_per_dev) + physical_pon;

            BCM_LOG(INFO, topo_log_id, "Map Logical PON ID=%u -> (Physical Device ID=%u, Physical pon ID=%u, PON mode='%s')\n", logical_pon, device_id, physical_pon,
                int2str(pon_mode2str, params->pon_mode));

            pon = &bcm_topo_context.devs[device_id].pons[physical_pon];
            bcm_topo_init_pon(pon, params->pon_mode);
            pon->is_initialized = BCMOS_TRUE;

            bcm_topo_context.logical_pon2physical_pon[logical_pon] = &bcm_topo_context.devs[device_id].pons[physical_pon];
            bcm_topo_context.devs[device_id].pons[physical_pon].logical_pon = logical_pon;
        }
    }

    return BCM_ERR_OK;
}

bcmos_errno bcm_topo_init(bcm_topo_params *params, const char *topo_filename)
{
    bcmos_errno ret;
    FILE *topo_fp;

#ifdef ENABLE_LOG
    if (topo_log_id == DEV_LOG_INVALID_ID)
    {
        topo_log_id = bcm_dev_log_id_register("TOPOLOGY", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
        BUG_ON(topo_log_id == DEV_LOG_INVALID_ID);
    }
#endif

    bcm_topo_init_context();

    topo_fp = fopen(topo_filename, "r");
    if (topo_fp)
    {
        BCM_LOG(INFO, topo_log_id, "Topology is taken from file\n");
        ret = bcm_topo_init_by_file(topo_fp, topo_filename);
        fclose(topo_fp);
    }
    else if (params)
    {
        BCM_LOG(INFO, topo_log_id, "Topology is taken from arguments\n");
        ret = bcm_topo_init_by_args(params);
    }
    else
    {
        BCM_LOG(INFO, topo_log_id, "At least one of topo_fp and params must be specified and exist\n");
        ret = BCM_ERR_PARM;
    }

    if (ret != BCM_ERR_OK)
        goto exit;

    bcm_topo_context.is_initialized = BCMOS_TRUE;

    ret = BCM_ERR_OK;

exit:
    return ret;
}

bcmos_bool bcm_topo_is_initialized(void)
{
    return bcm_topo_context.is_initialized;
}

bcmos_bool bcm_topo_dev_set_max_nni(bcmolt_devid device_id, uint32_t num_nni_ports)
{
    if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
    {
        return BCM_ERR_PARM;
    }
    /* make sure the max number does not exceed the allocated resrouce */
    if( num_nni_ports > BCM_TOPO_MAX_NNI_PORTS)
    {
        return BCM_ERR_PARM;
    } 
    g_max_nni_ports[device_id] = num_nni_ports;

    return BCMOS_TRUE;
}

bcmos_bool bcm_topo_dev_get_max_nni(bcmolt_devid device_id, uint32_t *p_num_nni_ports)
{
    if(device_id >= BCM_TOPO_MAX_NNI_DEVICES)
    {
        return BCM_ERR_PARM;
    }
     *p_num_nni_ports = g_max_nni_ports[device_id];

    return BCMOS_TRUE;
}

bcmos_bool bcm_topo_nni_is_valid(uint32_t nni)
{

    if (nni >= g_max_nni_ports[0])
        return BCMOS_FALSE;

    return BCMOS_TRUE;
}

