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