blob: 60cb073311af3087dcc58279ec72c0138a786e0f [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 <bcmcli_session.h>
#include <bcmolt_msg_pack.h>
#include <bcm_dev_log.h>
#include <encrypt_oam.h>
#include <oam_defs.h>
#include "bcmolt_epon_hde.h"
#define HDE_TASK_MSG_Q_SIZE 64
#define ENC_KEY_LENGTH_KEY 16
#define HDE_MAX_NUM_LINKS 512
#define KEY_EXCHANGE_PERIOD 15
typedef enum
{
HDE_EVENT_ENABLE_ENCRYPTION,
HDE_EVENT_DISABLE_ENCRYPTION,
HDE_EVENT_FRAME_RX,
HDE_EVENT_OAM_TIMEOUT,
HDE_EVENT__NUM_OF
} hde_event;
typedef enum
{
HDE_STATE_NOT_ENCRYPTED,
HDE_STATE_ENCRYPTED,
HDE_STATE_WAITING_FOR_OAM_ACK,
HDE_STATE__NUM_OF
} hde_state;
typedef struct
{
bcmos_msg os_msg;
bcmolt_msg *rx;
hde_key key;
hde_event event;
} hde_task_msg;
typedef struct
{
hde_key hde_link;
hde_state state;
bcmos_timer oam_timeout_timer;
bcmolt_epon_link_rate link_rate;
bcmolt_epon_llid llid;
bcmos_mac_address corresponding_pon_port_mac;
} hde_link_data;
static struct
{
bcmos_task task;
dev_log_id log_id[BCMTR_MAX_OLTS];
hde_link_data *links;
uint16_t num_links;
} hde_data;
static bcmos_bool is_running = BCMOS_FALSE;
typedef void (*link_state_handler)(hde_link_data *hde_link, const bcmolt_msg *ind);
static const char *get_state_string(hde_state state)
{
switch (state)
{
case HDE_STATE_NOT_ENCRYPTED:
return "not encrypted";
case HDE_STATE_ENCRYPTED:
return "encrypted";
case HDE_STATE_WAITING_FOR_OAM_ACK:
return "waiting for oam ack";
default:
return "UNKNOWN STATE!!!";
}
}
static bcmos_errno set_new_key(const hde_key *hde_link, bcmolt_encryption_information_container *new_key, bcmolt_epon_key_choice key_choice, bcmolt_epon_encryption_mode mode)
{
bcmolt_epon_link_cfg link_cfg;
bcmolt_epon_encryption_config encryption_config = { };
// Up/down format must match even when doing DS only
encryption_config.upstream_encryption_information.format = new_key->format;
encryption_config.downstream_encryption_information = *new_key;
encryption_config.downstream_key_choice = key_choice;
encryption_config.downstream_mode = mode;
bcmolt_epon_link_key link_key =
{
.epon_ni = hde_link->epon_ni,
.mac_address = hde_link->mac_addr
};
BCMOLT_CFG_INIT(&link_cfg, epon_link, link_key);
BCMOLT_CFG_PROP_SET(&link_cfg, epon_link, epon_encryption, encryption_config);
return bcmolt_cfg_set(hde_link->device_id, &link_cfg.hdr);
}
static bcmos_errno set_pon_encryption_if_needed(const hde_key *hde_link)
{
// First check the current state of the PON's encryption mode.
bcmos_errno rc;
bcmolt_epon_ni_cfg pon_cfg;
bcmolt_epon_ni_key pon_key = { .epon_ni = hde_link->epon_ni };
BCMOLT_CFG_INIT(&pon_cfg, epon_ni, pon_key);
BCMOLT_CFG_PROP_GET(&pon_cfg, epon_ni, encryption_cfg);
rc = bcmolt_cfg_get(hde_link->device_id, &pon_cfg.hdr);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->device_id], "Failure - Cannot query PON encryption mode!.\n");
return rc;
}
if (pon_cfg.data.encryption_cfg.downstream_encryption_mode != BCMOLT_EPON_ENCRYPTION_MODE_EPON_ZERO_OVERHEAD_AES)
{
// Encryption mode is not correctly set on the PON, so set it now.
pon_cfg.data.encryption_cfg.downstream_encryption_mode = BCMOLT_EPON_ENCRYPTION_MODE_EPON_ZERO_OVERHEAD_AES;
pon_cfg.data.encryption_cfg.upstream_encryption_mode = BCMOLT_EPON_ENCRYPTION_MODE_NO_ENCRYPTION;
rc = bcmolt_cfg_set(hde_link->device_id, &pon_cfg.hdr);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->device_id], "Failure - Cannot set PON encryption mode!.\n");
return rc;
}
}
return BCM_ERR_OK;
}
static bcmolt_epon_link_rate get_link_rate(const hde_key *hde_link)
{
bcmos_errno rc;
bcmolt_epon_link_cfg link_cfg;
bcmolt_epon_link_key link_key =
{
.epon_ni = hde_link->epon_ni,
.mac_address = hde_link->mac_addr
};
BCMOLT_CFG_INIT(&link_cfg, epon_link, link_key);
BCMOLT_CFG_PROP_GET(&link_cfg, epon_link, link_rate);
rc = bcmolt_cfg_get(hde_link->device_id, &link_cfg.hdr);
if (rc != BCM_ERR_OK)
{
BCM_LOG(
ERROR,
hde_data.log_id[hde_link->device_id],
"Failure - cannot query link rate for link %02x:%02x:%02x:%02x:%02x:%02x!.\n",
hde_link->mac_addr.u8[0],
hde_link->mac_addr.u8[1],
hde_link->mac_addr.u8[2],
hde_link->mac_addr.u8[3],
hde_link->mac_addr.u8[4],
hde_link->mac_addr.u8[5]);
}
return link_cfg.data.link_rate;
}
static bcmos_mac_address get_pon_mac(const hde_key *hde_link)
{
bcmos_errno rc;
bcmolt_epon_ni_cfg pon_cfg;
bcmolt_epon_ni_key pon_key = { .epon_ni = hde_link->epon_ni };
BCMOLT_CFG_INIT(&pon_cfg, epon_ni, pon_key);
BCMOLT_CFG_PROP_GET(&pon_cfg, epon_ni, mac_address);
rc = bcmolt_cfg_get(hde_link->device_id, &pon_cfg.hdr);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->device_id], "Failure - Cannot query PON mac address!.\n");
}
return pon_cfg.data.mac_address;
}
static bcmolt_epon_llid get_llid(const hde_key *hde_link)
{
bcmos_errno rc;
bcmolt_epon_link_cfg link_cfg;
bcmolt_epon_link_key link_key =
{
.epon_ni = hde_link->epon_ni,
.mac_address = hde_link->mac_addr
};
BCMOLT_CFG_INIT(&link_cfg, epon_link, link_key);
BCMOLT_CFG_PROP_GET(&link_cfg, epon_link, llid);
rc = bcmolt_cfg_get(hde_link->device_id, &link_cfg.hdr);
if (rc != BCM_ERR_OK)
{
BCM_LOG(
ERROR,
hde_data.log_id[hde_link->device_id],
"Failure - cannot query LLID for link %02x:%02x:%02x:%02x:%02x:%02x!.\n",
hde_link->mac_addr.u8[0],
hde_link->mac_addr.u8[1],
hde_link->mac_addr.u8[2],
hde_link->mac_addr.u8[3],
hde_link->mac_addr.u8[4],
hde_link->mac_addr.u8[5]);
}
return link_cfg.data.llid;
}
/* By spec the SCI is the LLID of the link appended to the corresponding epon port mac address */
static void create_sci(const bcmos_mac_address *epon_port_mac, bcmolt_epon_llid llid, uint8_t *sci)
{
sci[7] = (uint8_t) llid;
sci[6] = (uint8_t) (llid >> 8);
sci[5] = epon_port_mac->u8[5];
sci[4] = epon_port_mac->u8[4];
sci[3] = epon_port_mac->u8[3];
sci[2] = epon_port_mac->u8[2];
sci[1] = epon_port_mac->u8[1];
sci[0] = epon_port_mac->u8[0];
}
static void handle_not_encrypted_enable_encryption(hde_link_data *hde_link, const bcmolt_msg *ind)
{
dpoe_encrypt_mode mode = DPOE_ENCRYPT_MODE_NONE;
// Retreive useful link info and store it to save messages later.
hde_link->link_rate = get_link_rate(&hde_link->hde_link);
hde_link->corresponding_pon_port_mac = get_pon_mac(&hde_link->hde_link);
hde_link->llid = get_llid(&hde_link->hde_link);
if (hde_link->link_rate == BCMOLT_EPON_LINK_RATE_TEN_TEN || hde_link->link_rate == BCMOLT_EPON_LINK_RATE_TEN_ONE)
{
mode = DPOE_ENCRYPT_MODE_10DOWN;
}
else if (hde_link->link_rate == BCMOLT_EPON_LINK_RATE_ONE_ONE)
{
mode = DPOE_ENCRYPT_MODE_1DOWN;
}
else
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id], "Failure - UNKNOWN LINK RATE!!!.\n");
}
dpoe_encrypt_oam_set_request_send(
&hde_link->hde_link,
KEY_EXCHANGE_PERIOD,
mode,
hde_link->corresponding_pon_port_mac);
bcmos_timer_start(&hde_link->oam_timeout_timer, HDE_ENABLE_OAM_WAIT_US + OAM_TIMEOUT_GRACE_PERIOD_US);
hde_link->state = HDE_STATE_WAITING_FOR_OAM_ACK;
}
static void handle_encrypted_disable_encryption(hde_link_data *hde_link, const bcmolt_msg *ind)
{
bcmolt_encryption_information_container empty_key = { };
bcmos_errno rc;
// Turn off encryption on the embedded side.
rc = set_new_key(&hde_link->hde_link, &empty_key, BCMOLT_EPON_KEY_CHOICE_KEY_0, BCMOLT_EPON_ENCRYPTION_MODE_NO_ENCRYPTION);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id],
"Failure - Cannot communicate with the embedded!.\n");
}
// Send the disable OAM to the link. Don't bother waiting for a response.
dpoe_encrypt_oam_set_request_send(&hde_link->hde_link, 0, DPOE_ENCRYPT_MODE_NONE, get_pon_mac(&hde_link->hde_link));
hde_link->state = HDE_STATE_NOT_ENCRYPTED;
}
static void handle_encrypted_frame_rx(hde_link_data *hde_link, const bcmolt_msg *ind)
{
const bcmolt_epon_link_frame_captured *frame_captured = (const bcmolt_epon_link_frame_captured*) ind;
uint8_t new_key[16];
bcmolt_epon_key_choice key_choice;
bcmos_errno rc;
bcmolt_encryption_information_container key_for_embedded;
rc = dpoe_encrypt_oam_parse_new_key(&frame_captured->data.frame, new_key, &key_choice);
if (rc != BCM_ERR_OK)
{
// Not a DPoE new key, ignore it
return;
}
if (hde_link->link_rate == BCMOLT_EPON_LINK_RATE_TEN_TEN || hde_link->link_rate == BCMOLT_EPON_LINK_RATE_TEN_ONE)
{
uint8_t sci[8];
create_sci(&hde_link->corresponding_pon_port_mac, hde_link->llid, sci);
key_for_embedded.format = BCMOLT_EPON_ENCRYPTION_INFORMATION_FORMAT_CTR;
memcpy(key_for_embedded.u.ctr.key, new_key, sizeof(new_key));
memcpy(key_for_embedded.u.ctr.sci, sci, sizeof(sci));
}
else if (hde_link->link_rate == BCMOLT_EPON_LINK_RATE_ONE_ONE)
{
key_for_embedded.format = BCMOLT_EPON_ENCRYPTION_INFORMATION_FORMAT_CFB;
memcpy(key_for_embedded.u.cfb.key, new_key, sizeof(new_key));
}
else
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id], "Failure - UNKNOWN LINK RATE!!!.\n");
}
rc = set_new_key(&hde_link->hde_link, &key_for_embedded, key_choice, BCMOLT_EPON_ENCRYPTION_MODE_EPON_ZERO_OVERHEAD_AES);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id],
"Failure - Cannot communicate with the embedded!.\n");
}
}
static void handle_waiting_for_oam_ack_oam_timeout(hde_link_data *hde_link, const bcmolt_msg *ind)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id], "Failure - No response to initial OAM.\n");
hde_link->state = HDE_STATE_NOT_ENCRYPTED;
}
static void handle_waiting_for_oam_ack_frame_rx(hde_link_data *hde_link, const bcmolt_msg *ind)
{
const bcmolt_epon_link_frame_captured *frame_captured = (const bcmolt_epon_link_frame_captured*) ind;
uint8_t encrypt_mode_response;
uint8_t key_expiry_response;
bcmos_errno rc;
rc = dpoe_encrypt_oam_parse_set_response(&frame_captured->data.frame, &encrypt_mode_response, &key_expiry_response);
if (rc != BCM_ERR_OK)
{
// Not a encryption set reponse, ignore it
return;
}
/* 0 represents 'no error'. */
if ((encrypt_mode_response != 0) || (key_expiry_response != 0))
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id],
"Failure - The link refused one of the requested TLVs.\n");
hde_link->state = HDE_STATE_NOT_ENCRYPTED;
return;
}
// We have an appropriate response, so move on normally.
bcmos_timer_stop(&hde_link->oam_timeout_timer);
hde_link->state = HDE_STATE_ENCRYPTED;
}
static void handle_waiting_for_oam_ack_disable_encryption(hde_link_data *hde_link, const bcmolt_msg *ind)
{
hde_link->state = HDE_STATE_NOT_ENCRYPTED;
}
static void handle_ignore(hde_link_data *hde_link, const bcmolt_msg *ind)
{
// Literally do nothing
}
static void handle_error(hde_link_data *hde_link, const bcmolt_msg *ind)
{
BCM_LOG(ERROR, hde_data.log_id[hde_link->hde_link.device_id], "Unexpected event in state %s\n",
get_state_string(hde_link->state));
}
static link_state_handler link_state_machine[HDE_STATE__NUM_OF][HDE_EVENT__NUM_OF] =
{
[HDE_STATE_NOT_ENCRYPTED] =
{
[HDE_EVENT_ENABLE_ENCRYPTION] = handle_not_encrypted_enable_encryption,
[HDE_EVENT_DISABLE_ENCRYPTION] = handle_error,
[HDE_EVENT_FRAME_RX] = handle_ignore,
[HDE_EVENT_OAM_TIMEOUT] = handle_ignore,
},
[HDE_STATE_ENCRYPTED] =
{
[HDE_EVENT_ENABLE_ENCRYPTION] = handle_error,
[HDE_EVENT_DISABLE_ENCRYPTION] = handle_encrypted_disable_encryption,
[HDE_EVENT_FRAME_RX] = handle_encrypted_frame_rx,
[HDE_EVENT_OAM_TIMEOUT] = handle_ignore,
},
[HDE_STATE_WAITING_FOR_OAM_ACK] =
{
[HDE_EVENT_ENABLE_ENCRYPTION] = handle_error,
[HDE_EVENT_DISABLE_ENCRYPTION] = handle_waiting_for_oam_ack_disable_encryption,
[HDE_EVENT_FRAME_RX] = handle_waiting_for_oam_ack_frame_rx,
[HDE_EVENT_OAM_TIMEOUT] = handle_waiting_for_oam_ack_oam_timeout,
}
};
static int32_t find_table_index(const hde_key *hde_link)
{
uint16_t i;
for (i = 0; i < hde_data.num_links; ++i)
{
if (memcmp(hde_link, &hde_data.links[i], sizeof(*hde_link)) == 0)
{
return i;
}
}
return -1;
}
static void remove_link_from_table(int32_t link_index)
{
int32_t i;
for (i = link_index; i < hde_data.num_links - 1; ++i)
{
/* Backwards copy all data expect for the timer handle */
hde_data.links[i].hde_link = hde_data.links[i + 1].hde_link;
hde_data.links[i].link_rate = hde_data.links[i + 1].link_rate;
hde_data.links[i].llid = hde_data.links[i + 1].llid;
hde_data.links[i].state = hde_data.links[i + 1].state;
}
/* also clear the state of the now empty link */
hde_data.links[hde_data.num_links - 1].state = HDE_STATE_NOT_ENCRYPTED;
hde_data.num_links--;
}
static void run_state_machine(int32_t link_index, const hde_task_msg *task_msg)
{
if (link_index < 0) // We don't know of this link yet.
{
if (hde_data.num_links == HDE_MAX_NUM_LINKS)
{
BCM_LOG(ERROR, hde_data.log_id[task_msg->key.device_id], "Failure - Cannot add any more links!.\n");
return;
}
link_index = hde_data.num_links;
hde_data.links[link_index].hde_link = task_msg->key;
link_state_machine[hde_data.links[link_index].state][task_msg->event](&hde_data.links[link_index], task_msg->rx);
if (hde_data.links[link_index].state != HDE_STATE_NOT_ENCRYPTED)
{
// This link did not end in the state 'not encrypted', so we need to start tracking him.
++hde_data.num_links;
}
}
else // We already know of this link.
{
link_state_machine[hde_data.links[link_index].state][task_msg->event](&hde_data.links[link_index], task_msg->rx);
if (hde_data.links[link_index].state == HDE_STATE_NOT_ENCRYPTED)
{
// The link has is no longer encrypted so lets forget about him.
remove_link_from_table(link_index);
}
}
}
static void hde_handle_event(bcmos_module_id module_id, bcmos_msg *os_msg)
{
hde_task_msg *task_msg = (hde_task_msg *) os_msg;
int32_t link_index;
link_index = find_table_index(&task_msg->key);
run_state_machine(link_index, task_msg);
if (task_msg->rx != NULL)
{
bcmolt_msg_free(task_msg->rx);
}
bcmos_free(task_msg);
}
static bcmos_timer_rc oam_response_timeout(bcmos_timer *timer, long data)
{
hde_task_msg *task_msg = bcmos_calloc(sizeof(*task_msg));
BUG_UNLESS(task_msg);
task_msg->key = hde_data.links[data].hde_link;
task_msg->event = HDE_EVENT_OAM_TIMEOUT;
task_msg->os_msg.handler = hde_handle_event;
bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_EPON_HDE, &task_msg->os_msg, BCMOS_MSG_SEND_AUTO_FREE);
return BCMOS_TIMER_OK;
}
static bcmos_errno hde_set_encryption(hde_key* key, bcmos_bool enabled)
{
bcmos_errno rc = BCM_ERR_OK;
hde_task_msg *task_msg = bcmos_calloc(sizeof(*task_msg));
BUG_UNLESS(task_msg);
task_msg->key = *key;
task_msg->event = enabled ? HDE_EVENT_ENABLE_ENCRYPTION : HDE_EVENT_DISABLE_ENCRYPTION;
task_msg->os_msg.handler = hde_handle_event;
rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_EPON_HDE, &task_msg->os_msg, BCMOS_MSG_SEND_AUTO_FREE);
BUG_ON(rc != BCM_ERR_OK);
return rc;
}
static bcmos_errno hde_cli_enable(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
bcmos_errno rc = BCM_ERR_OK;
hde_key key =
{
.device_id = current_device,
.epon_ni = (bcmolt_epon_ni)(bcmcli_find_named_parm(session, "epon_ni")->value.number),
.mac_addr = (bcmos_mac_address)(bcmcli_find_named_parm(session, "mac_address")->value.mac)
};
rc = set_pon_encryption_if_needed(&key);
if (rc != BCM_ERR_OK)
{
return rc;
}
return hde_set_encryption(&key, BCMOS_TRUE);
}
static bcmos_errno hde_cli_disable(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
hde_key key =
{
.device_id = current_device,
.epon_ni = (bcmolt_epon_ni)(bcmcli_find_named_parm(session, "epon_ni")->value.number),
.mac_addr = (bcmos_mac_address)(bcmcli_find_named_parm(session, "mac_address")->value.mac)
};
return hde_set_encryption(&key, BCMOS_FALSE);
}
// public indication handler interface -- called in transport layer context
bcmos_errno bcmolt_epon_hde_process_rx(bcmolt_devid device_id, uint8_t instance, bcmolt_proxy_rx *rx)
{
bcmos_errno rc = BCM_ERR_OK;
bcmolt_epon_link_frame_captured* actual_rx;
hde_task_msg *task_msg;
hde_key key;
if (!is_running)
{
return BCM_ERR_OK;
}
// We only look at message targetting epon links.
if (rx->hdr.obj_type != BCMOLT_OBJ_ID_EPON_LINK)
{
// Not an error, we just don't care about this object.
return BCM_ERR_OK;
}
// This is the only kind of proxy RX currently supported.
if (rx->hdr.subgroup != BCMOLT_EPON_LINK_PROXY_RX_ID_FRAME_CAPTURED)
{
return BCM_ERR_OK;
}
// This is safe due to the above subgroup check.
actual_rx = (bcmolt_epon_link_frame_captured*) rx;
key.device_id = device_id;
key.epon_ni = instance;
key.mac_addr = actual_rx->key.mac_address;
task_msg = bcmos_calloc(sizeof(*task_msg));
if (task_msg == NULL)
{
rc = BCM_ERR_NOMEM;
}
else
{
bcmolt_msg *rx_clone = NULL;
rc = bcmolt_msg_clone(&rx_clone, &rx->hdr);
if (rc != BCM_ERR_OK)
{
bcmos_free(task_msg);
return rc;
}
actual_rx = (bcmolt_epon_link_frame_captured*) rx_clone;
task_msg->rx = rx_clone;
task_msg->key = key;
task_msg->event = HDE_EVENT_FRAME_RX;
task_msg->os_msg.handler = hde_handle_event;
rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_EPON_HDE, &task_msg->os_msg, BCMOS_MSG_SEND_AUTO_FREE);
if (rc != BCM_ERR_OK)
{
BCM_LOG(ERROR, hde_data.log_id[device_id], "Message send failed!\n");
bcmolt_msg_free(rx_clone);
}
}
return rc;
}
void bcmolt_epon_hde_appl_cli_init(bcmcli_entry *top_dir)
{
static const char *dir_name = "hde";
if (bcmcli_dir_find(top_dir, dir_name))
{
return;
}
bcmcli_entry *dir = bcmcli_dir_add(top_dir, dir_name, "EPON OAM negotiation commands", BCMCLI_ACCESS_ADMIN, NULL);
BUG_ON(dir == NULL);
BCMCLI_MAKE_CMD(
dir,
"enable",
"Enable encryption for an EPON link",
hde_cli_enable,
BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
BCMCLI_MAKE_PARM("mac_address", "MAC address", BCMCLI_PARM_MAC, 0));
BCMCLI_MAKE_CMD(
dir,
"disable",
"Disable encryption for an EPON link",
hde_cli_disable,
BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
BCMCLI_MAKE_PARM("mac_address", "MAC address", BCMCLI_PARM_MAC, 0));
}
void bcmolt_epon_hde_appl_init(void)
{
bcmos_errno rc = BCM_ERR_OK;
uint32_t i;
bcmos_task_parm task_params =
{
.name = "user_appl_hde",
.priority = TASK_PRIORITY_USER_APPL_EPON_HDE,
.core = BCMOS_CPU_CORE_ANY, /* No CPU affinity */
.init_handler = NULL
};
bcmos_timer_parm timer_parm =
{
.name = "oam_timeout_timer",
.owner = BCMOS_MODULE_ID_NONE,
.periodic = BCMOS_FALSE,
.handler = oam_response_timeout
};
if (is_running)
{
return;
}
is_running = BCMOS_TRUE;
for (i=0; i<BCMTR_MAX_OLTS; i++)
{
char log_name[MAX_DEV_LOG_ID_NAME];
snprintf(log_name, sizeof(log_name)-1, "user_appl_hde_%d", i);
hde_data.log_id[i] = bcm_dev_log_id_register(log_name, DEV_LOG_LEVEL_ERROR, DEV_LOG_ID_TYPE_BOTH);
}
hde_data.links = bcmos_calloc(HDE_MAX_NUM_LINKS * sizeof(hde_data.links[0]));
BUG_ON(hde_data.links == NULL);
rc = bcmos_task_create(&hde_data.task, &task_params);
BUG_ON(rc != BCM_ERR_OK);
bcmos_module_parm module_params =
{
.qparm = { .name = "user_appl_hde", .size = HDE_TASK_MSG_Q_SIZE }
};
rc = bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_EPON_HDE, &hde_data.task, &module_params);
BUG_ON(rc != BCM_ERR_OK);
for (i = 0; i < HDE_MAX_NUM_LINKS; ++i)
{
timer_parm.data = i;
rc = bcmos_timer_create(&hde_data.links[i].oam_timeout_timer, &timer_parm);
BUG_ON(rc != BCM_ERR_OK);
}
}