/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *
 *     Copyright (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.
 *
 *  :>
 *
 *****************************************************************************/

/**
 * @file bal_mac_util_epon.c
 *
 * @brief mac util interfaces definition used by Bal Core for EPON
 *
 * This file expose the APIs to the core to configure the mac
 * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
 *
 * @addtogroup mac_util
 */

/*@{*/

#include <bal_mac_util.h>
#include <bal_mac_util_epon.h>

#if BAL_EPON_EXCLUDE
#include <bcmolt_user_appl_epon_oam.h>
#include <bal_oam_util.h>
#include <bcmolt_eon.h>

static bcmos_errno mac_util_indication_handle_for_epon_link (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_epon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);


/** @brief array stores the list of EPON related auto indications from Maple to subscribe */
static mac_util_ind_obj_and_handlers mac_util_epon_ind_handlers[] =
{
    {BCMOLT_OBJ_ID_EPON_LINK,       "BCMOLT_OBJ_ID_EPON_LINK",  mac_util_indication_handle_for_epon_link},
    {BCMOLT_OBJ_ID_EPON_NI,         "BCMOLT_OBJ_ID_EPON_NI",    mac_util_indication_handle_for_epon_ni}
};


/* epon onu entry structure */
typedef enum
{
    OAM_PROVISION_STATE_IDLE = 0,          /**< idle - did not start yet */
    OAM_PROVISION_STATE_STARTED,            /**< started - waiting to configure traffic cb to send bal core flow up indication */
    OAM_PROVISION_STATE_COMPLETED,  /**< completed successfully */
    OAM_PROVISION_STATE_FAIL/**< failed to complete oam provision */
} oam_provision_state;

#define MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC 16
typedef struct epon_onu_list_entry epon_onu_list_entry;
struct epon_onu_list_entry
{
    TAILQ_ENTRY(epon_onu_list_entry) next;
    bcmbal_subscriber_terminal_key bal_onu_key;                   /* bal onu key */
    bcmos_mac_address mac_address;
    oam_provision_state oam_provision_state;
    uint8_t waiting_flows_num;
    bcmbal_flow_key flow_keys[MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC];
    uint32_t tunnel_id;
};


static TAILQ_HEAD(epon_onu_list_head_t, epon_onu_list_entry) epon_onu_list;


/** @todo needs to be ported to the topology stub function */
static bcmolt_devid maple_device_from_interface_get(uint16_t access_int_id)
{
    /* For now, all interfaces map to device 0 */
    return (bcmolt_devid)0;

}


static void epon_onu_list_add(epon_onu_list_entry *epon_onu_entry);
static epon_onu_list_entry *epon_onu_list_find_by_mac(const bcmos_mac_address *mac_address);
static epon_onu_list_entry *epon_onu_list_find_by_key(bcmbal_subscriber_terminal_key *key);
static void epon_onu_list_remove_by_key(bcmbal_subscriber_terminal_key *key);

static void mac_util_configure_traffic_cb(void *context,
    bcmolt_devid device_id,
    bcmolt_epon_ni epon_ni,
    const bcmos_mac_address *mac_address,
    bcmos_errno result);

static void mac_util_unconfigure_traffic_cb(void *context,
    bcmolt_devid device_id,
    bcmolt_epon_ni epon_ni,
    const bcmos_mac_address *mac_address,
    bcmos_errno result);


#define _mac_addr_fmt_str "<%02x:%02x:%02x:%02x:%02x:%02x>"
#define _mac_addr_data(mac) \
    (mac).u8[0], \
    (mac).u8[1], \
    (mac).u8[2], \
    (mac).u8[3], \
    (mac).u8[4], \
    (mac).u8[5]


static void mac_util_oam_negotiation_cb(void *context, bcmolt_devid device_id, bcmolt_epon_ni epon_ni, const bcmos_mac_address *mac_address, bcmos_errno result)
{

    epon_onu_list_entry *p_onu_entry = context;
    uint32_t logical_pon;
    bcmos_errno rc;

    do
    {

        rc = bcm_topo_pon_get_physical2logical(device_id, epon_ni, &logical_pon);
        if (BCM_ERR_OK != rc)
       {
           BCM_LOG(ERROR, log_id_mac_util,
                   "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, epon_ni, bcmos_strerror(rc));
           break;
       }

        BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
                "device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
                device_id, epon_ni, _mac_addr_data(*mac_address), result == BCM_ERR_OK ? "success" : "fail");


        mac_util_report_sub_term_event(logical_pon,
                                       p_onu_entry->bal_onu_key.sub_term_id,
                                       (bcmolt_serial_number *)NULL,
                                       BAL_UTIL_OPER_SUB_TERM_ADD,
                                       result,
                                       result == BCM_ERR_OK ? BCMOLT_RESULT_SUCCESS : BCMOLT_RESULT_FAIL,
                                       BCMOLT_ACTIVATION_FAIL_REASON_NONE,
                                       result == BCM_ERR_OK ? p_onu_entry->tunnel_id : BCMBAL_INVALID_TUNNEL_ID);

    }
    while(0);

}

/**
 * @brief get string for the indication object type for epon
 */
static char *mac_util_indication_get_obj_type_str_for_epon (bcmolt_obj_id obj_type)
{
    return _mac_util_get_obj_type_str_for_indications (obj_type, mac_util_epon_ind_handlers, BCM_SIZEOFARRAY(mac_util_epon_ind_handlers));
}

/**
 * @brief all the maple indication handlers for epon
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 */
bcmos_errno mac_util_handle_all_olt_ind_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    int i = 0;

    BCM_LOG(DEBUG, log_id_mac_util,
        "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
        p_msg->obj_type, mac_util_indication_get_obj_type_str_for_epon(p_msg->obj_type),
        p_msg->group, p_msg->subgroup);

    for (i=0; i < BCM_SIZEOFARRAY(mac_util_epon_ind_handlers); i++)
    {
        if (p_msg->obj_type == mac_util_epon_ind_handlers[i].obj_type)
        {
            return mac_util_epon_ind_handlers[i].ind_handler (device_id, p_msg);
        }
    }

    /* log an error if unhandled */
    return BCM_ERR_INTERNAL;
}


/**
 * @brief Handler function for Maple auto indications for EPON Link
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_epon_link (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint32_t logical_pon;

    do
    {
        if (BCMOLT_EPON_LINK_AUTO_ID_MPCP_DISCOVERED == p_msg->subgroup)
        {
            epon_onu_list_entry *p_onu_entry;
            bcmolt_epon_link_mpcp_discovered * p_ind = (bcmolt_epon_link_mpcp_discovered*)p_msg;

            rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.epon_ni, &logical_pon);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                        "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.epon_ni, bcmos_strerror(rc));
                break;
            }

            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "llid indication received obj=%d group=%d subgroup=%d err=%d; "
                    "link_status = %s (%d), llid = (0x%04x) tunnel_id = (0x%08x)\n",
                    p_msg->obj_type, p_msg->group, p_msg->subgroup, p_msg->err,
                    p_ind->data.link_info.link_status==BCMOLT_EPON_LINK_STATUS_DISCOVERED ? "Discovered" : "other",
                    p_ind->data.link_info.link_status,
                    p_ind->data.link_info.llid,
                    p_ind->data.link_info.tunnel_id);



            if(NULL == (p_onu_entry = epon_onu_list_find_by_mac(&(p_ind->key.mac_address))))
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                        "Failed to find epon onu related to received frame captured\n");
                rc = BCM_ERR_INTERNAL;
            }
            else
            {

                p_onu_entry->tunnel_id = p_ind->data.link_info.tunnel_id;
                bal_oam_start_oam_negotiation(device_id,
                                              p_ind->key.epon_ni,
                                              &p_ind->key.mac_address,
                                              mac_util_oam_negotiation_cb,
                                              p_onu_entry);
            }
        }
    }
    while(0);

    return rc;
}


/**
 * @brief Handler function for Maple auto indications for EPON NI
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_epon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint32_t logical_pon;
    do
    {

        if (BCMOLT_EPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
        {
            bcmolt_epon_ni_state_change_completed * p_ind = (bcmolt_epon_ni_state_change_completed *)p_msg;
            rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.epon_ni, &logical_pon);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                        "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.epon_ni, bcmos_strerror(rc));
                break;
            }

            BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
                    BCMOLT_EPON_NI_EN_STATE_ENABLED == p_ind->data.new_state ? "up" : "down");

            mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
                BCMOLT_RESULT_SUCCESS, p_ind->data.new_state);
        }
        else
        {
            /* just get the pon key by typecasting to a dummy structure */
            bcmolt_epon_ni_key *p_pon_key = &(((bcmolt_epon_ni_state_change_completed*)p_msg)->key);

            rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->epon_ni, &logical_pon);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                        "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->epon_ni, bcmos_strerror(rc));
                break;
            }

            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "Unhandled message indication for obj Epon_NI group %d "
                    "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
        }



    }
    while(0);
    return rc;
}


/**
 * @brief  Maple auto indication register for specific EPON based indications
 *
 * @param p_rx_cfg         handler config structure
 * @param  device_id                         specific device id (for multiple devices support)
 * @return bcmos_errno
 */
bcmos_errno mac_util_register_for_epon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
{
    return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_epon_ind_handlers, BCM_SIZEOFARRAY(mac_util_epon_ind_handlers), device_id);
}
#endif /* BAL_EPON_EXCLUDE */

static bcmos_errno mac_util_epon_access_terminal_set(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id,
    bcmolt_system_mode system_mode,
    bcmolt_nni_speed nni_speed)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_device_key key = {};
    bcmolt_device_nni_speed nni_speed_cfg;
    bcmolt_device_cfg dev_cfg;

    rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
    if (rc != BCM_ERR_OK)
        return rc;

    BCMOLT_CFG_INIT(&dev_cfg, device, key);
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, system_mode);

    nni_speed_cfg.first_half = nni_speed;
    nni_speed_cfg.second_half = nni_speed;
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);

    /** @todo with multiple devices the mechanism to configure acces term  will change */
    rc = bcmolt_cfg_set(device_id, &dev_cfg.hdr);
    if (rc != BCM_ERR_OK)
        return rc;

    return maple_access_terminal_connect_common(device_id);
}

bcmos_errno mac_util_access_terminal_set_for_epon_8_tdma(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA,
        BCMOLT_NNI_SPEED_GBPS_12P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_4_tdma(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA,
        BCMOLT_NNI_SPEED_GBPS_12P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_16_1g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__16_X,
        BCMOLT_NNI_SPEED_GBPS_2P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_8_1g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__8_X,
        BCMOLT_NNI_SPEED_GBPS_2P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_4_1g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__4_X,
        BCMOLT_NNI_SPEED_GBPS_2P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_8_10g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__8_X_10_G,
        BCMOLT_NNI_SPEED_GBPS_12P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_4_10g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__4_X_10_G,
        BCMOLT_NNI_SPEED_GBPS_12P5);
}

bcmos_errno mac_util_access_terminal_set_for_epon_2_10g(
    acc_term_inst *p_acc_term,
    bal_util_oper_acc_term op_type,
    bcmolt_devid device_id)
{
    return mac_util_epon_access_terminal_set(
        p_acc_term,
        op_type,
        device_id,
        BCMOLT_SYSTEM_MODE_EPON__2_X_10_G,
        BCMOLT_NNI_SPEED_GBPS_12P5);
}

/**
 * @brief Command Set setup routine for interface up to mac application for EPON
 *
 * This routine is called by if_fsm in the BAL core to initialize the command
 * set to up the interface of the mac application. The cmdset actually
 * consists of two commands, one is to send the if up request message to the mac
 * App and handle the relevant response, the other is to handle the indication message
 * from the mac APP when the operation is completed.
 *
 * @param p_interface_inst  Pointer to interface instance
 * @param op_type           Operation type on access terminal/interface instance
 *
 * @return bcmos_errno
 *
 */
bcmos_errno mac_util_interface_set_for_epon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmbal_interface_key intf_key = p_interface_inst->api_req_int_obj_info.key;
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    /* get physical interface from logical interface */
    rc = bcm_topo_pon_get_logical2physical(intf_key.intf_id, &device_id, &physical_if_id);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
                "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
        return rc;
    }

    bcmolt_epon_ni_key key;
    bcmolt_epon_ni_cfg cfg;
    bcmolt_epon_ni_set_epon_ni_en_state oper;

    key.epon_ni = physical_if_id;

    BCMOLT_CFG_INIT(&cfg, epon_ni, key);

    if (BAL_UTIL_OPER_IF_UP == op_type)
    {
        BCMOLT_CFG_PROP_SET(&cfg, epon_ni, registration_behavior, BCMOLT_REGISTRATION_BEHAVIOR_NOTIFY_UNKNOWN);

        bcmolt_cfg_set(device_id, &cfg.hdr);
        if (rc != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
                    "Failed to %s (set) pon interface (%d) - %s, err_text=%s\n",
                    (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
                    rc, bcmos_strerror(rc), cfg.hdr.hdr.err_text);
            return rc;
        }
    }

    BCMOLT_OPER_INIT(&oper, epon_ni, set_epon_ni_en_state, key);
    BCMOLT_OPER_PROP_SET(&oper, epon_ni, set_epon_ni_en_state, new_state,
        (BAL_UTIL_OPER_IF_UP == op_type ?
        BCMOLT_EPON_NI_EN_STATE_ENABLED : BCMOLT_EPON_NI_EN_STATE_DISABLED));

    rc = bcmolt_oper_submit(device_id, &oper.hdr);

    if (rc != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
                "Failed to %s (submit) pon interface (%d) - %s, err_text=%s\n",
                (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
                rc, bcmos_strerror(rc), oper.hdr.hdr.err_text);
    }
    else
    {
        BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
                "Submitted INTERFACE-%s operation for IF %d\n",
                (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN", intf_key.intf_id);
    }

    return rc;
}
/*---------------------------------------------------------------------------------------------*/





#if BAL_EPON_EXCLUDE
/**
 * @brief mac_util_validate_subscriber_terminal_info_for_epon
 *
 * This routine is used to validate all input attributes required for a sub term setting
 * received from core for EPON
 *
 * @param p_sub_term_req       A pointer to a subscriber terminal object
 *
 * @return bcmos_errno
 */
/*****************************************************************************/
bcmos_errno mac_util_validate_subscriber_terminal_info_for_epon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
{
    if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
    {
        if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, mac_address))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                    "mac_address is a mandatory parameter for an epon subscriber terminal, and it is not set\n");
            return BCM_ERR_MANDATORY_PARM_IS_MISSING;
        }
    }

    return BCM_ERR_OK;
}


/**
 * @brief Command Set setup routine for subscriber terminal connect to mac application for EPON
 *
 * This routine is called by sub_term_fsm in the BAL core to initialize the command
 * set to connect the subscriber terminal of the mac application. The cmdset actually
 * consists of two commands, one is to send the sub_term request message to the mac
 * App and handle the relevant response, the other is to handle the indication message
 * from the mac APP when the operation is completed.
 *
 * @param p_sub_term_inst   A pointer to a subscriber terminal instance
 * @param op_type          Type of operation being performed on the subscriber terminal instance
 * @param is_post_discovery This parameter is ignored for epon
 *
 * @return bcmos_errno
 */
bcmos_errno mac_util_subscriber_terminal_set_for_epon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
{
    bcmos_errno rc = BCM_ERR_OK;

    bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;


    BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
            "IN : %s pon_id = %d onu_id= %d "
            "omci_gem_port = %d\n",
            __FUNCTION__,
            p_sub_term_req->key.intf_id,
            p_sub_term_req->key.sub_term_id, p_sub_term_req->data.svc_port_id);

    if ((BAL_UTIL_OPER_SUB_TERM_ADD != op_type)
        && (BAL_UTIL_OPER_SUB_TERM_REMOVE != op_type)
        && (BAL_UTIL_OPER_SUB_TERM_CLEAR != op_type))
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                "Unsupported operation %d for sub_term %u\n",
                op_type, p_sub_term_req->key.sub_term_id);
        return BCM_ERR_NOT_SUPPORTED;
    }

    do
    {
        bcmolt_devid device_id;
        uint32_t physical_if_id;

        /* get physical interface from logical interface */
        rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }

        epon_onu_list_entry * p_new_epon_onu_entry;
        bcmolt_epon_ni_key key;
        bcmolt_epon_ni_add_link oper;

        key.epon_ni = physical_if_id;
        BCMOLT_OPER_INIT(&oper, epon_ni, add_link, key);

        if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
        {

            BCMOLT_OPER_PROP_SET(&oper, epon_ni, add_link, mac_address, p_sub_term_req->data.mac_address);
            BCMOLT_OPER_PROP_SET(&oper, epon_ni, add_link, rate, BCMOLT_EPON_LINK_RATE_TEN_TEN);
            rc = bcmolt_oper_submit(device_id, &oper.hdr);

            if (rc != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                        "Failed to register epon onu epon_ni = %d mac : "_mac_addr_fmt_str" rc = %d (%s), err_text=%s\n",
                        key.epon_ni, _mac_addr_data(p_sub_term_req->data.mac_address), rc, bcmos_strerror(rc),
                        oper.hdr.hdr.err_text);
                break;
            }
            /* add the new epon onu to the epon onu list to follow indications and oam sending */
            p_new_epon_onu_entry = bcmos_calloc(sizeof(epon_onu_list_entry));
            if (NULL == p_new_epon_onu_entry)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                        "Failed to allocate the epon onu entry\n");
                rc = BCM_ERR_NOMEM;
                break;
            }

            memcpy(&p_new_epon_onu_entry->bal_onu_key, &p_sub_term_req->key,
                   sizeof(bcmbal_subscriber_terminal_key));
            p_new_epon_onu_entry->mac_address = p_sub_term_req->data.mac_address;
            p_new_epon_onu_entry->oam_provision_state = OAM_PROVISION_STATE_IDLE;
            p_new_epon_onu_entry->waiting_flows_num = 0;

            epon_onu_list_add(p_new_epon_onu_entry);
        }
        else
        {
            mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
                                           p_sub_term_req->key.sub_term_id,
                                           (bcmolt_serial_number *)NULL,
                                           BAL_UTIL_OPER_SUB_TERM_REMOVE,
                                           BCM_ERR_OK, BCMOLT_RESULT_SUCCESS,
                                           MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);

           epon_onu_list_remove_by_key(&p_sub_term_req->key);

        }
    } while (0);

    BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
            "OUT : going out of %s rc = %s (%d)\n",
            __FUNCTION__,
            bcmos_strerror(rc), rc);


    return rc;
}





static bcmos_errno maple_us_sla_configure_epon(bcmbal_flow_cfg *flow_entry, bcmos_mac_address *mac)
{
    bcmolt_epon_link_key epon_link_key;
    bcmolt_epon_link_cfg epon_link_cfg;
    bcmolt_upstream_bandwidth_distribution us_bw_dist = {};

    bcmolt_devid device_id;
    uint32_t physical_if_id;
    bcmos_errno rc = BCM_ERR_OK;

    /* get physical interface from logical interface */
    rc = bcm_topo_pon_get_logical2physical (flow_entry->data.access_int_id, &device_id, &physical_if_id);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(flow_entry->data.access_int_id),
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
    }
    else
    {

        epon_link_key.epon_ni = physical_if_id;
        epon_link_key.mac_address = *mac;
        BCMOLT_CFG_INIT(&epon_link_cfg, epon_link, epon_link_key);

        us_bw_dist.polling_interval_us = BCMOLT_POLLING_INTERVAL_AUTOMATIC;
        if (BCMBAL_ATTRIBUTE_PROP_IS_SET(&flow_entry->data.sla, sla, min_rate))
        {
            us_bw_dist.min_schedulershaper.bandwidth_Kbps = flow_entry->data.sla.min_rate;
        }
        if (BCMBAL_ATTRIBUTE_PROP_IS_SET(&flow_entry->data.sla, sla, max_rate))
        {
            us_bw_dist.max_schedulershaper.bandwidth_Kbps = flow_entry->data.sla.max_rate;
        }
        else
        {
            us_bw_dist.max_schedulershaper.bandwidth_Kbps = 10000000;
        }
        us_bw_dist.max_schedulershaper.priority = 7;

        BCMOLT_CFG_PROP_SET(&epon_link_cfg, epon_link, upstream_bandwidth, us_bw_dist);
        return bcmolt_cfg_set(device_id, &epon_link_cfg.hdr);
    }

    return rc;
}






/**
 * @brief flow set for EPON
 *
 * @param p_flow_req    pointer to flow request structure from core
 * @param op_type      ADD, REMOVE or CLEAR
 * @param p_flow_core local DB flow context passed as a cookie
 *
 * @return errno    error
 */
bcmos_errno mac_util_flow_set_for_epon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
{
    bcmos_errno rc = BCM_ERR_OK;

    epon_onu_list_entry *p_onu_entry;
    bcmos_mac_address mac;
    bcmbal_subscriber_terminal_key key;


    key.intf_id = p_flow_req->data.access_int_id;
    key.sub_term_id = p_flow_req->data.sub_term_id;

    if(NULL != (p_onu_entry = epon_onu_list_find_by_key(&key)))
    {
            mac = p_onu_entry->mac_address;
    }
    else
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                "failed to configure flow, "
                "subscriber terminal if=%d sub-term id = %d was not found - no such device\n",
                p_flow_req->data.access_int_id, p_flow_req->data.sub_term_id);

        return BCM_ERR_NOENT;
    }



    if (BAL_UTIL_OPER_FLOW_ADD == op_type)
    {

        BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id), "add, context is %p\n", p_flow_context);

        switch (p_onu_entry->oam_provision_state)
        {
            case OAM_PROVISION_STATE_IDLE:
            {
                p_onu_entry->flow_keys[p_onu_entry->waiting_flows_num++] = p_flow_req->key;

                BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                        "add p_onu_entry-> %p, waiting flows: %d context is %p\n",
                        p_onu_entry, p_onu_entry->waiting_flows_num, p_flow_context);

                rc = maple_us_sla_configure_epon(p_flow_req, &mac);
                if (rc != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                            "Unable to configure EPON US SLA (%s)\n", bcmos_strerror(rc));

                    break;
                }

                p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_STARTED;

                bal_oam_configure_traffic(maple_device_from_interface_get(p_flow_req->data.access_int_id),
                                          p_flow_req->data.access_int_id,
                                          &mac,
                                          BCMOS_TRUE,
                                          mac_util_configure_traffic_cb, p_flow_context);
            }
            break;


            case OAM_PROVISION_STATE_STARTED:
            {
                if (p_onu_entry->waiting_flows_num < MAC_UTIL_MAX_WAITING_FLOWS_PER_MAC)
                {
                    p_onu_entry->flow_keys[p_onu_entry->waiting_flows_num++] = p_flow_req->key;
                }
                else
                {
                    BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                            "failed to configure flow for that mac, "
                            "too many flows already waiting for oam configuration\n");
                    rc = BCM_ERR_INSUFFICIENT_LIST_MEM;
                }
            }
            break;


            case OAM_PROVISION_STATE_COMPLETED:
            {
                mac_util_report_flow_add_success(p_flow_req->key, p_flow_req->data.access_int_id);
            }
            break;


            case OAM_PROVISION_STATE_FAIL:
            default:
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                        "failed to configure oam traffic for that mac,\n"); /* currently no failure indications */
            }
            break;
        }
    }
    else /* REMOVE or CLEAR FLOW */
    {

        BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                "delete p_onu_entry-> %p, waiting flows: %d, provisioned state is %d, context is %p\n",
                p_onu_entry,
                p_onu_entry->waiting_flows_num,
                p_onu_entry->oam_provision_state,
                p_flow_context);

        switch (p_onu_entry->oam_provision_state)
        {
            case OAM_PROVISION_STATE_IDLE:
            {
                mac_util_report_flow_remove_success(p_flow_req->key, p_flow_req->data.access_int_id, op_type);
            }
            break;

            case OAM_PROVISION_STATE_COMPLETED:
            {
                BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                        "calling bal_oam_configure_traffic w/ \"Disable\" state\n");

                bal_oam_configure_traffic(maple_device_from_interface_get(p_flow_req->data.access_int_id),
                                          p_flow_req->data.access_int_id,
                                          &mac,
                                          BCMOS_FALSE,
                                          mac_util_unconfigure_traffic_cb,
                                          p_flow_context);
            }
            break;

            case OAM_PROVISION_STATE_FAIL:
            case OAM_PROVISION_STATE_STARTED:
            default:
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(key.intf_id),
                        "failed to unconfigure oam traffic for that mac,\n"); /* currently no failure indications */
            }
            break;
        }
    }

    return rc;
}

static void mac_util_configure_traffic_cb(void *context,
    bcmolt_devid device_id,
    bcmolt_epon_ni epon_ni,
    const bcmos_mac_address *mac_address,
    bcmos_errno result)
{
    epon_onu_list_entry *p_onu_entry;
    int i;

    BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
        "configure device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
        device_id, epon_ni, _mac_addr_data(*mac_address), result == BCM_ERR_OK ? "success" : "fail");


    if(NULL == (p_onu_entry = epon_onu_list_find_by_mac(mac_address)))
    {
        BCM_LOG(ERROR,  MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
                "FAIL - received configure traffic cb for mac that was not configured " _mac_addr_fmt_str "\n",
                _mac_addr_data(*mac_address));
        return;
    }

    if (OAM_PROVISION_STATE_STARTED != p_onu_entry->oam_provision_state)
    {
        BCM_LOG(ERROR,  MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
                "FAIL - received configure traffic cb for mac that is in the wrong state (%d)\n",
                p_onu_entry->oam_provision_state);
        return;
    }

    if (result == BCM_ERR_OK)
    {
        p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_COMPLETED;

        BCM_LOG(INFO,  MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni), "Moved ONU to OAM COMPLETED state\n");

        for (i=0; i<p_onu_entry->waiting_flows_num; i++)
        {
            mac_util_report_flow_add_success(p_onu_entry->flow_keys[i], epon_ni);
        }
    }
    else
    {
        p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_FAIL;
    }

    p_onu_entry->waiting_flows_num = 0; /* currently we dont send fail indication */
}

/** EPON specific traffic unconfigure; Not used for GPON mode */
static void mac_util_unconfigure_traffic_cb(void *context,
    bcmolt_devid device_id,
    bcmolt_epon_ni epon_ni,
    const bcmos_mac_address *mac_address,
    bcmos_errno result)
{
    flow_inst *p_flow_core = (flow_inst *)(context);
    epon_onu_list_entry *p_onu_entry;

    BCM_LOG(INFO,  MAC_UTIL_GET_LOG_ID_FOR_PON_IF(epon_ni),
            "unconfigure device_id=%u, epon_ni=%u, mac_address=" _mac_addr_fmt_str " result='%s'\n",
            device_id,
            epon_ni,
            _mac_addr_data(*mac_address),
            result == BCM_ERR_OK ? "success" : "fail");


    /** @todo need to pass on the actual op type (REMOVE or CLEAR) */
    mac_util_report_flow_remove_success(p_flow_core->current_flow_info.key, epon_ni, BAL_UTIL_OPER_FLOW_REMOVE);

    if(NULL != (p_onu_entry = epon_onu_list_find_by_mac(mac_address)))
    {
        p_onu_entry->oam_provision_state = OAM_PROVISION_STATE_IDLE;
    }
}



/**
 * @brief used for epon oam message handling
 *
 * @param device_id   bcm dev id
 * @param p_msg oam msg pointer
 */
void bal_proxy_rx_cb_for_epon (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmolt_proxy_rx *proxy_rx = (bcmolt_proxy_rx *)p_msg;

    bcmolt_user_appl_eon_process_rx(device_id, proxy_rx);
    bcmolt_user_appl_epon_oam_handle_rx(device_id, proxy_rx, bal_oam_proxy_rx_cb);

    /** @note the free of p_msg is done in caller function */
}


/**
 * @brief init for epon oam and eon
 *
 */
static void mac_util_init_oam_for_epon (void)
{
    bcmolt_user_appl_epon_oam_init();
    bcmolt_user_appl_eon_init();
}




static void epon_onu_list_add(epon_onu_list_entry *epon_onu_entry)
{
    TAILQ_INSERT_HEAD(&epon_onu_list, epon_onu_entry, next);
    return;
}

static void epon_onu_list_remove_by_key(bcmbal_subscriber_terminal_key *key)
{
    epon_onu_list_entry *p_onu_entry = NULL;

    if(NULL != (p_onu_entry = epon_onu_list_find_by_key(key)))
    {
        TAILQ_REMOVE(&epon_onu_list, p_onu_entry, next);
        bcmos_free(p_onu_entry);
    }

    return;
}

static epon_onu_list_entry *epon_onu_list_find_by_mac(const bcmos_mac_address *mac_address)
{
    epon_onu_list_entry *p_onu_entry = NULL;
    epon_onu_list_entry *current_onu_entry;

    TAILQ_FOREACH(current_onu_entry, &epon_onu_list, next)
    {
        if (memcmp(&current_onu_entry->mac_address, mac_address, sizeof(bcmos_mac_address))==0)
        {
            p_onu_entry = current_onu_entry;
            break;
        }
    }

    return p_onu_entry;
}

static epon_onu_list_entry *epon_onu_list_find_by_key(bcmbal_subscriber_terminal_key *key)
{
    epon_onu_list_entry *p_onu_entry = NULL;
    epon_onu_list_entry *current_onu_entry;

    TAILQ_FOREACH(current_onu_entry, &epon_onu_list, next)
    {
        if ((current_onu_entry->bal_onu_key.intf_id == key->intf_id) &&
            (current_onu_entry->bal_onu_key.sub_term_id == key->sub_term_id))
        {
            p_onu_entry = current_onu_entry;
            break;
        }
    }

    return p_onu_entry;
}
#endif /* BAL_EPON_EXCLUDE */

/*@}*/
