/******************************************************************************
 *
 *  <: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_esw_flow.c
 * @brief BAL Switch util functions that handle flow requests
 * @addtogroup sw_util
 */
 
 /*@{*/
#include <bal_common.h>
#include <bcm_dev_log.h>
#include <bal_msg.h>
#include "bal_switch_flow.h"
#include "flow_fsm.h"
#include "bcmos_errno.h"
#include "bal_switch_util.h"

#ifndef TEST_SW_UTIL_LOOPBACK
#include <bcm/types.h>
#include <sal/core/libc.h>
#ifndef sal_memset
#define sal_memset memset
#endif
#include <bcm/port.h>
#include <bcm/vlan.h>
#include <bcm/field.h>
#include <bcm/error.h>
#include <sal/core/libc.h>

#include "bal_switch_acc_term.h"
#include "bal_esw_flow.h"
/**
 * @brief The acl add function add an Access Control Rule in the switch  VCAP/ICAP/ECAP
 *        to perform action based on flow classifier
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_flow  a pointer to the flow definition the created rule will be based on  
 * @return error code
 */
static bcm_field_group_t esw_group_id = 0;
/* add an ingress ACL rule */
static bcmos_errno bal_swapp_esw_acl_add(int unit, bcmbal_flow_cfg *p_flow)
{
     uint32_t ret, j; 
     uint32_t nni_phy;
     int vid;
     bcm_field_qset_t qset;
     bcm_field_entry_t eid;
     bcm_mac_t bcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
     bcm_mac_t dst_mask =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   
    do 
    {        
        vid = p_flow->data.classifier.o_vid;
 
        /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
        /* The KT2 resources allow only limit number of qset - indexed by esw_group_id, create qset when necessary */
        if (0 == esw_group_id)
        {
            BCM_FIELD_QSET_INIT(qset);
            BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageLookup);
            BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyOuterVlan);
            BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort);
            BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyDstMac);
            ret = bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &esw_group_id);
            if (ret != BCM_E_NONE)
            {
                 BCM_LOG(ERROR, log_id_sw_util, 
                                  " flow fail to create field - %d\n", ret );
                 break;
            }
        }

        /* if action is to drop broadcast, add an ACL in nni VCAP to  drop it */
        if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST)
        {             
            /* loop through all nni ports */
            for(j=0; -1 != (nni_phy = bal_bcm_net_inf_pbm_get(j)); j++)
            {
                if ( bal_bcm_net_inf_dev_get(j) != unit)
                {
                    continue; 
                }
                  
                ret = bcm_field_entry_create(unit, esw_group_id, &eid);
                if (ret != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util, 
                            " flow fail to create field entry for port %d - ret = %d\n", nni_phy, ret );
                    break;
                }            
               
                ret = bcm_field_qualify_DstMac(unit, eid, bcast_mac, dst_mask);
                if (ret != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to set field dst mac qualifier %d - ret = %d\n", nni_phy, ret );
                    break;
                }
                    
                ret = bcm_field_qualify_OuterVlanId(unit, eid, vid, 0xffff);
                if (ret != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to set field outer vlan qualifier %d - ret = %d\n", nni_phy, ret );
                    break;
                }
                ret = bcm_field_action_add(unit, eid, bcmFieldActionDrop, 0, 0);
                if (ret != BCM_E_NONE)
                {    
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to add action to the field entry %d - ret = %d\n", nni_phy, ret );
                    break;
                }   
                
                ret = bcm_field_entry_install(unit, eid);
                if (ret != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to install field entry %d - ret = %d\n", nni_phy, ret );
                    break;
                }      
            } /* for loop */
        } /* if drop bcast */
    } while(0);
   
     
     if (ret != BCM_E_NONE)
     {
         return BCM_ERR_INTERNAL;
     }
     
     return BCM_ERR_OK;
}

/**
 * @brief The ingress vlan translation function program switch to
 *  translate packet vlan attributes before the switch vaidate the
 *  vlan membership of the packets
 * @param unit    the switch unit this translation is perfromed
 * @param p_flow  a pointer to the flow that contains translation action  
 * @return        error code
 */
static bcmos_errno bal_swapp_esw_ivlanx(int unit, bcmbal_flow_cfg *p_flow)
{
    bcmos_errno ret = BCM_ERR_OK;    
    bcm_gport_t pon_gport;
    uint32_t pon_phy_pbm;    
    int bcm_rc;    
 
    /* find out which PON this action is to be performed */
    /* map pon logical port to physical port */
    pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
    /* create local gport based on pon physical port number */
    BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm); 
    
    do 
    {     
        /* For TR-156 1:1 uptream single tagged packets,
           S-tag add acton is performed in the INGRESS vlan translator.   
        */
       if (BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
       {
           if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG )
           {
               uint32_t u_ovid, u_ivid;
               bcm_vlan_action_set_t u_action;
               bcm_vlan_action_set_t_init(&u_action);
              
               /* set gpon ingress translaton to add outer tag on upstream packets */
               u_action.new_outer_vlan = p_flow->data.action.o_vid;
               u_action.priority       = p_flow->data.action.o_pbits;
               
               switch(p_flow->data.classifier.pkt_tag_type)
               {
                   case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                        u_action.ot_outer          = bcmVlanActionAdd; 
                        u_action.ot_outer_pkt_prio = bcmVlanActionReplace;
                        u_ovid                     = p_flow->data.classifier.o_vid;
                        u_ivid                     = BCM_VLAN_NONE;
                       break;
                   default: /* not supported, goto while(0) */
                        u_ovid                     = BCM_VLAN_NONE;
                        u_ivid                     = BCM_VLAN_NONE;
                        ret = BCM_ERR_INTERNAL;
                       continue;                                                    
               }    
               /* enable ingress vlan translation on specified port */                
               bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanTranslateIngressEnable, 1);
               if (bcm_rc != BCM_E_NONE)
               {
                   BCM_LOG(ERROR, log_id_sw_util,
                           " flow fail to enable ingress vlan translation on port %d - %d\n", 
                           pon_phy_pbm, bcm_rc );               
                   ret = BCM_ERR_INTERNAL;
                   break;
               } 
               /* set the outer vlan id as lookup key - i.e. packet filtering key */
               bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanPortTranslateKeyFirst, bcmVlanTranslateKeyOuter);
               if (bcm_rc != BCM_E_NONE)
               {
                   BCM_LOG(ERROR, log_id_sw_util,
                           " flow fail to set upstream lookup key on port %d - %d\n", 
                           pon_phy_pbm, bcm_rc );               
                   ret = BCM_ERR_INTERNAL;
                   break;
               } 
               /* install the action into ingress vlan translation table */
               bcm_rc = bcm_vlan_translate_action_add(unit, pon_gport, bcmVlanTranslateKeyOuter, u_ovid, u_ivid, &u_action);
               if (bcm_rc != BCM_E_NONE)
               {
                   BCM_LOG(ERROR, log_id_sw_util,
                           " flow fail to set ingress action on port %d - %d\n", 
                           pon_phy_pbm, bcm_rc );               
                   ret = BCM_ERR_INTERNAL;
                   break;
               }     
           }
           else 
           {
               BCM_LOG(ERROR, log_id_sw_util,
                       " flow upstream action 0x%x not supported\n", p_flow->data.action.cmds_bitmask);
                                                   
               ret = BCM_ERR_NOT_SUPPORTED;         
           }   
       }
  
    } while(0);
     
    return ret;
}

/**
 * @brief The engress vlan translation function program switch to
 *  translate packet vlan attributes before the packets were sent out
 *  
 * @param unit    the switch unit this translation is perfromed
 * @param p_flow  a pointer to the flow that contains translation action  
 * @return        error code
 */
static bcmos_errno bal_swapp_esw_evlanx(int unit, bcmbal_flow_cfg *p_flow)
{
    bcmos_errno ret = BCM_ERR_OK;    
    bcm_gport_t pon_gport;
    uint32_t pon_phy_pbm;    
    int bcm_rc;    
 
    /* find out which PON this action is to be performed */ 
    /* map pon logical port to physical port */
    pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
    /* create local gport based on pon physical port number */
    BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm); 
    
    do 
    {     
        /* For TR-156 1:1 downstream double tagged packets,
           S-tag remove acton is performed in the EGRESS vlan translator.   
        */
        if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow->key.flow_type)
        {
                
            if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG )
            {
                /* set gpon egress translaton to drop outer tag of double tag downstream packets */
                uint32_t d_ovid, d_ivid;
                bcm_vlan_action_set_t d_action;
                bcm_vlan_action_set_t_init(&d_action);
                switch(p_flow->data.classifier.pkt_tag_type)
                {
                    case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
                        d_action.dt_outer = bcmVlanActionDelete;
                        d_ovid = p_flow->data.classifier.o_vid;
                        d_ivid = p_flow->data.classifier.i_vid;
                        break;
                   
                    default: /* not supported, goto while(0) */
                        d_ovid   = BCM_VLAN_NONE;
                        d_ivid   = BCM_VLAN_NONE;
                        ret = BCM_ERR_INTERNAL;
                        continue;                                                    
                }    
                /* enable egress vlan translation on specified port */                     
                bcm_rc = bcm_vlan_control_port_set(unit, pon_gport, bcmVlanTranslateEgressEnable, 1);
                if (bcm_rc != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to enable egress vlan translation on port %d - %d\n", 
                            pon_phy_pbm, bcm_rc );               
                    ret = BCM_ERR_INTERNAL;
                    break;
                }
 
                /* install the action into egress vlan translation table */                    
                bcm_rc = bcm_vlan_translate_egress_action_add(unit, pon_gport, d_ovid, d_ivid, &d_action);                              
                if (bcm_rc != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " flow fail to set egress action on port %d - %d\n", 
                            pon_phy_pbm, bcm_rc );               
                    ret = BCM_ERR_INTERNAL;
                    break;
                }         
           }
           else 
           {
               BCM_LOG(ERROR, log_id_sw_util,
                       " flow downstream action 0x%x not supported\n", p_flow->data.action.cmds_bitmask);
                                                   
                   ret = BCM_ERR_NOT_SUPPORTED;         
           }   
        
       }
  
    } while(0);
     
    return ret;
}


/**
 * @brief The flow add function program KT2 to forward packets that have
 * specified attributes to the designated ports.
 * The packets is modified before egress
 * On the downstream, an access id (outer vlan tag) is added to the packets
 * On the upstream, outer vlan tag (access id) is removed from the packets
 *
 * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
 * @param p_flow A pointer to the requested add flow info
 * @return error code
 */
bcmos_errno bal_sw_util_esw_flow_add(bcmbal_iwf_mode iwf_mode,  bcmbal_flow_cfg *p_flow)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcm_gport_t pon_gport;
    uint32_t pon_phy_pbm;
    bcm_vlan_t vlan_id;
    bcm_gport_t nni_gport;
    uint32_t nni_phy_pbm;
    int ii;
    int bcm_rc;
    int unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id);

    BCM_LOG(INFO, log_id_sw_util,
            " Got an ESW flow request - iwf_mode=%d flow_id=%d  sub_port=%d svc_id=%d\n",
            iwf_mode, 
            p_flow->key.flow_id, p_flow->data.access_int_id, p_flow->data.svc_port_id);
    BCM_LOG(DEBUG, log_id_sw_util,
            " classifier - mask=0x%llx otpid=%x itpid=%x ovid=%x ivid=%x\n",
            (unsigned long long)p_flow->data.classifier.presence_mask,
            p_flow->data.classifier.o_tpid, p_flow->data.classifier.i_tpid,
            p_flow->data.classifier.o_vid, p_flow->data.classifier.i_vid);

    /* 
     * First, validate that the specified PON has at least one NNI port on the same device.
     * If not, return an error, as this is not supported.
     */
    ii = 0;
    ret = BCM_ERR_NOT_SUPPORTED;
    /* walk through the entire mapping table */
    while(-1 != bal_bcm_net_inf_pbm_get(ii))
    {
        if(bal_bcm_net_inf_dev_get(ii) == unit)
        {
            ret = BCM_ERR_OK;
            break;
        }
        ii++; /* Next NNI */
    }

    do 
    {
        /*
         * Check return code from device check above.  Return if there was an error.
         */
        if(BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: no network port is on the same device as access port %d\n", p_flow->data.access_int_id);
            break;
        }

        /* create vlan domain for this flow */        
        vlan_id = (bcm_vlan_t)p_flow->data.classifier.o_vid;
        bcm_rc = bcm_vlan_create(unit, vlan_id);

        /* if OK or already existed, continue */
        if (bcm_rc != BCM_E_NONE && bcm_rc != BCM_E_EXISTS)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " failed to create vlan %d on unit %d - bcm_rc:%d\n", vlan_id, unit, bcm_rc );
            ret = BCM_ERR_INTERNAL;
            break;
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util,
                    " vlan %d %s on unit %d - bcm_rc:%d\n", 
                    vlan_id, 
                    (BCM_E_EXISTS == bcm_rc) ? "reused" : "created",
                    unit, 
                    bcm_rc );
        }

        /* map pon logical port to physical port */
        pon_phy_pbm = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);

        /* create gport based on pon physical port number */
        BCM_GPORT_LOCAL_SET(pon_gport, pon_phy_pbm);
                                                   
        /* add the specified pon to vlan */
        bcm_rc = bcm_vlan_gport_add(unit, vlan_id, pon_gport, BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP);

        if (bcm_rc != BCM_E_NONE)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " flow fail to add pon %d (pbm %d, gport %d) into vlan %d - %d\n", 
                    p_flow->data.access_int_id, pon_phy_pbm, pon_gport, vlan_id, bcm_rc );
                
            ret = BCM_ERR_INTERNAL;

            break;
        }

        /* Add all the NNI ports that are on the same device to the vlan as well */

        ii = 0;  /* Start with the first NNI logical interface */

        /* map nni logical ports to physical ports */
        while(-1 != (nni_phy_pbm = bal_bcm_net_inf_pbm_get(ii)))
        {
            if ( bal_bcm_net_inf_dev_get(ii) != unit)
            {
                continue; 
            }
            /* create gport based on nni physical port number */
            BCM_GPORT_LOCAL_SET(nni_gport, nni_phy_pbm);
                
            bcm_rc = bcm_vlan_gport_add(unit, vlan_id, nni_gport, BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP);

            if (bcm_rc != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        " flow fail to add nni %d (pbm %d, gport %d) into vlan %d - %d\n", 
                        ii, nni_phy_pbm, nni_gport, vlan_id, bcm_rc );
                     
                ret = BCM_ERR_INTERNAL;

                break;
            }

            ii++; /* Next NNI */
        }
        
        /* perform the ACTION */
        if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action) 
            /* && BCMOS_TRUE == BCMBAL_ATTRIBUTE_CFG_PROP_IS_SET(&p_flow->data.action, action, action_cmds_bitmask) */
            )
        {
            BCM_LOG(INFO, log_id_sw_util,
                    " Got a flow action - flow type = %d, cmd=%d in_ovid=%d, out_ovid=%d\n", 
                    p_flow->key.flow_type, p_flow->data.action.cmds_bitmask,
                    p_flow->data.classifier.i_vid, p_flow->data.classifier.o_vid);
                           
            /* enable vlan translation */
            bcm_rc = bcm_vlan_control_set(unit, bcmVlanTranslate, 1);
            if (bcm_rc != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        " flow fail to enable vlan translation - %d\n", 
                        bcm_rc );               
                ret = BCM_ERR_INTERNAL;
                break;
            }            
            /* For TR-156 1:1 downstream,
               ACTIONs are performed on the EGRESS vlan translator.
               For TR-156 1:1 upstream,
               ACTIONs are perform on the INGRESS vlan translator. 
               For TR-156 N:1 there is no actions for switch
               The outer tag adding is per PON base, i.e. upstream packets with same
               inner vid can add different outer vid based on receiving PON 
            */
            if (BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
            {
                if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG )
                {
                    ret = bal_swapp_esw_ivlanx(unit, p_flow); 
                }    
            }
            else if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow->key.flow_type)/* downstream */
            { 
                if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG )
                {
                    ret = bal_swapp_esw_evlanx(unit, p_flow);                
                }    
            }
            else  /* broadcast */
            {
                if ( p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_DISCARD_DS_BCAST)
                {
                    ret = bal_swapp_esw_acl_add(unit, p_flow);
                }   
                
            }   
        } /* end if ACTION set */

    } while(0);

        
    return ret;
}

/**
 * @brief The flow remove function remove switch resource that were allocated during ADD
 *
 * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
 * @param p_flow A pointer to the requested add flow info
 * @return error code
 */
bcmos_errno bal_sw_util_esw_flow_remove(bcmbal_iwf_mode iwf_mode,  bcmbal_flow_cfg *p_flow)
{
    return BCM_ERR_OK;
}

#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */

/*@}*/
