blob: f43e7fb0dcc5ea55f044cf3c06d8451f4393b726 [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 <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_gpon_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_gpon_ni_state_change_completed *ind)
{
bcmolt_gpon_ni_key key = { partner->pon_id };
bcmolt_gpon_ni_set_pon_state oper;
BCMOLT_OPER_INIT(&oper, gpon_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, gpon_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, gpon_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_gpon_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_gpon_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_gpon_onu_key key = { partner->pon_id, ind->data.onus.val[i].onu_id };
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_ranging_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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 *partner,
const bcmolt_gpon_onu_key_exchange_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, aes_encryption_key, ind->data.new_key);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_password_authentication_completed(
const bcmolt_ps_pon *partner,
const bcmolt_gpon_onu_password_authentication_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
/* only react to success indications */
if (ind->data.status != BCMOLT_RESULT_SUCCESS)
{
return BCM_ERR_OK;
}
PS_INFO("%s: updating password <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, password, ind->data.password);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_activation_completed(
const bcmolt_ps_pon *partner,
const bcmolt_gpon_onu_onu_activation_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_set_onu_state oper;
/* only react to success indications */
if (ind->data.status != BCMOLT_RESULT_SUCCESS)
{
return BCM_ERR_OK;
}
PS_INFO("%s: activating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_deactivation_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_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, gpon_onu, set_onu_state, key);
BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_enable_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_set_onu_state oper;
/* don't try to mirror broadcast enable/disable */
if (key.onu_id == BCMOLT_GPON_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, gpon_onu, set_onu_state, key);
BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_disable_completed *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_set_onu_state oper;
/* don't try to mirror broadcast enable/disable */
if (key.onu_id == BCMOLT_GPON_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, gpon_onu, set_onu_state, key);
BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_alarm_state *alarm_state)
{
alarm_state->losi = BCMOLT_STATUS_NO_CHANGE;
alarm_state->lofi = BCMOLT_STATUS_NO_CHANGE;
alarm_state->loami = BCMOLT_STATUS_NO_CHANGE;
alarm_state->dgi = 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->loai = BCMOLT_STATUS_NO_CHANGE;
alarm_state->loki = BCMOLT_STATUS_NO_CHANGE;
}
static bcmos_errno ps_handle_onu_alarm(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_onu_alarm *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_onu_alarm_state alarm_state;
ps_alarm_state_init(&alarm_state);
alarm_state.losi = ind->data.onu_alarm.losi;
alarm_state.lofi = ind->data.onu_alarm.lofi;
alarm_state.loami = ind->data.onu_alarm.loami;
PS_INFO(
"%s: updating ONU alarms <%d:%d> ONU %d -> %d/%d/%d\n",
__FUNCTION__,
partner->device_id,
key.pon_ni,
key.onu_id,
alarm_state.losi,
alarm_state.lofi,
alarm_state.loami);
BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_dowi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
if (ind->data.alarm_status == BCMOLT_STATUS_ON)
{
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sfi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sdi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_dfi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sufi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_loai(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loai *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_onu_alarm_state alarm_state;
PS_INFO(
"%s: updating LOAi <%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.loai = ind->data.alarm_status;
BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_dgi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_dgi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_onu_alarm_state alarm_state;
PS_INFO(
"%s: updating DGi <%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.dgi = ind->data.alarm_status;
BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_tiwi *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_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, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_loki(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loki *ind)
{
bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
bcmolt_gpon_onu_cfg cfg;
bcmolt_gpon_onu_alarm_state alarm_state;
PS_INFO(
"%s: updating LOKi <%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.loki = ind->data.alarm_status;
BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_onu_omci_port_configuration_completed(
const bcmolt_ps_pon *partner,
const bcmolt_gpon_onu_omci_port_id_configuration_completed *ind)
{
bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->data.gem_port };
bcmolt_gpon_gem_port_set_state oper;
BCMOLT_OPER_INIT(&oper, gpon_gem_port, set_state, key);
if (ind->data.operation == BCMOLT_OMCI_PORT_ID_OPERATION_CONFIGURE)
{
/* don't react to unsuccessful activations */
if (ind->data.status != BCMOLT_RESULT_SUCCESS)
{
return BCM_ERR_OK;
}
PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
}
else
{
PS_INFO(
"%s: deactivating <%d:%d> GEM port ID %d\n",
__FUNCTION__,
partner->device_id,
key.pon_ni,
key.gem_port_id);
BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
}
return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}
static bcmos_errno ps_handle_mac_table_new_mac(
const bcmolt_ps_global_cfg *global_cfg,
const bcmolt_ps_pon *partner,
const bcmolt_gpon_iwf_mac_table_new_mac *ind)
{
bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
bcmolt_gpon_iwf_mac_table_cfg cfg;
if (!global_cfg->mirror_mac_entries)
{
return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
}
BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.flow_id);
if (global_cfg->static_mac_entries)
{
BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_TRUE);
}
else
{
BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_FALSE);
}
return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_mac_table_mac_aged(
const bcmolt_ps_global_cfg *global_cfg,
const bcmolt_ps_pon *partner,
const bcmolt_gpon_iwf_mac_table_mac_aged *ind)
{
bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
bcmolt_gpon_iwf_mac_table_cfg cfg;
if (!global_cfg->mirror_mac_entries)
{
return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
}
BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
return bcmolt_cfg_clear(partner->device_id, &cfg.hdr);
}
static bcmos_errno ps_handle_mac_table_mac_move(
const bcmolt_ps_global_cfg *global_cfg,
const bcmolt_ps_pon *partner,
const bcmolt_gpon_iwf_mac_table_mac_move *ind)
{
bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
bcmolt_gpon_iwf_mac_table_cfg cfg;
if (!global_cfg->mirror_mac_entries)
{
return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
}
BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.new_flow_id);
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_gpon_alloc_configuration_completed *ind)
{
bcmolt_gpon_alloc_key key = { partner->pon_id, ind->key.alloc_id };
bcmolt_gpon_alloc_set_state oper;
BCMOLT_OPER_INIT(&oper, gpon_alloc, set_state, key);
if (ind->data.new_state == BCMOLT_ALLOC_STATE_ACTIVE)
{
/* don't react to unsuccessful activations */
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, gpon_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, gpon_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);
}
static bcmos_errno ps_handle_gem_port_configuration_completed(
const bcmolt_ps_pon *partner,
const bcmolt_gpon_gem_port_configuration_completed *ind)
{
bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->key.gem_port_id };
bcmolt_gpon_gem_port_set_state oper;
BCMOLT_OPER_INIT(&oper, gpon_gem_port, set_state, key);
if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_ACTIVE)
{
/* don't react to unsuccessful activations */
if (ind->data.status != BCMOLT_RESULT_SUCCESS)
{
return BCM_ERR_OK;
}
PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
}
else if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_INACTIVE)
{
PS_INFO(
"%s: deactivating <%d:%d> GEM port ID %d\n",
__FUNCTION__,
partner->device_id,
key.pon_ni,
key.gem_port_id);
BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
}
else /* ind->data.new_state is something else (e.g. unprovisioned, if the GEM port was cleared) */
{
return BCM_ERR_OK;
}
return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}
bcmos_errno ps_process_ind_gpon(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_GPON_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_GPON_NI:
switch (ind->hdr.subgroup)
{
case BCMOLT_GPON_NI_AUTO_ID_LOS:
return ps_handle_ni_los(&global_cfg, pon, ((const bcmolt_gpon_ni_los *)ind));
case BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED:
return ps_handle_ni_state_changed(&partner, ((const bcmolt_gpon_ni_state_change_completed *)ind));
case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_TRAFFIC_RESUME:
return ps_handle_ni_traffic_resume(pon, ((const bcmolt_gpon_ni_protection_switching_traffic_resume *)ind));
case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_ONUS_RANGED:
return ps_handle_ni_onus_ranged(&partner, ((const bcmolt_gpon_ni_protection_switching_onus_ranged *)ind));
default:
return BCM_ERR_OK; /* silently ignore all other NI indications */
}
case BCMOLT_OBJ_ID_GPON_ONU:
switch (ind->hdr.subgroup)
{
case BCMOLT_GPON_ONU_AUTO_ID_RANGING_COMPLETED:
return ps_handle_onu_ranging_completed(&partner, ((const bcmolt_gpon_onu_ranging_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_KEY_EXCHANGE_COMPLETED:
return ps_handle_onu_key_exchange_completed(
&partner,
((const bcmolt_gpon_onu_key_exchange_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_PASSWORD_AUTHENTICATION_COMPLETED:
return ps_handle_onu_password_authentication_completed(
&partner,
((const bcmolt_gpon_onu_password_authentication_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_ONU_ACTIVATION_COMPLETED:
return ps_handle_onu_activation_completed(
&partner,
((const bcmolt_gpon_onu_onu_activation_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_ONU_DEACTIVATION_COMPLETED:
return ps_handle_onu_deactivation_completed(
&partner,
((const bcmolt_gpon_onu_onu_deactivation_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_ONU_ENABLE_COMPLETED:
return ps_handle_onu_enable_completed(&partner, ((const bcmolt_gpon_onu_onu_enable_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_ONU_DISABLE_COMPLETED:
return ps_handle_onu_disable_completed(&partner, ((const bcmolt_gpon_onu_onu_disable_completed *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_ONU_ALARM:
return ps_handle_onu_alarm(&partner, ((const bcmolt_gpon_onu_onu_alarm *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_DOWI:
return ps_handle_onu_dowi(&partner, ((const bcmolt_gpon_onu_dowi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_SFI:
return ps_handle_onu_sfi(&partner, ((const bcmolt_gpon_onu_sfi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_SDI:
return ps_handle_onu_sdi(&partner, ((const bcmolt_gpon_onu_sdi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_DFI:
return ps_handle_onu_dfi(&partner, ((const bcmolt_gpon_onu_dfi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_SUFI:
return ps_handle_onu_sufi(&partner, ((const bcmolt_gpon_onu_sufi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_LOAI:
return ps_handle_onu_loai(&partner, ((const bcmolt_gpon_onu_loai *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_DGI:
return ps_handle_onu_dgi(&partner, ((const bcmolt_gpon_onu_dgi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_TIWI:
return ps_handle_onu_tiwi(&partner, ((const bcmolt_gpon_onu_tiwi *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_LOKI:
return ps_handle_onu_loki(&partner, ((const bcmolt_gpon_onu_loki *)ind));
case BCMOLT_GPON_ONU_AUTO_ID_OMCI_PORT_ID_CONFIGURATION_COMPLETED:
return ps_handle_onu_omci_port_configuration_completed(
&partner,
((const bcmolt_gpon_onu_omci_port_id_configuration_completed *)ind));
default:
return BCM_ERR_OK; /* silently ignore all other ONU indications */
}
case BCMOLT_OBJ_ID_GPON_ALLOC:
switch (ind->hdr.subgroup)
{
case BCMOLT_GPON_ALLOC_AUTO_ID_CONFIGURATION_COMPLETED:
return ps_handle_alloc_id_configuration_completed(
&partner,
((const bcmolt_gpon_alloc_configuration_completed *)ind));
default:
return BCM_ERR_OK; /* silently ignore all other alloc indications */
}
case BCMOLT_OBJ_ID_GPON_GEM_PORT:
switch (ind->hdr.subgroup)
{
case BCMOLT_GPON_GEM_PORT_AUTO_ID_CONFIGURATION_COMPLETED:
return ps_handle_gem_port_configuration_completed(
&partner,
((const bcmolt_gpon_gem_port_configuration_completed *)ind));
default:
return BCM_ERR_OK; /* silently ignore all other GEM port indications */
}
case BCMOLT_OBJ_ID_GPON_IWF_MAC_TABLE:
switch (ind->hdr.subgroup)
{
case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_NEW_MAC:
return ps_handle_mac_table_new_mac(
&global_cfg,
&partner,
(const bcmolt_gpon_iwf_mac_table_new_mac *)ind);
case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_AGED:
return ps_handle_mac_table_mac_aged(
&global_cfg,
&partner,
(const bcmolt_gpon_iwf_mac_table_mac_aged *)ind);
case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_MOVE:
return ps_handle_mac_table_mac_move(
&global_cfg,
&partner,
(const bcmolt_gpon_iwf_mac_table_mac_move *)ind);
default:
return BCM_ERR_OK; /* silently ignore all other mac table indications */
}
default:
return BCM_ERR_NOT_SUPPORTED; /* someone else needs to handle this indication */
}
}
bcmos_errno ps_move_to_standby_gpon(const bcmolt_ps_pon *pon)
{
bcmolt_gpon_ni_set_pon_state set_pon_state;
bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };
BCMOLT_OPER_INIT(&set_pon_state, gpon_ni, set_pon_state, key);
BCMOLT_OPER_PROP_SET(&set_pon_state, gpon_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_gpon(const bcmolt_ps_pon *pon)
{
bcmolt_gpon_ni_set_pon_state set_pon_state;
bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };
BCMOLT_OPER_INIT(&set_pon_state, gpon_ni, set_pon_state, key);
BCMOLT_OPER_PROP_SET(&set_pon_state, gpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_WORKING);
return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
}