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