/*
<: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.

:>
*/

/* This file contains the pieces of the OAM negotiation state machine that are common to all OAM. */

#include "oam_common.h"
#include "bcmolt_utils.h"
#include "bcmolt_math.h"
#include "bcmolt_eon_private.h"
#include "bcmolt_user_appl_epon_oam.h"
#include "dpoe/dpoe.h"
#include "brcm/brcm.h"
#include "ctc/ctc.h"

static const oam_info_add_tlv add_org_spec_tlv[EON_OAM_SET_ID_COUNT] =
{
    [EON_OAM_SET_ID_DPOE] = dpoe_tx_add_tlv,
    [EON_OAM_SET_ID_BRCM] = brcm_tx_add_tlv,
    [EON_OAM_SET_ID_CTC] = ctc_tx_add_tlv
};

static const oam_rx_org_spec_tlv rx_org_spec_tlv[EON_OAM_SET_ID_COUNT] =
{
    [EON_OAM_SET_ID_DPOE] = dpoe_rx_tlv,
    [EON_OAM_SET_ID_BRCM] = brcm_rx_tlv,
    [EON_OAM_SET_ID_CTC] = ctc_rx_tlv
};

static uint8_t get_oam_version(void)
{
    return 0x01; /* only version currently supported */
}

static void fill_local_tlv(const eon_link_state *link_state, bcmolt_epon_oam_local_remote_info *tlv)
{
    tlv->oam_version = get_oam_version();
    tlv->revision = link_state->revision;
    tlv->state =
        BCMOLT_EPON_OAM_LOCAL_REMOTE_INFO_STATE_PARSER_ACTION1 |
        BCMOLT_EPON_OAM_LOCAL_REMOTE_INFO_STATE_MULTIPLEXER_ACTION;
    tlv->oam_config =
        BCMOLT_EPON_OAM_LOCAL_REMOTE_INFO_CONFIG_OAM_MODE |
        BCMOLT_EPON_OAM_LOCAL_REMOTE_INFO_CONFIG_UNIDIRECTIONAL_SUPPORT |
        BCMOLT_EPON_OAM_LOCAL_REMOTE_INFO_CONFIG_LINK_EVENTS;
    tlv->max_pdu_size = link_state->max_pdu_size;
    tlv->oui = BCMOLT_EPON_OAM_WELL_KNOWN_OUI_TEK;
    tlv->vendor_specific_information[0] = 0x06;
    tlv->vendor_specific_information[1] = 0x86;
    tlv->vendor_specific_information[2] = 0x20;
    tlv->vendor_specific_information[3] = 0xA0;
}

static void dump_std_info_tlv(const eon_link_key *link_key, const char *type, bcmolt_epon_oam_local_remote_info *info)
{
    EON_LINK_LOG(
        DEBUG,
        link_key,
        "%s: ver %02x rev %04x state %02x cfg %02x pdu %5u oui %06x vendor %02x%02x%02x%02x\n",
        type,
        info->oam_version,
        info->revision,
        info->state,
        info->oam_config,
        info->max_pdu_size,
        info->oui,
        info->vendor_specific_information[0],
        info->vendor_specific_information[1],
        info->vendor_specific_information[2],
        info->vendor_specific_information[3]);
}

static void dump_org_spec_tlv(const eon_link_key *link_key, bcmolt_epon_oam_organization_specific_info *org_spec)
{
    switch (org_spec->oui)
    {
        case BCMOLT_EPON_OAM_WELL_KNOWN_OUI_TEK:
            if (BCMOLT_EPON_OAM_TEK_INFO_TLV_TYPE_EXTENSION_SUPPORT == org_spec->u.tek.tlvs.type)
            {
                EON_LINK_LOG(
                    DEBUG, link_key, "BRCM Ext Support: ver %02x rpt %02x pref %02x\n",
                    org_spec->u.tek.tlvs.u.extension_support.version,
                    org_spec->u.tek.tlvs.u.extension_support.report_mode,
                    org_spec->u.tek.tlvs.u.extension_support.preferred_report_mode);
            }
            break;
        case BCMOLT_EPON_OAM_WELL_KNOWN_OUI_DPOE:
            if (BCMOLT_EPON_OAM_DPOE_INFO_TLV_TYPE_DPOE_OAM_SUPPORT == org_spec->u.dpoe.dpoe_info_tlv.type)
            {
                EON_LINK_LOG(
                    DEBUG, link_key, "DPoE Support: ver %02x\n",
                    org_spec->u.dpoe.dpoe_info_tlv.u.dpoe_oam_support.dpoe_oam_version);
            }
            break;
        case BCMOLT_EPON_OAM_WELL_KNOWN_OUI_CTC:
            EON_LINK_LOG(
                DEBUG, link_key, "CTC Extension Support %u, Preferred Version 0x%02x, Supports (%u):\n",
                org_spec->u.ctc.extension_support,
                org_spec->u.ctc.version,
                org_spec->u.ctc.supp_version_count);
            for (uint32_t i = 0; i < org_spec->u.ctc.supp_version_count; i++)
            {
                EON_LINK_LOG(
                    DEBUG, link_key, "\tOUI %06x, Version 0x%02x\n",
                    org_spec->u.ctc.supp_version[i].oui, org_spec->u.ctc.supp_version[i].version);
            }
            break;
        default:
            EON_LINK_LOG(WARNING, link_key, "No support for %06x\n", org_spec->oui);
            break;
    }
}

static void dump_info_frame(const bcmolt_epon_oam_ethernet_frame *oam, const eon_link_state* link_state)
{
    static const char* entname[] = {"ONU","OLT"};
    char da_buf[MAC_STR_LEN];
    char sa_buf[MAC_STR_LEN];
    bcmolt_epon_oam_oam_flags flags = oam->protocols[0].u.slow_protocol.value.u.oam.flags;
    uint8_t is_olt = (0 == memcmp(link_state->epon_ni_mac_addr.u8, oam->sa.u8, BCMOS_ETH_ALEN));
    uint8_t olt_stab = 0 !=
        (flags & (is_olt ? BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_STABLE : BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_STABLE));
    uint8_t onu_stab = 0 !=
        (flags & (is_olt ? BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_STABLE : BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_STABLE));
    uint8_t olt_eval = 0 !=
        (flags & (is_olt ? BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_EVALUATING : BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_EVALUATING));
    uint8_t onu_eval = 0 !=
        (flags & (is_olt ? BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_EVALUATING : BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_EVALUATING));

    EON_LINK_LOG(
        DEBUG, &link_state->link_key, "from %s: OLT %s  ONU %s\n", entname[is_olt],
        olt_stab ? "stab" : (olt_eval ? "eval" : "NONE"),
        onu_stab ? "stab" : (onu_eval ? "eval" : "NONE"));

    EON_LINK_LOG(DEBUG, &link_state->link_key, "               da                sa  eth su flgs cd\n");
    EON_LINK_LOG(
        DEBUG, &link_state->link_key, "%s %s %04x %02x %04x %02x\n",
        bcmos_mac_2_str(&oam->da, da_buf), bcmos_mac_2_str(&oam->sa, sa_buf),
        oam->protocols[0].ethertype, oam->protocols[0].u.slow_protocol.value.subtype,
        oam->protocols[0].u.slow_protocol.value.u.oam.flags,
        oam->protocols[0].u.slow_protocol.value.u.oam.content.code);
    EON_LINK_LOG(
        DEBUG, &link_state->link_key, "TLVS: (%u)\n",
        oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs_count);
    for (uint8_t i = 0; i < oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs_count; i++)
    {
        switch (oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs[i].type)
        {
            case BCMOLT_EPON_OAM_INFO_TLV_TYPE_LOCAL:
                dump_std_info_tlv(
                    &link_state->link_key,
                    "LOCAL",
                    &oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs[i].u.local.info);
                break;
            case BCMOLT_EPON_OAM_INFO_TLV_TYPE_REMOTE:
                dump_std_info_tlv(
                    &link_state->link_key,
                    "REMOTE",
                    &oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs[i].u.remote.info);
                break;
            case BCMOLT_EPON_OAM_INFO_TLV_TYPE_ORGANIZATION_SPECIFIC:
                dump_org_spec_tlv(
                    &link_state->link_key,
                    &oam->protocols[0].u.slow_protocol.value.u.oam.content.u.info.tlvs[i].u.organization_specific.value);
                break;
            default:
                break;
        }
    }
}

bcmos_errno build_tx_info_frame(eon_link_state *link_state, eon_frame_data *frame_data)
{
    bcmos_bool have_remote_info = link_state->remote_info.oam_version == get_oam_version();
    bcmolt_epon_oam_ethernet_frame oam_frame = {};
    bcmolt_epon_oam_ethernet_protocol protocol = {};
    bcmolt_epon_oam_info_tlv_base tlvs[4] = {};

    EON_LINK_LOG(DEBUG, &link_state->link_key, "BUILDING INFO FRAME, current state %04x\n", link_state->oam_state);

    oam_frame.da = slow_protocol_multicast_mac;
    oam_frame.sa = link_state->epon_ni_mac_addr;
    oam_frame.protocols_count = 1;
    oam_frame.protocols = &protocol;
    protocol.ethertype = BCMOLT_EPON_OAM_PROTOCOL_TYPE_SLOW_PROTOCOL;
    protocol.u.slow_protocol.value.subtype = BCMOLT_EPON_OAM_SLOW_PROTOCOL_SUBTYPE_OAM;
    protocol.u.slow_protocol.value.u.oam.flags = link_state->oam_state;
    protocol.u.slow_protocol.value.u.oam.content.code = BCMOLT_EPON_OAM_OAM_OPCODE_INFO;
    protocol.u.slow_protocol.value.u.oam.content.u.info.tlvs_count = 1;
    protocol.u.slow_protocol.value.u.oam.content.u.info.tlvs = tlvs;
    tlvs[0].type = BCMOLT_EPON_OAM_INFO_TLV_TYPE_LOCAL;
    fill_local_tlv(link_state, &tlvs[0].u.local.info);
    if (have_remote_info)
    {
        tlvs[1].type = BCMOLT_EPON_OAM_INFO_TLV_TYPE_REMOTE;
        tlvs[1].u.remote.info = link_state->remote_info;
        protocol.u.slow_protocol.value.u.oam.content.u.info.tlvs_count++;
    }
    add_org_spec_tlv[link_state->oam_set](link_state, &protocol.u.slow_protocol.value.u.oam.content);
    tlvs[protocol.u.slow_protocol.value.u.oam.content.u.info.tlvs_count].type = BCMOLT_EPON_OAM_INFO_TLV_TYPE_END;
    protocol.u.slow_protocol.value.u.oam.content.u.info.tlvs_count++;

    dump_info_frame(&oam_frame, link_state);

    return epon_oam_pack_frame(&oam_frame, &frame_data->payload, &frame_data->length);
}

/* OK = done
   in_progress = send next frame
   parse = ignore
   other = stop
   */
bcmos_errno handle_rx_info_frame(eon_link_state *link_state, uint16_t rx_length, uint8_t *rx_payload)
{
    bcmos_errno rc = BCM_ERR_IN_PROGRESS;
    bcmolt_epon_oam_oam_flags start_state;
    bcmolt_epon_oam_ethernet_frame *frame;
    bcmolt_epon_oam_slow_protocol *sp;
    bcmolt_epon_oam_organization_specific_info *org_spec = NULL;

    start_state = link_state->oam_state;
    EON_LINK_LOG(DEBUG, &link_state->link_key, "RECEIVED INFO FRAME, current state %04x\n", start_state);

    frame = epon_oam_unpack(link_state->link_key.device_id, rx_length, rx_payload);

    if ((frame->protocols_count == 0) ||
        (frame->protocols[0].ethertype != BCMOLT_EPON_OAM_PROTOCOL_TYPE_SLOW_PROTOCOL) ||
        (frame->protocols[0].u.slow_protocol.value.subtype != BCMOLT_EPON_OAM_SLOW_PROTOCOL_SUBTYPE_OAM) ||
        (frame->protocols[0].u.slow_protocol.value.u.oam.content.code != BCMOLT_EPON_OAM_OAM_OPCODE_INFO))
    {
        /* not an info frame, ignore */
        bcmos_free(frame);
        return BCM_ERR_PARSE;
    }

    dump_info_frame(frame, link_state);
    sp = &frame->protocols[0].u.slow_protocol.value;

    /* capture link's TLV for subsequent retransmission */
    if ((sp->u.oam.content.u.info.tlvs_count > 0) &&
        (sp->u.oam.content.u.info.tlvs[0].type == BCMOLT_EPON_OAM_INFO_TLV_TYPE_LOCAL))
    {
        link_state->remote_info = sp->u.oam.content.u.info.tlvs[0].u.local.info;
    }
    else
    {
        bcmos_free(frame);
        return BCM_ERR_ONU_ERR_RESP; /* no local info */
    }

    if (0 != memcmp(frame->da.u8, slow_protocol_multicast_mac.u8, sizeof(slow_protocol_multicast_mac)))
    {
        rc = BCM_ERR_ONU_ERR_RESP;
        EON_LINK_LOG(WARNING, &link_state->link_key,
                     "DA mismatch "BCMOS_MACADDR_FMT_STR" expected vs. "BCMOS_MACADDR_FMT_STR" actual\n",
                     BCMOS_MACADDR_PARAMS(&slow_protocol_multicast_mac), BCMOS_MACADDR_PARAMS(&frame->da));
    }

    if (0 != memcmp(frame->sa.u8, &link_state->link_key.link.mac_address, sizeof(frame->sa)))
    {
        rc = BCM_ERR_ONU_ERR_RESP;
        EON_LINK_LOG(WARNING, &link_state->link_key,
                     "SA mismatch "BCMOS_MACADDR_FMT_STR"  expected vs. "BCMOS_MACADDR_FMT_STR" actual\n",
                     BCMOS_MACADDR_PARAMS(&link_state->link_key.link.mac_address), BCMOS_MACADDR_PARAMS(&frame->sa));
    }

    if (sp->u.oam.content.u.info.tlvs[0].u.local.info.oam_version != get_oam_version())
    {
        rc = BCM_ERR_ONU_ERR_RESP;
        EON_LINK_LOG(WARNING, &link_state->link_key, "oam version mismatch 0x%02x expected vs. 0x%02x actual\n",
                     get_oam_version(), sp->u.oam.content.u.info.tlvs[0].u.local.info.oam_version);
    }

    /* Is the far end echoing the TLV we sent? */
    if ((sp->u.oam.content.u.info.tlvs_count > 1) &&
        (sp->u.oam.content.u.info.tlvs[1].type == BCMOLT_EPON_OAM_INFO_TLV_TYPE_REMOTE))
    {
        if (sp->u.oam.content.u.info.tlvs[0].u.local.info.max_pdu_size !=
            sp->u.oam.content.u.info.tlvs[1].u.remote.info.max_pdu_size)
        {
            link_state->max_pdu_size = MIN(
                sp->u.oam.content.u.info.tlvs[0].u.local.info.max_pdu_size,
                sp->u.oam.content.u.info.tlvs[1].u.remote.info.max_pdu_size);
            link_state->revision++;
        }
        else
        {
            bcmolt_epon_oam_local_remote_info loc_tlv = {};
            fill_local_tlv(link_state, &loc_tlv);
            if (0 == memcmp(&loc_tlv, &sp->u.oam.content.u.info.tlvs[1].u.remote.info, sizeof(loc_tlv)))
            {
                link_state->oam_state = (link_state->oam_state | BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_STABLE) &
                                        (~BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_EVALUATING);
                EON_LINK_LOG(DEBUG, &link_state->link_key, "setting LOCAL STABLE flag\n");
            }
            else
            {
                EON_LINK_LOG(WARNING, &link_state->link_key, "Remote TLV from ONU does NOT match what we sent\n");
            }
        }
    }

    if (sp->u.oam.flags & BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_EVALUATING)
    {
        link_state->oam_state = (link_state->oam_state | BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_EVALUATING) &
                                (~BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_STABLE);
        EON_LINK_LOG(DEBUG, &link_state->link_key, "setting REMOTE EVAL flag\n");
    }

    if (sp->u.oam.flags & BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_STABLE)
    {
        link_state->oam_state = (link_state->oam_state | BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_STABLE) &
                                (~BCMOLT_EPON_OAM_OAM_FLAGS_REMOTE_EVALUATING);
        EON_LINK_LOG(DEBUG, &link_state->link_key, "setting REMOTE STABLE flag\n");
    }

    if (LOCAL_STABLE_REMOTE_STABLE == link_state->oam_state)
    {
        rc = BCM_ERR_OK; /* basic negotiation complete */
    }

    if ((sp->u.oam.content.u.info.tlvs_count > 2) &&
        (sp->u.oam.content.u.info.tlvs[2].type == BCMOLT_EPON_OAM_INFO_TLV_TYPE_ORGANIZATION_SPECIFIC))
    {
        org_spec = &sp->u.oam.content.u.info.tlvs[2].u.organization_specific.value;
    }
    rx_org_spec_tlv[link_state->oam_set](link_state, org_spec, &rc);

    EON_LINK_LOG(DEBUG, &link_state->link_key, "state %04x -> %04x (%s)\n",
                 start_state, link_state->oam_state, bcmos_strerror(rc));

    bcmos_free(frame);

    return rc;
}

