blob: c4635b95b44a02ca9732743bb40f9cb9cfc779b4 [file] [log] [blame]
/******************************************************************************
*
* <: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.
*
* :>
*
*****************************************************************************/
/**
* @file acc_term_fsm.c
* @brief Code to support the BAL access terminal FSM
*
* @addtogroup access_terminal
*/
/*@{*/
#define BAL_DBG_PRINT
/*--- project includes ---*/
#include <bcmos_system.h>
#include <acc_term_fsm.h>
#include <bal_msg.h>
#include <bal_api.h>
#include "bal_worker.h"
#include "bal_mac_util.h"
#include "bal_switch_util.h"
#include <bal_osmsg.h>
#include <fsm_common.h>
#include <rsc_mgr.h>
#include <bal_core.h>
#ifdef ENABLE_LOG
#include <bcm_dev_log.h>
/*
* @brief The logging device ids for the access-terminal and interface
*/
static dev_log_id log_id_access_terminal;
static dev_log_id log_id_interface;
#endif
/*--- local function declarations ---*/
static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface,
void *msg);
static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface,
void *msg);
static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser);
static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst, acc_term_fsm_event *p_event);
/**
* access-terminal FSM helper functions
*/
static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event);
static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst);
static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
bcmbal_sub_id_list_u16 *sub_term_id_list);
static acc_term_inst *access_terminal_get(void);
static char *interface_type_str_get(bcmbal_intf_type intf_type);
static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info);
static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key);
#define ACC_TERM_FSM_STATE_ADDING_TIMEOUT (45) /* Seconds */
/*
* @brief The definition of an access terminal FSM state processing function
*/
typedef bcmos_errno (* acc_term_fsm_state_processor)(acc_term_inst *, void *, acc_term_fsm_event *);
extern bcmbal_config_params bal_config_params;
/**
* @brief API to get oper status from admin state of an interface
*/
bcmbal_status bcmbal_get_intf_oper_status_from_admin_state (bcmbal_state intf_admin_state)
{
switch (intf_admin_state)
{
case BCMBAL_STATE_UP:
return BCMBAL_STATUS_UP;
break;
case BCMBAL_STATE_DOWN:
return BCMBAL_STATUS_DOWN;
break;
case BCMBAL_STATE_TESTING:
return BCMBAL_STATUS_TESTING;
break;
default:
return BCMBAL_STATUS_UP; /* default keep oper status as UP */
break;
}
return BCMBAL_STATUS_UP; /* default keep oper status as UP */
}
/**
* @brief API to convert port type and id from CLI/Mgmt interface to the internal
* index of interface array database.
*/
uint32_t bcmbal_port_type_and_id_to_interface_index (bcmbal_intf_type intf_type, bcmbal_intf_id intf_id)
{
switch (intf_type)
{
case BCMBAL_INTF_TYPE_PON:
if (intf_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
{
return intf_id; /* zero offset for the PON ports */
}
break;
case BCMBAL_INTF_TYPE_NNI:
if (intf_id < bal_config_params.num_nni_ports)
{
return (NUM_SUPPORTED_SUBSCRIBER_INTERFACES + intf_id); /* offset-ed for the NNI ports */
}
break;
default:
break;
}
return INVALID_INTERFACE_INDEX;
}
/*
* @brief The Access terminal FSM state processing array
*/
static acc_term_fsm_state_processor access_term_states[ACC_TERM_FSM_STATE__NUM_OF][ACC_TERM_FSM_EVENT_TYPE__NUM_OF] =
{
[ACC_TERM_FSM_STATE_NULL] =
{
/*
* Next state: ADDING
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_start,
/*
* Next state: NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_ok,
/*
* Next state: NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
/*
* Next state: NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
},
[ACC_TERM_FSM_STATE_ADDING] =
{
/*
* Next state: ADDING
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_pending,
/*
* Next state: ADDING | ADDED
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_adding_process_util_msg,
/*
* Next state: ADDING
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
/*
* Next state: NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_adding_timeout,
},
[ACC_TERM_FSM_STATE_ADDED] =
{
/*
* Next state: ADDED
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_ok,
/*
* Next state: REMOVING
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_start,
/*
* Next state: ADDING | ADDED
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
/*
* Next state: ADDED
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
},
[ACC_TERM_FSM_STATE_REMOVING] =
{
/*
* Next state: REMOVING
*/
[ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_pending,
/*
* Next state: REMOVING | NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_removing_process_util_msg,
/*
* Next state: REMOVING
*/
[ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
/*
* Next state: NULL
*/
[ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_removing_timeout,
},
};
static char *state_name_str[] =
{
"ACC_TERM_NULL",
"ACC_TERM_ADDING",
"ACC_TERM_ADDED",
"ACC_TERM_REMOVING",
};
/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT (ACC_TERM_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), acc_term_fsm_state);
static char *acc_term_state_name_get(acc_term_fsm_state state)
{
if(state < ACC_TERM_FSM_STATE__LAST)
{
return state_name_str[state];
}
else
{
return "ACC_TERM_UNKNOWN";
}
}
static char *event_name_str[] =
{
"ACC_TERM_FSM_ACC_TERM_ADMIN_UP_EVENT",
"ACC_TERM_FSM_ACC_TERM_ADMIN_DN_EVENT",
"ACC_TERM_FSM_INT_ADMIN_UP_EVENT",
"ACC_TERM_FSM_INT_ADMIN_DN_EVENT",
"ACC_TERM_FSM_UTIL_MSG_EVENT",
"ACC_TERM_FSM_UTIL_AUTO_MSG_EVENT",
"ACC_TERM_FSM_TIMEOUT_EVENT"
};
/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT (ACC_TERM_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), acc_term_fsm_event_type);
static char *acc_term_event_name_get(acc_term_fsm_event_type event)
{
if(event < ACC_TERM_FSM_EVENT_TYPE__LAST)
{
return event_name_str[event];
}
else
{
return "ACC_TERM_EVT_UNKNOWN";
}
}
static acc_term_inst single_access_terminal_instance;
/*****************************************************************************/
/**
* @brief A function called to initialize the access-terminal FSM
* infrastructure.
*
* NOTE: This is called once on startup and NOT for each FSM instance.
*
* @returns void
*****************************************************************************/
void access_terminal_fsm_init(void)
{
#ifdef ENABLE_LOG
/* Register the log ids for this FSM */
log_id_access_terminal = bcm_dev_log_id_register("ACC_TERM", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
BUG_ON(log_id_access_terminal == DEV_LOG_INVALID_ID);
log_id_interface = bcm_dev_log_id_register("INTF", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
BUG_ON(log_id_interface == DEV_LOG_INVALID_ID);
#endif
/*
* Initialize the access terminal instance structures
*/
initialize_access_terminal_instance_config(&single_access_terminal_instance);
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing executive function
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_fsm_state pre_state;
acc_term_fsm_state_processor acc_term_state_processor;
/* Parameter checks */
BUG_ON(NULL == p_acc_term_inst);
BUG_ON(NULL == p_event);
/* Record the present state before transitioning
*/
pre_state = p_acc_term_inst->fsm_state;
/*
* Get the state processing function
*/
acc_term_state_processor = access_term_states[p_acc_term_inst->fsm_state][p_event->event_type];
/*
* If there's a state processing function for this event and state, execute it.
* Otherwise, process a generic error.
*/
if (acc_term_state_processor)
{
ret = acc_term_state_processor(p_acc_term_inst, p_event->msg, p_event);
} else
{
acc_term_fsm_state_err(p_acc_term_inst, p_event->msg, p_event);
}
BCM_LOG(DEBUG, log_id_access_terminal, "*** FSM exec: Event %s, State: %s --> %s\n",
acc_term_event_name_get(p_event->event_type),
acc_term_state_name_get(pre_state),
acc_term_state_name_get(p_acc_term_inst->fsm_state));
return ret;
}
bcmos_errno process_access_terminal_util_msg(void *msg_payload)
{
acc_term_inst *p_access_terminal_inst;
BCM_LOG(INFO, log_id_access_terminal, "ACCESS_TERMINAL indication received from util\n");
/* Find the specified access terminal instance */
p_access_terminal_inst = access_terminal_get();
if (NULL != p_access_terminal_inst)
{
acc_term_fsm_event event;
event.event_type = ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG;
event.msg = msg_payload;
access_terminal_fsm_exec(p_access_terminal_inst, &event);
}
else
{
BCM_LOG(ERROR, log_id_interface, "Could not find the ACTIVE access-terminal\n");
}
return BCM_ERR_OK;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing for an access-terminal
* admin-up command received from the BAL Public API when the specified
* access-terminal instance is in the admin-down state (i.e. when
* the access-terminal instance FSM is in the NULL state).
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_fsm_state old_state = p_acc_term_inst->fsm_state;
BCM_LOG(INFO, log_id_access_terminal,
"Received an admin UP request from BAL API - bringing access terminal up\n");
do
{
/* change access terminal state to ADDING */
p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDING;
/* start the timeout timer for the ADDING state */
fsm_timer_start(&p_acc_term_inst->timer_info,
p_acc_term_inst,
acc_term_fsm_timer_expiry,
TIMER_DURATION_IN_SEC(ACC_TERM_FSM_STATE_ADDING_TIMEOUT),
log_id_access_terminal);
/* Validate that the OLT SW version that the Bal was compiled against matches
* the SW version of the actual OLT that the Bal works with. We assume that
* Device Id 0 has the same version as all other OLT devices */
if (!bcmbal_is_mac_in_loopback() &&
(BCM_ERR_OK != (ret = mac_util_access_terminal_sw_version_validate((bcmolt_devid) 0))))
{
BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_sw_version_validate(() failed. rc=%s\n", bcmos_strerror(ret));
break;
}
/* Core calls Mac Utils to set the access-terminal parameters using the applicable SDK calls */
if(BCM_ERR_OK != (ret = mac_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT)))
{
BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
break;
}
}while(0);
if(BCM_ERR_OK == ret)
{
/*
* The access-terminal object command has succeeded. The current object info
* becomes the commanded object info, except for the oper_status. This should
* be done atomically
*/
memcpy(&p_acc_term_inst->current_acc_term_obj_info,
&p_acc_term_inst->api_req_acc_term_obj_info,
sizeof(p_acc_term_inst->api_req_acc_term_obj_info));
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_TRUE);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
oper_status,
BCMBAL_STATUS_DOWN);
}
else
{
fsm_timer_stop(&p_acc_term_inst->timer_info);
p_acc_term_inst->fsm_state = old_state;
mgmt_msg_send_balapi_ind(ret, msg, log_id_access_terminal);
}
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing for an access-terminal
* admin-up command from the BAL Public API when the specified
* access-terminal is already admin-up (i.e. when the specified
* access-terminal instance FSM is in the ADDED state).
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(DEBUG, log_id_access_terminal,
"Received an admin UP request from BAL API - returning OK to the API"
" - no further function\n");
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing for an access-terminal
* admin-down command received from the BAL Public API when the specified
* access-terminal is admin-up (i.e when the specified access-terminal
* instance FSM is in the ADDED state).
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(DEBUG, log_id_access_terminal,
"Received an admin DOWN request from BAL API - removing the access terminal\n");
/*
* @todo - complete the DOWN implementation - until then, return an error
*/
ret = BCM_ERR_NOT_SUPPORTED;
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing for access-terminal
* admin-down command from the BAL Public API when the specified
* access-terminal is already admin-down.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(DEBUG, log_id_access_terminal,
"Received an admin DOWN request from BAL API - returning OK to the API"
" - no further function\n");
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to ignore a
* received message.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(DEBUG, log_id_access_terminal, "Ignoring message from BAL API \n");
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to process an
* access-terminal admin-up command from the BAL Public API when the
* specified access-terminal is in the REMOVING state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(DEBUG, log_id_access_terminal,
" Received an admin UP request from BAL API - returning UP_PENDING to the API"
" - no further function\n");
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to process an
* access-terminal admin-down command from the BAL Public API when the
* specified access-terminal FSM is in the REMOVING state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_IN_PROGRESS;
BCM_LOG(DEBUG, log_id_access_terminal,
" Received an admin DOWN request from BAL API"
" - returning IN_PROGRESS to the API - no further function\n");
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to process a
* message from one of the BAL apps when the specified access-terminal
* instance FSM is in the ADDING state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from one of
* the BAL apps.
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
flow_fsm_state next_state = ACC_TERM_FSM_STATE_NULL;
bcmos_errno ret;
bal_util_msg_ind *ind_msg;
/* Parameter checks */
BUG_ON(NULL == p_acc_term_inst);
BUG_ON(NULL == msg);
BUG_ON(NULL == p_event);
ind_msg = (bal_util_msg_ind *)msg;
ret = ind_msg->status;
/*
* NOTE: AUTO_IND messages are not processed in this function,
* so there is no need to consider them in this logic.
*/
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_access_terminal,
"Received an IND message from BAL UTIL (%s) during ADDING state with status %s\n",
subsystem_str[bcmbal_sender_get(msg)],
bcmos_strerror(ret)
);
}
/*
* Stop the indication timer
*/
fsm_timer_stop(&p_acc_term_inst->timer_info);
if(BCM_ERR_OK == ret)
{
/* Core calls Switch Utils to set the access-terminal parameters using the applicable SDK calls */
ret = sw_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT);
if (ret)
{
BCM_LOG(INFO, log_id_access_terminal,
"sw_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
}
if(BCM_ERR_OK == ret)
{
uint32_t logical_pon;
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
oper_status,
BCMBAL_STATUS_UP);
/*
* Initialize the resource manager only if at least of the PONs on the device is a GPON/XGPON/XGS/NGPON2 PON
*/
BCM_TOPO_DEV_FOR_EACH_PON(0, logical_pon)
{
bcm_topo_pon_family pon_family = bcm_topo_pon_get_pon_family(logical_pon);
if (pon_family == BCM_TOPO_PON_FAMILY_GPON)
{
rsc_mgr_mac_init();
break;
}
}
/*
* Go to the ADDED state upon success
*/
next_state = ACC_TERM_FSM_STATE_ADDED;
}
else
{
/* Error */
BCM_LOG(ERROR, log_id_access_terminal,
" Failed in state %s;%s\n",
acc_term_state_name_get(p_acc_term_inst->fsm_state),
bcmos_strerror(ret));
/*
* Automatically return to the NULL state if an error occurs
*/
}
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
/*
* Send the indication back to the BAL public API here
*/
mgmt_msg_send_balapi_ind(ret,
(void *)&p_acc_term_inst->current_acc_term_obj_info.hdr,
log_id_access_terminal);
}
p_acc_term_inst->fsm_state = next_state;
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to process a
* message from one of the BAL apps received when the specified
* access-terminal instance FSM is in the REMOVING state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from one of
* the BAL apps.
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret;
bal_util_msg_ind *ind_msg;
/* Parameter checks */
BUG_ON(NULL == p_acc_term_inst);
BUG_ON(NULL == msg);
BUG_ON(NULL == p_event);
ind_msg = (bal_util_msg_ind *)msg;
ret = ind_msg->status;
/*
* NOTE: AUTO_IND messages are not processed in this function,
* so there is no need to consider them in this logic.
*/
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_access_terminal,
" Received an IND message from BAL UTIL (%s) during REMOVING state\n",
subsystem_str[bcmbal_sender_get(msg)]);
}
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing function to process an
* AUTO IND message from one of the BAL apps.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from one of
* the BAL apps.
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
/* Parameter checks */
BUG_ON(NULL == p_acc_term_inst);
BUG_ON(NULL == msg);
BUG_ON(NULL == p_event);
BCM_LOG(INFO, log_id_access_terminal,
" Received an AUTO IND message from BAL UTIL ()\n");
return ret;
}
/*****************************************************************************/
/**
* @brief Interface admin-up command received from the BAL Public API when
* the specified interface instance is in the admin-up state.
*
* @note This handler gets called for both PON and NNI type interfaces
*
* @param p_interface_inst Pointer to an interface instance
* @param msg Pointer to a BAL message received from the BAL Public API
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface_inst,
void *msg)
{
bcmos_errno ret = BCM_ERR_OK;
bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
BCM_LOG(INFO, log_id_interface,
" Received an INTERFACE admin UP request from BAL API"
" - bringing interface (%s%d) UP \n",
interface_type_str_get(key->intf_type),
key->intf_id);
do
{
bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
/*
* Create a pointer to the interface instance specified by the user
*/
/*
* If the user has set the min_data_agg_port_id attribute for the interface, then program the resource manager
* with this value. It will also be sent to the MAC device for any required programming there.
*/
if ((BCMBAL_INTF_TYPE_PON == key->intf_type) &&
(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_interface_inst->api_req_int_obj_info,
interface,
min_data_agg_port_id)) &&
(BCM_ERR_OK != rsc_mgr_access_int_base_alloc_id_set(key->intf_id,
p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id)))
{
BCM_LOG(ERROR, log_id_access_terminal, "Error while setting base agg_port_id (%d) in the resource manager\n",
p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id);
ret = BCM_ERR_INTERNAL;
break;
}
/* Change the interface admin state of the "current" interface object to up (this is for reporting) */
BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
interface,
admin_state,
BCMBAL_STATE_UP);
/* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_UP);
if (BCM_ERR_OK != ret)
{
BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
interface,
admin_state,
old_admin_state);
BCM_LOG(ERROR, log_id_interface,
"Error detected by mac_util_interface_set (%s)\n",
bcmos_strerror(ret));
break;
}
} while (0);
if (BCM_ERR_OK != ret)
{
/* report this error to the API */
mgmt_msg_send_balapi_ind(ret,
msg,
log_id_interface);
}
else
{
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
}
return ret;
}
/*****************************************************************************/
/**
* @brief Interface admin-up command received from the BAL Public API when
* the specified interface instance is in the admin-down state.
*
* @note This handler gets called for both PON and NNI type interfaces
*
* @param p_interface_inst Pointer to an interface instance
* @param msg Pointer to a BAL message received from the BAL Public API
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface_inst,
void *msg)
{
bcmos_errno ret = BCM_ERR_OK;
bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
BCM_LOG(INFO, log_id_interface,
" Received an INTERFACE admin DOWN request from BAL API"
" - bringing interface (%s%d) DOWN \n",
interface_type_str_get(key->intf_type),
key->intf_id);
do
{
bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
/*
* Create a pointer to the interface instance specified by the user
*/
/* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_DOWN);
if (BCM_ERR_OK != ret)
{
BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
interface,
admin_state,
old_admin_state);
BCM_LOG(ERROR, log_id_interface,
"Error detected by mac_util_interface_set (%s)\n",
bcmos_strerror(ret));
break;
}
} while (0);
/* Change the interface admin state of the current interface info to down */
BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
interface,
admin_state,
BCMBAL_STATE_DOWN);
/* Check for any error and send an indication immediately in that case */
if (BCM_ERR_OK != ret)
{
/* report this error to the API */
mgmt_msg_send_balapi_ind(ret,
msg,
log_id_interface);
}
else
{
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
}
return ret;
}
/*****************************************************************************/
/**
* @brief The function to process a timer expiry for either the ADDING
* states. This function executes an
* ACC_TERM_FSM_TIMEOUT_EVENT in the FSM state machine.
*
* @param timer - A pointer to the timer instance
* @param pUser - An opaque pointer to an access terminal instance
*
* @returns bcmos_timer_rc == BCMOS_TIMER_OK
*/
static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser)
{
acc_term_fsm_event acc_term_event;
/*
* Stop the indication timer
*/
fsm_timer_stop(timer);
BCM_LOG(INFO, log_id_access_terminal,
"timer expiry\n");
/*
* A message pointer is always passed inside the event structure. In this case, it is unused
*/
acc_term_event.msg = NULL;
acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_TIMEOUT;
/* Declare this no longer in-progress */
BCMBAL_OBJ_IN_PROGRESS_SET(&(((acc_term_inst *)pUser)->current_acc_term_obj_info), BCMOS_FALSE);
/*
* Run the access terminal FSM to process this event
*/
access_terminal_fsm_exec((acc_term_inst *)pUser, &acc_term_event);
return BCMOS_TIMER_OK;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing a timeout that occurs
* when the FSM is in the ADDING state. In this case, the FSM should
* just go back to the NULL state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(ERROR, log_id_access_terminal,
"Error: Received a timeout while in the %s state.\n",
acc_term_state_name_get(p_acc_term_inst->fsm_state));
/*
* Send the indication back to the BAL public API here
*/
mgmt_msg_send_balapi_ind(BCM_ERR_TIMEOUT,
(void *)&(p_acc_term_inst->current_acc_term_obj_info.hdr.hdr),
log_id_access_terminal);
/*
* Go back to the previous state
*/
p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_NULL;
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM state processing a timeout that occurs
* when the FSM is in the REMOVING state. In this case, the FSM should
* just go back to the ADDED state.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message received from the BAL Public API
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_OK;
BCM_LOG(INFO, log_id_access_terminal,
"Received a timeout while in the %s state. Going back to the ADDED state\n",
acc_term_state_name_get(p_acc_term_inst->fsm_state));
/*
* Go back to the previous state
*/
p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDED;
return ret;
}
/*****************************************************************************/
/**
* @brief The function to process a
* message from one of the BAL apps for the specified interface
*
* @param msg Pointer to a BAL message received from one of
* the BAL apps.
*
* @returns bcmos_errno
*****************************************************************************/
bcmos_errno process_interface_util_msg(void *msg)
{
bcmos_errno ret = BCM_ERR_OK;
uint32_t interface_index = INVALID_INTERFACE_INDEX;
bal_util_msg_ind *ind_msg;
acc_term_interface *p_interface_inst;
/* Parameter checks */
BUG_ON(NULL == msg);
ind_msg = (bal_util_msg_ind *)msg;
/*
* NOTE: AUTO_IND messages are not processed in this function,
* so there is no need to consider them in this logic.
*/
BCM_LOG(DEBUG, log_id_access_terminal,
" Received an interface IND message from BAL UTIL (%s)\n",
subsystem_str[bcmbal_sender_get(msg)]);
if (BCM_ERR_OK == ind_msg->status)
{
/* first get the index to the interface array from port id/type */
interface_index = bcmbal_port_type_and_id_to_interface_index(ind_msg->obj_key.if_key.intf_type,
ind_msg->obj_key.if_key.intf_id);
if (interface_index >= INVALID_INTERFACE_INDEX)
{
BCM_LOG(ERROR, log_id_interface,
"INVALID port type/id (%s/%d) to interface index (%d)\n",
interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
ind_msg->obj_key.if_key.intf_id,
interface_index);
ret = BCM_ERR_PARM;
}
p_interface_inst = &(access_terminal_get()->intf_info.interface[interface_index]);
if(BCM_ERR_OK == ret)
{
/* Core calls Switch Utils to set the interface parameters using the applicable SDK call
* If a PON port is being set, then the corresponding direct connect switch port is also
* set along with it
*/
ret = sw_util_interface_set(p_interface_inst,
(p_interface_inst->api_req_int_obj_info.data.admin_state == BCMBAL_STATE_DOWN ?
BAL_UTIL_OPER_IF_DOWN : BAL_UTIL_OPER_IF_UP));
if (ret)
{
BCM_LOG(ERROR, log_id_access_terminal,
"sw_util_interface_set(() failed. rc=%s\n", bcmos_strerror(ret));
}
}
else
{
/* Error */
BCM_LOG(ERROR, log_id_interface,
"Bad interface index: interface type/id (%s/%d) (status: %s)\n",
interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
ind_msg->obj_key.if_key.intf_id,
bcmos_strerror(ind_msg->status));
}
if(BCM_ERR_OK == ret)
{
BCM_LOG(DEBUG, log_id_interface,
"Setting interface (%d) to %s\n",
interface_index,
(BCMBAL_STATE_UP == p_interface_inst->api_req_int_obj_info.data.admin_state) ?
"UP" : "DOWN");
/*
* Interface SET function succeeded, so copy the API request into the
* current interface object.
*/
bcmbal_interface_object_overlay_w_src_priority(&(p_interface_inst->current_int_obj_info),&(p_interface_inst->api_req_int_obj_info));
/* Set the status of the current interface that we just configured to the requested state (UP or DOWN) */
BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
interface,
oper_status,
bcmbal_get_intf_oper_status_from_admin_state(p_interface_inst->api_req_int_obj_info.data.admin_state));
}
else
{
/* Error */
BCM_LOG(ERROR, log_id_interface,
"Bad response from switch: Interface type/Id: %s/%d (status:%s) \n",
interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
ind_msg->obj_key.if_key.intf_id,
bcmos_strerror(ind_msg->status));
}
}
else
{
/* Error */
BCM_LOG(ERROR, log_id_interface,
"Bad interface indication from MAC (status:%s)\n",
bcmos_strerror(ind_msg->status));
}
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_FALSE);
/*
* Send the indication back to the BAL public API here
*/
mgmt_msg_send_balapi_ind(ret,
(void *)&(p_interface_inst->current_int_obj_info.hdr),
log_id_interface);
return ret;
}
/*****************************************************************************/
/**
* @brief The Access terminal FSM function which is executed when an error
* is encountered during FSM processing.
*
* @param p_acc_term_inst Pointer to an access terminal instance
* @param msg Pointer to a BAL message (MAY BE NULL!)
* @param p_event Pointer to an access terminal event structure
*
* @returns bcmos_errno
*****************************************************************************/
static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
void *msg,
acc_term_fsm_event *p_event)
{
bcmos_errno ret = BCM_ERR_INVALID_OP;
BCM_LOG(ERROR, log_id_access_terminal,
"Error encountered processing FSM - BAD EVENT event:%s, state:%s\n",
acc_term_event_name_get(p_event->event_type),
acc_term_state_name_get(p_acc_term_inst->fsm_state));
return ret;
}
/*****************************************************************************/
/**
* @brief A function called by the core worker thread to process an
* access-terminal object message (SET, GET, CLEAR, STATS) received
* from the BAL Public API.
*
* @param msg_payload Pointer to a BAL message received from the
* BAL Public API.
*
* @returns bcmos_errno
*****************************************************************************/
bcmos_errno process_access_terminal_object(void *msg_payload)
{
bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
acc_term_inst *p_access_terminal_inst;
acc_term_fsm_event acc_term_event;
bcmbal_obj_msg_type oper_type;
/* Parameter checks */
BUG_ON(NULL == msg_payload);
BCM_LOG(DEBUG, log_id_access_terminal,
"Processing an access-terminal object\n");
do
{
/*
* Find or create the specified access terminal instance
*/
p_access_terminal_inst = access_terminal_get();
oper_type = ((bcmbal_access_terminal_cfg *)msg_payload)->hdr.hdr.type;
/* If the state of the access-terminal is in flux, then reject the SET request */
if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
{
BCM_LOG(ERROR, log_id_access_terminal,
"The access-terminal is in-progress, SETs are not allowed\n");
ret = BCM_ERR_IN_PROGRESS;
break;
}
/* Copy the object in the message into local storage */
memcpy(&p_access_terminal_inst->api_req_acc_term_obj_info,
msg_payload,
sizeof(p_access_terminal_inst->api_req_acc_term_obj_info));
BCM_LOG(DEBUG, log_id_access_terminal,
"access_terminal admin state is: %s\n",
(BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state) ?
"UP" : "DOWN");
/*
* A message pointer is always passed inside the event structure.
*/
acc_term_event.msg = msg_payload;
/* SET or GET or ...? */
switch (oper_type)
{
case (BCMBAL_OBJ_MSG_TYPE_SET):
{
BCM_LOG(DEBUG, log_id_access_terminal,
"Processing a access-terminal SET REQ mgmt message\n");
/*
* Check if the mandatory access-terminal attributes have been set
*/
do
{
/* The admin state attribute is mandatory */
if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
access_terminal,
admin_state))
{
ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
break;
}
/*set iwf_mode from the global config parameters*/
BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
access_terminal,
iwf_mode,
bcmbal_config_get()->iwf_mode);
/*
* Perform the validation check(s) that the utils require
*/
if(BCM_ERR_OK !=
(ret = mac_util_access_terminal_info_validate(&p_access_terminal_inst->api_req_acc_term_obj_info)))
{
break;
}
}
while(0);
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
rsp_ret = mgmt_msg_send_balapi_rsp(ret,
msg_payload,
oper_type,
log_id_access_terminal);
if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
{
/* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
break;
}
/* Reflect the admin state of the access-terminal according to the commanded admin state */
BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->current_acc_term_obj_info,
access_terminal,
admin_state,
p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state);
if(BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state)
{
acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP;
}
else
{
acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN;
}
/*
* Run the access terminal FSM to process this event
*/
ret = access_terminal_fsm_exec(p_access_terminal_inst, &acc_term_event);
break;
}
case (BCMBAL_OBJ_MSG_TYPE_GET):
{
BCM_LOG(DEBUG, log_id_access_terminal,
"Processing a access-terminal GET REQ mgmt message\n");
p_access_terminal_inst->current_acc_term_obj_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
*((bcmbal_access_terminal_cfg *)msg_payload) = p_access_terminal_inst->current_acc_term_obj_info;
mgmt_msg_send_balapi_rsp(ret,
msg_payload,
oper_type,
log_id_access_terminal);
break;
}
default:
{
BCM_LOG(ERROR, log_id_access_terminal,
"Unsupported operation on access-terminal object (%d)\n",
bcmbal_msg_id_oper_get(msg_payload));
ret = BCM_ERR_NOT_SUPPORTED;
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_access_terminal);
break;
}
}
}while(0);
return ret;
}
/*****************************************************************************/
/**
* @brief A function to retrieve an access-terminal instance
*
* @returns acc_term_inst_t* A pointer to the found access-terminal instance,
* or NULL if one is not found.
*****************************************************************************/
static acc_term_inst *access_terminal_get(void)
{
acc_term_inst *p_acc_term = (acc_term_inst *)NULL;
p_acc_term = &single_access_terminal_instance;
return p_acc_term;
}
/*****************************************************************************/
/**
* @brief A function to retrieve the status of the access-terminal
*
*
* @returns bcmbal_status
*****************************************************************************/
bcmbal_status acc_term_status_get(void)
{
acc_term_inst *p_acc_term_inst;
p_acc_term_inst = access_terminal_get();
return p_acc_term_inst->current_acc_term_obj_info.data.oper_status;
}
static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info)
{
bcmos_errno ret = BCM_ERR_OK;
tm_sched_inst *p_tm_sched_inst;
bcmbal_tm_sched_key tm_key;
switch(p_interface_info->key.intf_type)
{
case BCMBAL_INTF_TYPE_PON:
{
/*for active pon interface:
ds_tm should be define, - if it is set, validate sched exist and match direction (ds)
if not set - will create auto created tm */
if(BCMBAL_CFG_PROP_IS_SET(p_interface_info,interface,ds_tm))
{
tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
tm_key.id = p_interface_info->data.ds_tm;
p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
if (NULL == p_tm_sched_inst)
{
BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
ret = BCM_ERR_NOENT;
break;
}
ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
p_interface_info->key.intf_id, tm_key.id);
break;
}
}
else /*auto created sched was removed and no other default sched was set*/
{
BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
break;
}
/* us_tm is optional - if it is set, validate sched exist and match direction (us)*/
if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
{
tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
tm_key.id = p_interface_info->data.us_tm;
p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
if (NULL == p_tm_sched_inst)
{
BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
ret = BCM_ERR_NOENT;
break;
}
ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
p_interface_info->key.intf_id, tm_key.id);
break;
}
}
}
break;
case BCMBAL_INTF_TYPE_NNI:
{
/*for active nni interface:
us_tm should be define, -
if it is set, validate sched exist and match direction (us)
if not set - will create auto created tm
*/
if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
{
tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
tm_key.id = p_interface_info->data.us_tm;
p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
if (NULL == p_tm_sched_inst)
{
BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
ret = BCM_ERR_NOENT;
break;
}
ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
p_interface_info->key.intf_id, tm_key.id);
break;
}
}
else /*auto created sched was removed and no other default sched was set*/
{
BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
break;
}
/* ds_tm is optional - if it is set, validate sched exist and match direction (ds)*/
if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, ds_tm))
{
tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
tm_key.id = p_interface_info->data.ds_tm;
p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
if (NULL == p_tm_sched_inst)
{
BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
ret = BCM_ERR_NOENT;
break;
}
ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
p_interface_info->key.intf_id, tm_key.id);
break;
}
}
}
break;
default:
BCM_LOG(ERROR, log_id_interface, "Invalid intf type (%d) in interface key\n",
p_interface_info->key.intf_type);
ret = BCM_ERR_PARM;
}
return ret;
}
bcmos_errno interface_tm_sched_unset(bcmbal_interface_key intf_key, bcmbal_tm_sched_key sched_key)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_interface *p_acc_term_interface = bcmbal_interface_get(intf_key);
do
{
if(NULL == p_acc_term_interface)
{
BCM_LOG(ERROR, log_id_interface, "no such interface (id = %d dir = %s ) \n",
intf_key.intf_id, interface_type_str_get(intf_key.intf_type));
ret = BCM_ERR_INTERNAL;
break;
}
if (BCMBAL_TM_SCHED_DIR_US == sched_key.dir)
{
BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, us_tm);
}
else
{
BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, ds_tm);
}
}while(0);
return ret;
}
/*****************************************************************************/
/**
* @brief A function to process an interface object message
* (SET, GET, CLEAR, STATS) received from the BAL Public API.
*
* @param msg_payload Pointer to a BAL message received from the
* BAL Public API.
*
* @returns bcmos_errno
*****************************************************************************/
bcmos_errno process_interface_object(void *msg_payload)
{
bcmos_errno ret = BCM_ERR_OK;
bcmbal_interface_cfg *p_intf_cfg = (bcmbal_interface_cfg *)msg_payload;
bcmbal_interface_key *p_intf_key;
acc_term_inst *p_access_terminal_inst;
bcmbal_interface_cfg *p_api_req_interface_info;
bcmbal_interface_cfg *p_current_interface_info;
uint32_t interface_index = INVALID_INTERFACE_INDEX;
bcmbal_obj_msg_type oper_type;
BCM_LOG(DEBUG, log_id_interface,
"Processing an interface object\n");
do
{
do
{
oper_type = p_intf_cfg->hdr.hdr.type;
/*
* See if the access terminal is active
*/
p_access_terminal_inst = access_terminal_get();
if(NULL == p_access_terminal_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,
"the access-terminal is not active\n");
ret = BCM_ERR_NOENT;
break;
}
/* If the state of the access-terminal is in flux, then reject the SET request */
if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
{
BCM_LOG(ERROR, log_id_access_terminal,
"The access-terminal is in-progress, SETs to an interface are not allowed\n");
ret = BCM_ERR_IN_PROGRESS;
break;
}
/*
* Get the interface key from the message
*/
p_intf_key = &p_intf_cfg->key;
if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_PON)
{
if(p_intf_key->intf_id > NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
{
BCM_LOG(ERROR, log_id_interface,
"out of range value (%d) detected in interface key for PON\n", p_intf_key->intf_id);
ret = BCM_ERR_RANGE;
break;
}
}
/** @todo check the lower limit also */
else if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_NNI)
{
if( BCMOS_FALSE == bcm_topo_nni_is_valid(p_intf_key->intf_id))
{
BCM_LOG(ERROR, log_id_interface,
"out of range value (%d) detected in interface key for NNI\n", p_intf_key->intf_id);
ret = BCM_ERR_RANGE;
break;
}
}
else
{
BCM_LOG(ERROR, log_id_interface,
"Invalid intf type (%d) in interface key\n", p_intf_key->intf_type);
ret = BCM_ERR_PARM;
break;
}
/*
* Don't accept interface object references when the associated access-terminal is down
*
* Interfaces are not even instantiated internally until the access-terminal object to which
* they belong is instantiated.
*/
if(BCMBAL_STATE_DOWN == p_access_terminal_inst->current_acc_term_obj_info.data.admin_state)
{
BCM_LOG(INFO, log_id_interface,
"access terminal admin-state is DOWN\n");
ret = BCM_ERR_INVALID_OP;
break;
}
/* Get the index to the interface array from port id/type */
interface_index = bcmbal_port_type_and_id_to_interface_index (p_intf_key->intf_type, p_intf_key->intf_id);
if (interface_index >= INVALID_INTERFACE_INDEX)
{
BCM_LOG(ERROR, log_id_access_terminal,
"INVALID port type/id (%s/%d) to interface index (%d) for access terminal\n",
interface_type_str_get(p_intf_key->intf_type), p_intf_key->intf_id, interface_index);
ret = BCM_ERR_PARM;
break;
}
/*
* This is a pointer to the "API interface" structure
*/
p_api_req_interface_info =
&(p_access_terminal_inst->intf_info.interface[interface_index].api_req_int_obj_info);
/*
* This is a pointer to the "current interface" structure
*/
p_current_interface_info =
&(p_access_terminal_inst->intf_info.interface[interface_index].current_int_obj_info);
/* If the state of the interface is in flux, then reject the SET request */
if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
(BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(p_current_interface_info)))
{
BCM_LOG(ERROR, log_id_access_terminal,
"The interface is in-progress, SETs are not allowed\n");
ret = BCM_ERR_IN_PROGRESS;
break;
}
}while(0);
if(BCM_ERR_OK != ret)
{
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
break;
}
/*
* Fill in the interface info SET data structure
*/
*p_api_req_interface_info = *p_intf_cfg;
BCM_LOG(DEBUG, log_id_interface,
" interface object state from API message is: %d, intf_type: %s intf_id: %d\n",
p_api_req_interface_info->data.admin_state,
interface_type_str_get(p_api_req_interface_info->key.intf_type),
p_api_req_interface_info->key.intf_id);
/* SET or GET or ...? */
switch (oper_type)
{
case (BCMBAL_OBJ_MSG_TYPE_SET):
{
BCM_LOG(DEBUG, log_id_interface,
"Processing an interface SET REQ mgmt message\n");
/*if sched is already set, can not change sched setting using set command, should first delete current sched*/
if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,ds_tm)
&& BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,ds_tm))
{
BCM_LOG(ERROR, log_id_interface,
"ds_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
p_current_interface_info->data.ds_tm);
ret = BCM_ERR_ALREADY;
break;
}
if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,us_tm)
&& BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,us_tm))
{
BCM_LOG(ERROR, log_id_interface,
"us_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
p_current_interface_info->data.us_tm);
ret = BCM_ERR_ALREADY;
break;
}
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
if(BCM_ERR_OK != ret)
{
break;
}
/* If this interface is already up, then just return OK */
if(BCMBAL_STATE_UP == p_api_req_interface_info->data.admin_state)
{
if(BCMBAL_STATUS_UP == p_current_interface_info->data.oper_status)
{
BCM_LOG(DEBUG, log_id_interface,
"=====> Received an interface UP for an already UP interface, returning OK\n");
break;
}
/*validate and set the interface' tm sched*/
bcmbal_interface_object_overlay_w_dst_priority(p_api_req_interface_info,p_current_interface_info);
ret = interface_tm_sched_set(p_api_req_interface_info);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface,"Could not set the interface tm sched\n");
break;
}
interface_admin_up_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
msg_payload);
}
else
{
if(BCMBAL_STATUS_DOWN == p_current_interface_info->data.oper_status)
{
BCM_LOG(DEBUG, log_id_interface,
"=====> Received an interface DOWN for an already DOWN interface, returning OK\n");
break;
}
interface_admin_dn_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
msg_payload);
}
break;
}
case (BCMBAL_OBJ_MSG_TYPE_GET):
{
BCM_LOG(DEBUG, log_id_interface,
"Processing a interface GET REQ mgmt message\n");
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
p_current_interface_info->hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
bcmbal_sub_id_list_u16 sub_term_id_list = {};
BCMBAL_CFG_PROP_CLEAR(p_current_interface_info,
interface,
sub_term_id_list);
/* If the user requested the list of sub_term_ids for this interface,
* and this is a PON interface, then return the list.
*/
if(BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,
interface,
sub_term_id_list))
{
if(BCMBAL_INTF_TYPE_PON == p_current_interface_info->key.intf_type)
{
sub_term_id_list_fill(interface_index, &sub_term_id_list);
/* NOTE: The returned list may be empty */
BCMBAL_CFG_PROP_SET(p_current_interface_info,
interface,
sub_term_id_list,
sub_term_id_list);
}
}
*((bcmbal_interface_cfg *)msg_payload) = *p_current_interface_info;
mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
/* Free the temporary list if it was used */
if(sub_term_id_list.val)
{
bcmos_free(sub_term_id_list.val);
}
break;
}
default:
{
BCM_LOG(ERROR, log_id_interface,
"Unsupported operation on interface object (%d)\n",
bcmbal_msg_id_oper_get(msg_payload));
ret = BCM_ERR_NOT_SUPPORTED;
/* We respond to the BAL public API backend with a result. We always
* send a complete msg_payload back to the API, but the data portion
* of the object is only relevant when a GET or GET-STATS has been requested.
*/
mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
break;
}
}
}while (0);
return ret;
}
/*****************************************************************************/
/**
* @brief A function called to initialize a single access-terminal instance.
* NOTE: This is called once on startup and NOT for each FSM instance.
*
* @param p_acc_term_inst Pointer to an access terminal instance
*
* @returns void
*****************************************************************************/
static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst)
{
int ii;
int intf_id;
bcmos_errno ret;
BUG_ON(NULL == p_acc_term_inst);
p_acc_term_inst->current_acc_term_obj_info.key.access_term_id = 0;
BCMBAL_CFG_INIT(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
p_acc_term_inst->current_acc_term_obj_info.key);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
admin_state,
BCMBAL_STATE_DOWN);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
oper_status,
BCMBAL_STATUS_DOWN);
BCMBAL_PROP_SET_PRESENT(&p_acc_term_inst->current_acc_term_obj_info,
access_terminal,
_cfg,
iwf_mode);
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
{
bcmbal_interface_key key;
intf_id = 0; /* reset the port id to the starting id value for the PON interfaces */
key.intf_type = BCMBAL_INTF_TYPE_PON;
for(ii=0; ii<NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii++)
{
key.intf_id = intf_id;
p_acc_term_inst->intf_info.interface[ii].num_sub_terms_on_int = 0;
TAILQ_INIT(&p_acc_term_inst->intf_info.interface[ii].sub_term_id_list);
BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
key);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
admin_state,
BCMBAL_STATE_DOWN);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
oper_status,
BCMBAL_STATUS_DOWN);
ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for pon if %d", intf_id);
break;
}
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
intf_id++;
}
intf_id = 0; /* reset the port id to the starting id value for the NNI interfaces */
key.intf_type = BCMBAL_INTF_TYPE_NNI;
for(ii=NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii<(NUM_SUPPORTED_SUBSCRIBER_INTERFACES + bal_config_params.num_nni_ports); ii++)
{
key.intf_id = intf_id;
BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
key);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
admin_state,
BCMBAL_STATE_UP);
BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
interface,
oper_status,
BCMBAL_STATUS_UP);
ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
if(BCM_ERR_OK != ret)
{
BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for nni if %d", intf_id);
break;
}
BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
intf_id++;
}
}
}
bcmos_errno bcmbal_interface_sub_term_list_entry_add(bcmbal_subscriber_terminal_key sub_term_key)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_inst *p_access_terminal_inst;
sub_term_id_entry *current_entry;
acc_term_interface *p_interface;
p_access_terminal_inst = access_terminal_get();
do
{
/*
* If the specified access terminal is not active then it's interfaces are down.
*/
if(NULL == p_access_terminal_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,
"no such ACTIVE access terminal\n");
ret = BCM_ERR_STATE;
break;
}
p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
/* Check if the id is already on the list before adding it */
TAILQ_FOREACH(current_entry,
&p_interface->sub_term_id_list,
next)
{
if(current_entry->sub_term_id == sub_term_key.sub_term_id)
{
return BCM_ERR_ALREADY;
}
}
/* Get a new entry and configure it */
current_entry = bcmos_calloc(sizeof(sub_term_id_entry));
if (NULL == current_entry)
{
BCM_LOG(ERROR, log_id_access_terminal,
"No memory available\n");
ret = BCM_ERR_NOMEM;
break;
}
current_entry->sub_term_id = sub_term_key.sub_term_id;
BCM_LOG(INFO, log_id_access_terminal,
"adding sub_term id %u to interface %u\n", sub_term_key.sub_term_id, sub_term_key.intf_id);
/* Save the entry on the list of subscriber-terminal ids on this interface */
TAILQ_INSERT_TAIL(&p_interface->sub_term_id_list,
current_entry, next);
(p_interface->num_sub_terms_on_int)++;
} while (0);
return ret;
}
bcmos_errno bcmbal_interface_sub_term_list_entry_remove(bcmbal_subscriber_terminal_key sub_term_key)
{
bcmos_errno ret = BCM_ERR_NOENT;
acc_term_inst *p_access_terminal_inst;
acc_term_interface *p_interface;
sub_term_id_entry *current_entry, *p_temp_entry;
do
{
p_access_terminal_inst = access_terminal_get();
/*
* If the specified access terminal is not active then it's interfaces are down.
*/
if(NULL == p_access_terminal_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,
"no such ACTIVE access terminal\n");
ret = BCM_ERR_STATE;
break;
}
p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
/* Check if the id is on the list */
TAILQ_FOREACH_SAFE(current_entry,
&p_interface->sub_term_id_list,
next,
p_temp_entry)
{
if(current_entry->sub_term_id == sub_term_key.sub_term_id)
{
/* Remove it from the list of subscriber-terminal ids on this interface */
TAILQ_REMOVE(&p_interface->sub_term_id_list,
current_entry, next);
bcmos_free(current_entry);
(p_interface->num_sub_terms_on_int)--;
ret = BCM_ERR_OK;
break;
}
}
} while (0);
return ret;
}
static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
bcmbal_sub_id_list_u16 *sub_term_id_list)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_inst *p_acc_term_inst;
sub_term_id_entry *current_entry = NULL;
int ii = 0;
do
{
/*
* See if the access-terminal is active
*/
p_acc_term_inst = access_terminal_get();
/*
* If the specified access terminal is not active then it's interfaces are down.
*/
if(NULL == p_acc_term_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,
"no such ACTIVE access terminal\n");
ret = BCM_ERR_NOENT;
break;
}
/* Traverse the list of sub_term_ids recorded and fill in the list to be returned */
sub_term_id_list->len = p_acc_term_inst->intf_info.interface[interface_index].num_sub_terms_on_int;
sub_term_id_list->val = bcmos_calloc(sizeof(bcmbal_sub_id) * sub_term_id_list->len);
if (NULL == sub_term_id_list->val)
{
BCM_LOG(ERROR, log_id_access_terminal,
"No memory available\n");
ret = BCM_ERR_NOMEM;
break;
}
TAILQ_FOREACH(current_entry,
&p_acc_term_inst->intf_info.interface[interface_index].sub_term_id_list,
next)
{
BCM_LOG(DEBUG, log_id_access_terminal,
"adding sub_term_id %u to response at array location %u\n",
current_entry->sub_term_id,
ii);
sub_term_id_list->val[ii++] = current_entry->sub_term_id;
}
} while (0);
return ret;
}
bcmos_errno bcmbal_interface_tm_get(bcmbal_interface_key key, bcmbal_tm_sched_id *id)
{
bcmos_errno ret = BCM_ERR_OK;
acc_term_inst *p_acc_term_inst;
uint32_t interface_index = INVALID_INTERFACE_INDEX;
do
{
/* See if the access-terminal is active */
p_acc_term_inst = access_terminal_get();
/* If the specified access terminal is not active then it's interfaces are down. */
if(NULL == p_acc_term_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,"no such ACTIVE access terminal\n");
ret = BCM_ERR_NOT_CONNECTED;
break;
}
/* If the specified access terminal is down, then it's interfaces are down. */
if(BCMBAL_STATE_UP != p_acc_term_inst->current_acc_term_obj_info.data.admin_state)
{
ret = BCM_ERR_NOT_CONNECTED;
break;
}
/* first get the index to the interface array from port id/type */
interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
if (interface_index >= INVALID_INTERFACE_INDEX)
{
BCM_LOG(ERROR, log_id_access_terminal,"INVALID port type/id (%s/%d) to interface index (%d)\n",
interface_type_str_get(key.intf_type), key.intf_id, interface_index);
ret = BCM_ERR_INTERNAL;
break;
}
/* Retrieve the relevany default tm sched of the interface */
if (BCMBAL_INTF_TYPE_NNI == key.intf_type)
{
*id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.us_tm;
}
else /*BCMBAL_INTF_TYPE_PON */
{
*id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.ds_tm;
}
}while(0);
return ret;
}
/*****************************************************************************/
/**
* @brief A function that returns the status of the specified interface object
*
* @param key An interface instance key
*
* @returns bcmbal_state
*****************************************************************************/
bcmbal_status bcmbal_interface_status_get(bcmbal_interface_key key)
{
bcmbal_state intf_status = BCMBAL_STATUS_DOWN;
acc_term_interface *p_acc_term_interface = bcmbal_interface_get(key);
if(NULL == p_acc_term_interface)
{
BCM_LOG(ERROR, log_id_access_terminal,"no such interface\n");
}
else
{
intf_status = p_acc_term_interface->current_int_obj_info.data.oper_status;
}
return intf_status;
}
/*****************************************************************************/
/**
* @brief A function that returns the interface object
*
* @param key An interface instance key
*
* @returns acc_term_interface *p_acc_term_interface a pointer to the interface object
*****************************************************************************/
static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key)
{
acc_term_inst *p_acc_term_inst = NULL;
acc_term_interface *p_acc_term_interface = NULL;
uint32_t interface_index = INVALID_INTERFACE_INDEX;
do
{
/*
* See if the access-terminal is active
*/
p_acc_term_inst = access_terminal_get();
/*
* If the specified access terminal is not active then it's interfaces are down.
*/
if(NULL == p_acc_term_inst)
{
BCM_LOG(ERROR, log_id_access_terminal,
"no such ACTIVE access terminal\n");
break;
}
/*
* Retrieve the interface
*/
/* first get the index to the interface array from port id/type */
interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
if (interface_index >= INVALID_INTERFACE_INDEX)
{
BCM_LOG(ERROR, log_id_access_terminal,
"INVALID port type/id (%s/%d) to interface index (%d)\n",
interface_type_str_get(key.intf_type), key.intf_id, interface_index);
break;
}
p_acc_term_interface = &(p_acc_term_inst->intf_info.interface[interface_index]);
}while(0);
return p_acc_term_interface;
}
static char *interface_type_str_get(bcmbal_intf_type intf_type)
{
return intf_type == BCMBAL_INTF_TYPE_NNI ? "NNI" :
intf_type == BCMBAL_INTF_TYPE_PON ? "PON" : "UNKNOWN TYPE";
}
/*@}*/