blob: dab93cb243bff0db97d902fc236e820a279c1d91 [file] [log] [blame]
/*
<:copyright-BRCM:2016:DUAL/GPL:standard
Broadcom Proprietary and Confidential.(c) 2016 Broadcom
All Rights Reserved
Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:
As a special exception, the copyright holders of this software give
you permission to link this software with independent modules, and
to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent
module, the terms and conditions of the license of that module.
An independent module is a module which is not derived from this
software. The special exception does not apply to any modifications
of the software.
Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.
:>
*/
#include <bcmos_system.h>
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcm_dev_log.h>
#include <bcmos_common.h>
#include "bcmolt_user_appl_ps.h"
#include "bcmolt_user_appl_ps_internal.h"
static bcmos_errno ps_handle_ni_no_reports(bcmolt_ps_global_cfg * global_cfg, const bcmolt_ps_pon *pon, const bcmolt_epon_ni_no_reports * ind)
{
if (ind->data.alarm_status == BCMOLT_STATUS_OFF)
{
PS_INFO("<%d:%d> LoS alarm cleared\n", pon->device_id, pon->pon_id);
return BCM_ERR_OK;
}
PS_INFO("<%d:%d> LoS alarm raised\n", pon->device_id, pon->pon_id);
if (global_cfg->switch_condition == BCMOLT_PS_SWITCH_CONDITION_MANUAL)
{
/* don't react to the switch if we're in manual switch mode */
return BCM_ERR_OK;
}
else
{
return bcmolt_ps_switch_perform(pon);
}
}
static bcmos_errno ps_handle_logical_link_discovered(bcmolt_ps_global_cfg * global_cfg, const bcmolt_ps_pon *pon, const bcmolt_epon_link_mpcp_discovered * ind)
{
bcmolt_ps_pon_state state;
bcmolt_ps_pon partner;
bcmos_errno result;
if (global_cfg->mirror_mode != BCMOLT_PS_MIRROR_MODE_AUTO)
{
return BCM_ERR_OK;
}
//At this point we know we have a link discovered on a PON that is in the PROTECTED WORKING state.
//This means we want to make sure that is is setup on the PROCTECTED STANDBY PON. It is possible
//That this link has been previously configured on the STANDBY PON so we have to handle that case
//gracefully as well.
result = bcmolt_ps_pon_state_get(pon, &state, &partner);
PS_INFO("pon %d, bcmolt_ps_pon_state_get result == %d, state == %d, partner.pon_id == %d\n", pon->pon_id, result, state, partner.pon_id);
if ((BCM_ERR_OK == result) && (state == BCMOLT_PS_PON_STATE_WORKING))
{
bcmolt_epon_ni_add_protected_standby_link add_standby = {};
bcmolt_epon_ni_key key = {};
PS_INFO("Mirroring received link discovered on working PON\n");
key.epon_ni = (bcmolt_epon_ni)partner.pon_id; //Setup the standby PON as the location to add the link.
//Setup operation key for api call.
BCMOLT_OPER_INIT(&add_standby, epon_ni, add_protected_standby_link, key);
//Copy over the data from the received messages:
BCMOLT_OPER_PROP_SET(&add_standby, epon_ni, add_protected_standby_link, mac_address, ind->key.mac_address);
BCMOLT_OPER_PROP_SET(&add_standby, epon_ni, add_protected_standby_link, working_link_info, ind->data.link_info);
result = bcmolt_oper_submit(partner.device_id, &add_standby.hdr);
//We have multiple acceptable return codes here:
// BCM_ERR_OK - Indicates new entry created.
// BCM_ERR_ALREADY - Indicates the entry already exists (possible after deregistration/reregistration).
PS_INFO("Mirroring add protected standby link result %d\n", result);
if ( (result == BCM_ERR_OK) || (result == BCM_ERR_ALREADY) )
{
bcmolt_epon_link_static_registration static_reg = {};
bcmolt_epon_link_key link_key = {};
link_key.epon_ni = (bcmolt_epon_ni)partner.pon_id;
link_key.mac_address = ind->key.mac_address;
//Setup operation key for api call.
BCMOLT_OPER_INIT(&static_reg, epon_link, static_registration, link_key);
BCMOLT_OPER_PROP_SET(&static_reg, epon_link, static_registration, laseron_time_tq, ind->data.link_info.onu_laser_on_time_tq);
BCMOLT_OPER_PROP_SET(&static_reg, epon_link, static_registration, laseroff_time_tq, ind->data.link_info.onu_laser_off_time_tq);
BCMOLT_OPER_PROP_SET(&static_reg, epon_link, static_registration, range_value_tq, ind->data.link_info.range_value_tq);
BCMOLT_OPER_PROP_SET(&static_reg, epon_link, static_registration, pending_grants, ind->data.link_info.pending_grants);
result = bcmolt_oper_submit(partner.device_id, &static_reg.hdr);
if (result != BCM_ERR_OK)
{
PS_ERR("Static registration failed %d\n", result);
}
else
{
PS_INFO("Static registration success\n");
}
}
else
{
PS_ERR("Add protected standby failed %d\n", result);
}
}
return BCM_ERR_OK;
}
bcmos_errno ps_process_ind_epon(const bcmolt_ps_pon *pon, const bcmolt_auto *ind)
{
bcmos_errno err;
bcmolt_ps_global_cfg global_cfg;
err = bcmolt_ps_global_cfg_get(&global_cfg);
if (err != BCM_ERR_OK)
{
return err;
}
PS_INFO("ps_process_ind_epon Type: %d CFG_ID: %d\n", ind->hdr.obj_type, ind->hdr.subgroup);
switch (ind->hdr.obj_type)
{
case BCMOLT_OBJ_ID_EPON_NI:
switch (ind->hdr.subgroup)
{
case BCMOLT_EPON_NI_AUTO_CFG_ID_NO_REPORTS:
return ps_handle_ni_no_reports(&global_cfg, pon, ((const bcmolt_epon_ni_no_reports *)ind));
default:
return BCM_ERR_OK;
}
case BCMOLT_OBJ_ID_EPON_LINK:
switch (ind->hdr.subgroup)
{
case BCMOLT_EPON_LINK_AUTO_CFG_ID_MPCP_DISCOVERED:
return ps_handle_logical_link_discovered(&global_cfg, pon, ((const bcmolt_epon_link_mpcp_discovered *)ind));
default:
return BCM_ERR_OK;
}
default:
return BCM_ERR_OK;
}
return BCM_ERR_OK;
}
bcmos_errno ps_move_to_standby_epon(const bcmolt_ps_pon *pon)
{
bcmolt_epon_ni_set_epon_ni_en_state set_pon_state;
bcmolt_epon_ni_key key = {};
key.epon_ni = pon->pon_id;
BCMOLT_OPER_INIT(&set_pon_state, epon_ni, set_epon_ni_en_state, key);
BCMOLT_OPER_PROP_SET(&set_pon_state, epon_ni, set_epon_ni_en_state, new_state, BCMOLT_EPON_NI_EN_STATE_PROTECTED_STANDBY);
return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
}
bcmos_errno ps_move_to_working_epon(const bcmolt_ps_pon *pon)
{
bcmolt_epon_ni_set_epon_ni_en_state set_pon_state;
bcmolt_epon_ni_key key = {};
key.epon_ni = pon->pon_id;
BCMOLT_OPER_INIT(&set_pon_state, epon_ni, set_epon_ni_en_state, key);
BCMOLT_OPER_PROP_SET(&set_pon_state, epon_ni, set_epon_ni_en_state, new_state, BCMOLT_EPON_NI_EN_STATE_PROTECTED_WORKING);
return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
}