| /* |
| <: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 <bcmolt_host_api.h> |
| #include "bcmolt_user_appl_ps.h" |
| #include "bcmolt_user_appl_ps_internal.h" |
| |
| static bcmos_errno ps_handle_ni_los( |
| const bcmolt_ps_global_cfg *global_cfg, |
| const bcmolt_ps_pon *pon, |
| const bcmolt_xgpon_ni_los *ind) |
| { |
| if (ind->data.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_ni_state_changed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_ni_state_change_completed *ind) |
| { |
| bcmolt_xgpon_ni_key key = { partner->pon_id }; |
| bcmolt_xgpon_ni_set_pon_state oper; |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_ni, set_pon_state, key); |
| |
| if (ind->data.previous_state == BCMOLT_PON_STATE_INACTIVE && |
| ind->data.new_state == BCMOLT_PON_STATE_ACTIVE_WORKING) |
| { |
| PS_INFO("%s: activating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY); |
| } |
| else if (ind->data.previous_state == BCMOLT_PON_STATE_ACTIVE_WORKING && |
| ind->data.new_state == BCMOLT_PON_STATE_INACTIVE) |
| { |
| PS_INFO("%s: deactivating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_INACTIVE); |
| } |
| else |
| { |
| /* only change the standby PON's state if we're pre-provisioning the working PON |
| (the switchover is handled separately) */ |
| return BCM_ERR_OK; |
| } |
| |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| static bcmos_errno ps_handle_ni_traffic_resume( |
| const bcmolt_ps_pon *pon, |
| const bcmolt_xgpon_ni_protection_switching_traffic_resume *ind) |
| { |
| uint32_t after_us = bcmos_timestamp(); |
| uint32_t before_us = ps_get_last_switch_start_time_us(); |
| uint32_t time_taken_us = (after_us > before_us) ? after_us - before_us : before_us - after_us; |
| const char *traffic_resume_result_str = NULL; |
| |
| switch (ind->data.result) |
| { |
| case BCMOLT_TRAFFIC_RESUME_RESULT_SUCCESS: |
| traffic_resume_result_str = "success"; |
| break; |
| case BCMOLT_TRAFFIC_RESUME_RESULT_FAILURE: |
| traffic_resume_result_str = "failure"; |
| break; |
| case BCMOLT_TRAFFIC_RESUME_RESULT_SUSPECTED_LOS: |
| traffic_resume_result_str = "suspected_los"; |
| break; |
| default: |
| break; |
| } |
| |
| PS_INFO( |
| "<%d:%d> Traffic resume %s. Time since start of switch: %d ms.\n", |
| pon->device_id, |
| pon->pon_id, |
| traffic_resume_result_str, |
| time_taken_us / 1000); |
| |
| return BCM_ERR_OK; |
| } |
| |
| static bcmos_errno ps_handle_ni_onus_ranged( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_ni_protection_switching_onus_ranged *ind) |
| { |
| uint32_t i; |
| bcmos_errno last_err = BCM_ERR_OK; |
| |
| /* apply all of the new ONU EQDs to the standby PON */ |
| for (i = 0; i < ind->data.onus.len; i++) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->data.onus.val[i].onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmos_errno err; |
| |
| PS_INFO( |
| "%s: updating EQD <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.onus.val[i].eqd); |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.onus.val[i].eqd); |
| err = bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| if (err != BCM_ERR_OK) |
| { |
| PS_ERR("EQD update failed: %s\n", bcmos_strerror(err)); |
| last_err = err; |
| } |
| } |
| |
| return last_err; |
| } |
| |
| static bcmos_errno ps_handle_onu_ranging_completed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_ranging_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| |
| /* only react to success indications */ |
| if (ind->data.status != BCMOLT_RESULT_SUCCESS) |
| { |
| return BCM_ERR_OK; |
| } |
| |
| PS_INFO( |
| "%s: updating EQD <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.eqd); |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.eqd); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_key_exchange_completed( |
| const bcmolt_ps_pon *pon, |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_key_exchange_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| |
| PS_INFO("%s: updating AES key <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id); |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, current_encryption_key, ind->data.new_key); |
| return bcmolt_cfg_set(pon->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_activation_completed( |
| const bcmolt_ps_pon *pon, |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_onu_activation_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_set_onu_state oper; |
| bcmos_errno err; |
| |
| /* only react to success indications */ |
| if (ind->data.status != BCMOLT_RESULT_SUCCESS) |
| { |
| return BCM_ERR_OK; |
| } |
| |
| PS_INFO( |
| "%s: provisioning registration ID / keys for newly-activated ONU <%d:%d> ONU %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id); |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id, ind->data.registration_id); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_encryption_keys, ind->data.registration_encryption_keys); |
| err = bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| PS_INFO("%s: activating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id); |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ACTIVE); |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_deactivation_completed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_onu_deactivation_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_set_onu_state oper; |
| |
| /* Note: we react to this indication whether or not the deactivation was successful. Failure indicates that the |
| * ONU didn't respond to the deactivation, but we still remove the ONU from OLT hardware so it must be mirrored. */ |
| |
| PS_INFO("%s: deactivating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id); |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_INACTIVE); |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_enable_completed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_onu_enable_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_set_onu_state oper; |
| |
| /* don't try to mirror broadcast enable/disable */ |
| if (key.onu_id == BCMOLT_XGPON_ONU_ID_INVALID) |
| { |
| return BCM_ERR_OK; |
| } |
| |
| PS_INFO("%s: enabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id); |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ENABLE); |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_disable_completed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_onu_onu_disable_completed *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_set_onu_state oper; |
| |
| /* don't try to mirror broadcast enable/disable */ |
| if (key.onu_id == BCMOLT_XGPON_ONU_ID_INVALID) |
| { |
| return BCM_ERR_OK; |
| } |
| |
| PS_INFO("%s: disabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id); |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_DISABLE); |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| static void ps_alarm_state_init(bcmolt_xgpon_onu_alarm_state *alarm_state) |
| { |
| alarm_state->losi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->lobi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->lopci = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->lopci_mic_error = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->looci = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->tiwi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->dowi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->sufi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->sfi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->sdi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->dfi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->dgi = BCMOLT_STATUS_NO_CHANGE; |
| alarm_state->pqsi = BCMOLT_STATUS_NO_CHANGE; |
| } |
| |
| static bcmos_errno ps_handle_onu_alarm(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_onu_alarm *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.losi = ind->data.onu_alarm.losi; |
| alarm_state.lobi = ind->data.onu_alarm.lobi; |
| alarm_state.lopci = ind->data.onu_alarm.lopci_miss; |
| alarm_state.lopci_mic_error = ind->data.onu_alarm.lopci_mic_error; |
| |
| PS_INFO( |
| "%s: updating ONU alarms <%d:%d> ONU %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id); |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_dowi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_dowi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating DOWi <%d:%d> ONU %d -> %d (EQD %d)\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status, |
| ind->data.new_eqd); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.dowi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| |
| if (ind->data.alarm_status == BCMOLT_STATUS_ON) |
| { |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.new_eqd); |
| } |
| |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_sfi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sfi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating SFI <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.sfi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_sdi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sdi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating SDi <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.sdi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_dfi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_dfi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating DFi <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.dfi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_sufi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sufi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating SUFi <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.sufi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_tiwi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_tiwi *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating TIWi <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.tiwi = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_onu_looci(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_looci *ind) |
| { |
| bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id }; |
| bcmolt_xgpon_onu_cfg cfg; |
| bcmolt_xgpon_onu_alarm_state alarm_state; |
| |
| PS_INFO( |
| "%s: updating LOOCi <%d:%d> ONU %d -> %d\n", |
| __FUNCTION__, |
| partner->device_id, |
| key.pon_ni, |
| key.onu_id, |
| ind->data.alarm_status); |
| |
| ps_alarm_state_init(&alarm_state); |
| alarm_state.looci = ind->data.alarm_status; |
| |
| BCMOLT_CFG_INIT(&cfg, xgpon_onu, key); |
| BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state); |
| return bcmolt_cfg_set(partner->device_id, &cfg.hdr); |
| } |
| |
| static bcmos_errno ps_handle_alloc_id_configuration_completed( |
| const bcmolt_ps_pon *partner, |
| const bcmolt_xgpon_alloc_configuration_completed *ind) |
| { |
| bcmolt_xgpon_alloc_key key = { partner->pon_id, ind->key.alloc_id }; |
| bcmolt_xgpon_alloc_set_state oper; |
| |
| BCMOLT_OPER_INIT(&oper, xgpon_alloc, set_state, key); |
| |
| if (ind->data.new_state == BCMOLT_ALLOC_STATE_ACTIVE) |
| { |
| /* only react to success indications */ |
| if (ind->data.status != BCMOLT_RESULT_SUCCESS) |
| { |
| return BCM_ERR_OK; |
| } |
| |
| PS_INFO("%s: activating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_ACTIVATE); |
| } |
| else if (ind->data.new_state == BCMOLT_ALLOC_STATE_INACTIVE) |
| { |
| PS_INFO("%s: deactivating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id); |
| BCMOLT_OPER_PROP_SET(&oper, xgpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_DEACTIVATE); |
| } |
| else /* ind->data.new_state is something else (e.g. unprovisioned, if the alloc was cleared) */ |
| { |
| return BCM_ERR_OK; |
| } |
| |
| return bcmolt_oper_submit(partner->device_id, &oper.hdr); |
| } |
| |
| bcmos_errno ps_process_ind_xgpon(const bcmolt_ps_pon *pon, const bcmolt_auto *ind) |
| { |
| bcmos_errno err; |
| bcmolt_ps_pon_state state; |
| bcmolt_ps_pon partner; |
| bcmolt_ps_global_cfg global_cfg; |
| |
| err = bcmolt_ps_global_cfg_get(&global_cfg); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| if (global_cfg.mirror_mode != BCMOLT_PS_MIRROR_MODE_AUTO && |
| ind->hdr.subgroup != BCMOLT_XGPON_NI_AUTO_ID_LOS) |
| { |
| /* only handle most indications while in mirror mode 'auto', but perform a switchover on LoS in any case */ |
| return BCM_ERR_OK; |
| } |
| |
| err = bcmolt_ps_pon_state_get(pon, &state, &partner); |
| if (err != BCM_ERR_OK) |
| { |
| return err; |
| } |
| |
| if (state != BCMOLT_PS_PON_STATE_WORKING) |
| { |
| return BCM_ERR_OK; /* ignore indications from PONs that aren't protected working */ |
| } |
| |
| switch (ind->hdr.obj_type) |
| { |
| case BCMOLT_OBJ_ID_XGPON_NI: |
| switch (ind->hdr.subgroup) |
| { |
| case BCMOLT_XGPON_NI_AUTO_ID_LOS: |
| return ps_handle_ni_los(&global_cfg, pon, ((const bcmolt_xgpon_ni_los *)ind)); |
| case BCMOLT_XGPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED: |
| return ps_handle_ni_state_changed(&partner, ((const bcmolt_xgpon_ni_state_change_completed *)ind)); |
| case BCMOLT_XGPON_NI_AUTO_ID_PROTECTION_SWITCHING_TRAFFIC_RESUME: |
| return ps_handle_ni_traffic_resume(pon, ((const bcmolt_xgpon_ni_protection_switching_traffic_resume *)ind)); |
| case BCMOLT_XGPON_NI_AUTO_ID_PROTECTION_SWITCHING_ONUS_RANGED: |
| return ps_handle_ni_onus_ranged(&partner, ((const bcmolt_xgpon_ni_protection_switching_onus_ranged *)ind)); |
| default: |
| return BCM_ERR_OK; /* silently ignore all other NI indications */ |
| } |
| |
| case BCMOLT_OBJ_ID_XGPON_ONU: |
| switch (ind->hdr.subgroup) |
| { |
| case BCMOLT_XGPON_ONU_AUTO_ID_RANGING_COMPLETED: |
| return ps_handle_onu_ranging_completed(&partner, ((const bcmolt_xgpon_onu_ranging_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_KEY_EXCHANGE_COMPLETED: |
| return ps_handle_onu_key_exchange_completed( |
| pon, |
| &partner, |
| ((const bcmolt_xgpon_onu_key_exchange_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ACTIVATION_COMPLETED: |
| return ps_handle_onu_activation_completed( |
| pon, |
| &partner, |
| ((const bcmolt_xgpon_onu_onu_activation_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_ONU_DEACTIVATION_COMPLETED: |
| return ps_handle_onu_deactivation_completed( |
| &partner, |
| ((const bcmolt_xgpon_onu_onu_deactivation_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ENABLE_COMPLETED: |
| return ps_handle_onu_enable_completed(&partner, ((const bcmolt_xgpon_onu_onu_enable_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_ONU_DISABLE_COMPLETED: |
| return ps_handle_onu_disable_completed(&partner, ((const bcmolt_xgpon_onu_onu_disable_completed *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ALARM: |
| return ps_handle_onu_alarm(&partner, ((const bcmolt_xgpon_onu_onu_alarm *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_DOWI: |
| return ps_handle_onu_dowi(&partner, ((const bcmolt_xgpon_onu_dowi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_SFI: |
| return ps_handle_onu_sfi(&partner, ((const bcmolt_xgpon_onu_sfi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_SDI: |
| return ps_handle_onu_sdi(&partner, ((const bcmolt_xgpon_onu_sdi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_DFI: |
| return ps_handle_onu_dfi(&partner, ((const bcmolt_xgpon_onu_dfi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_SUFI: |
| return ps_handle_onu_sufi(&partner, ((const bcmolt_xgpon_onu_sufi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_TIWI: |
| return ps_handle_onu_tiwi(&partner, ((const bcmolt_xgpon_onu_tiwi *)ind)); |
| case BCMOLT_XGPON_ONU_AUTO_ID_LOOCI: |
| return ps_handle_onu_looci(&partner, ((const bcmolt_xgpon_onu_looci *)ind)); |
| default: |
| return BCM_ERR_OK; /* silently ignore all other ONU indications */ |
| } |
| |
| case BCMOLT_OBJ_ID_XGPON_ALLOC: |
| switch (ind->hdr.subgroup) |
| { |
| case BCMOLT_XGPON_ALLOC_AUTO_ID_CONFIGURATION_COMPLETED: |
| return ps_handle_alloc_id_configuration_completed( |
| &partner, |
| ((const bcmolt_xgpon_alloc_configuration_completed *)ind)); |
| default: |
| return BCM_ERR_OK; /* silently ignore all other alloc indications */ |
| } |
| |
| default: |
| return BCM_ERR_NOT_SUPPORTED; /* someone else needs to handle this indication */ |
| } |
| } |
| |
| bcmos_errno ps_move_to_standby_xgpon(const bcmolt_ps_pon *pon) |
| { |
| bcmolt_xgpon_ni_set_pon_state set_pon_state; |
| bcmolt_xgpon_ni_key key = { (bcmolt_xgpon_ni)pon->pon_id }; |
| |
| BCMOLT_OPER_INIT(&set_pon_state, xgpon_ni, set_pon_state, key); |
| BCMOLT_OPER_PROP_SET(&set_pon_state, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY); |
| return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr); |
| } |
| |
| bcmos_errno ps_move_to_working_xgpon(const bcmolt_ps_pon *pon) |
| { |
| bcmolt_xgpon_ni_set_pon_state set_pon_state; |
| bcmolt_xgpon_ni_key key = { (bcmolt_xgpon_ni)pon->pon_id }; |
| |
| BCMOLT_OPER_INIT(&set_pon_state, xgpon_ni, set_pon_state, key); |
| BCMOLT_OPER_PROP_SET(&set_pon_state, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_WORKING); |
| return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr); |
| } |