openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

cint_sat.c (73169B)


      1 /*
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  */
      6 
      7 /*
      8  * File: cint_sat.c
      9  *
     10  * Background:
     11  *     Service Activation Test (SAT) feature is basically a validation of an Ethernet Service for a customer 
     12  *     by a service provider operator before activating theservice. The customer may be another operator, 
     13  *     upstream or downstream, or an end-point customer. It is usually done with an Ethernet Test Equipment and involves a Truck Roll to 
     14  *     the premises where the network endpoint or the intermediate point resides. 
     15  *     The industry is moving towards the use of embedded test application within the network switch element.
     16  * 
     17  *     The SAT implementation borrows concept of MEP points from Ethernet OAM. Each SAT MEP has an Rx and Tx point. 
     18  *     These SAT MEP Tx/Rx points in SAT context are defined as Service Activation Measurement Points (SAMP). 
     19  *     SAT MEP Rx point is where a SAT packet coming from wire is trapped and sent to OLP. 
     20  *     SAT MEP Tx point is where a SAT packet is injected from OLP before going out on wire.
     21  * 
     22  *     A SAT MEP (SAMP) can perform one or all of the functions defined below:
     23  *     Generator Function (GTF):  SAT logic that injects test frames for OVC/EVC at specified rate and 
     24  *                                Test frames processed like customer service frames.
     25  *     Collector Function (CTF):  SAT Test frames are processed like customerservice frames and 
     26  *                                logic has instrumentation counters for SAT.
     27  *     Reflector Function (Latching Loopback Function): Loops back customerservice frames 
     28  *                                at remote end for two-way measurement with GTF and CTF at the same end.
     29  * 
     30  * Purpose: 
     31  *     Example of using SAT APIs.
     32  *     The following CINT provides a calling sequence example to Setup one GTF and one CTF. 
     33  *
     34  * Global - configure sequence:
     35  *     1. global configure
     36  *        - Call bcm_sat_config_set()
     37  * 
     38  * GTF - Set up sequence:
     39  *     1. Create GTF Object
     40  *        - Call bcm_sat_gtf_create()
     41  *     2. Configure packet info, including header type, header info, payload, packet edit info and packet offset. 
     42  *        Note: The format of SAT packet transsmitted from GTF is defined in MEF Sat spec.
     43  *        - Call bcm_sat_gtf_packet_config()
     44  *     3. Set Bandwidth
     45  *        - Call bcm_sat_gtf_bandwidth_set()
     46  *     4. Set Rate Pattern
     47  *        - Call bcm_sat_gtf_rate_pattern_set()
     48  *
     49  * CTF - Set up sequence:
     50  *     1. Create CTF Object
     51  *        - Call bcm_sat_ctf_create()
     52  *     2. Use PMF to capture the sat packets to OAMP
     53  *        - Call bcm_field_group_create()
     54  *     3. Map identification to specific flow
     55  *        - Call bcm_sat_ctf_trap_add()
     56  *        - Call bcm_sat_ctf_trap_data_to_session_map()
     57  *        - Call bcm_sat_ctf_identifier_map()
     58  *     4. Get the collected information
     59  *        - Call bcm_sat_ctf_stat_get()
     60  *
     61  *
     62  * To Activate Above Settings Run:
     63  *     BCM> cint examples/sat/cint_sat.c
     64  *     BCM> cint 
     65  *     cint> print sat_setup(0);
     66  *     cint> print sat_cleanup(0);
     67  */
     68 
     69 int is_xgs = 1;                             /* Device Type Configure */
     70 
     71 /************** Packet Parameters - used by both GTF and CTF ******************/
     72 bcm_mac_t pkt_dmac = {0x00, 0x00, 0x00, 0xca, 0xfe, 0xda};
     73 bcm_mac_t pkt_smac = {0x00, 0x00, 0x00, 0xca, 0xfe, 0x5a};
     74 bcm_vlan_t pkt_vlans[2] = {0x100, 0x200};
     75 uint8 pkt_vlan_pri[2] = {0, 1};
     76 uint8 pkt_vlan_cfi[2] = {0, 0};
     77 uint16 pkt_ether_type = 0x8902;
     78 /* FL Packet Related Rarameter */
     79 uint32 gtf_seq_number_offset = -1;             
     80 /* FD Packet Related Rarameter */
     81 uint32 gtf_timestamp_offset = 0;
     82 
     83 /************** CTF Parameters ******************/
     84 bcm_field_group_t grp;
     85 int trap_id=0;
     86 int trap_code_qualifier = 0;
     87 bcm_sat_ctf_identifier_t identifier;
     88 bcm_sat_ctf_t ctf_id = 0;
     89 
     90 /************** PMF for receiving SAT packet on JR2 ******************/
     91 bcm_field_group_t sat_fg_id=0;
     92 bcm_field_entry_t sat_fg_entry_id = 0;
     93 bcm_field_context_t sat_field_context_id;
     94 /*  
     95  * Create a FG to capture matched packets to SAT engine.
     96  * The filter can be SA, DA, SIP, DIP or other packet's fields.
     97  */
     98 int ctf_jer_specific_config(int unit, int ctf_id) {
     99  
    100     bcm_field_qset_t qset;
    101     bcm_field_aset_t aset;
    102     bcm_field_entry_t ent;
    103     int group_priority = 1;
    104     bcm_ip_t src_ip = 0x0a0a0a0a;
    105     bcm_ip_t src_ip_mask = 0xffffffff;
    106     bcm_ip_t dst_ip = 0x0b0b0b0b;
    107     bcm_ip_t dst_ip_mask = 0xffffffff;
    108     uint32 dest_port = 232; /*dest_port (OAMP PP port)*/
    109     bcm_gport_t sat_gport;
    110     bcm_rx_trap_config_t trap_config;
    111     bcm_sat_config_t sat_cfg;
    112     uint32 oam_value = 0;
    113     int rv = 0;
    114     /* uint16 ether_type = 0x8902;  */
    115 
    116     rv = bcm_sat_config_get(unit, &sat_cfg);
    117     if (BCM_E_NONE != rv) {
    118         printf("Error in bcm_sat_config_get\n");
    119         return rv;
    120     }
    121     oam_value = (sat_cfg.timestamp_format == bcmSATTimestampFormatIEEE1588v1) ? 0x8000: 0xC000;
    122 
    123     /* Create a trap for SAT */
    124     /* create trap */
    125     rv = bcm_rx_trap_type_create(unit, 0, bcmRxTrapUserDefine, &trap_id);
    126     if (rv != BCM_E_NONE) {
    127         printf("Error in bcm_rx_trap_type_create (%s) \n",bcm_errmsg(rv));
    128         return rv;
    129     }
    130 
    131     sal_memset(&trap_config, 0, sizeof(trap_config));
    132     trap_config.flags = (BCM_RX_TRAP_UPDATE_DEST | BCM_RX_TRAP_TRAP | BCM_RX_TRAP_REPLACE);
    133     trap_config.trap_strength = 0;
    134     trap_config.dest_port = dest_port;
    135     
    136     rv = bcm_rx_trap_set(unit, trap_id, &trap_config);
    137     if (rv != BCM_E_NONE) {
    138         printf("Error in bcm_rx_trap_set (%s) \n",bcm_errmsg(rv));
    139         return rv;
    140     }
    141     BCM_GPORT_TRAP_SET(sat_gport, trap_id, 7, 0);
    142 
    143     /* Jericho specific - set PMF */
    144     BCM_FIELD_QSET_INIT(qset);
    145     BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageIngress);
    146     BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyOuterVlan);
    147 
    148     BCM_FIELD_ASET_INIT(aset);
    149     BCM_FIELD_ASET_ADD(aset, bcmFieldActionTrap);
    150     BCM_FIELD_ASET_ADD(aset, bcmFieldActionOam);
    151 
    152     rv = bcm_field_group_create(unit, qset, group_priority, &grp);
    153     if (BCM_E_NONE != rv) {
    154         printf("Error in bcm_field_group_create\n");
    155         return rv;
    156     }
    157 
    158     rv = bcm_field_group_action_set(unit, grp, aset);
    159     if (BCM_E_NONE != rv) {
    160         printf("Error in bcm_field_group_action_set\n");
    161         return rv;
    162     }
    163 
    164     rv = bcm_field_group_install(unit, grp);
    165     if (BCM_E_NONE != rv) {
    166         printf("Error in bcm_field_group_install\n");
    167         return rv;
    168     }
    169 
    170     rv = bcm_field_entry_create(unit, grp, &ent);
    171     if (BCM_E_NONE != rv) {
    172         printf("Error in bcm_field_entry_create\n");
    173         return rv;
    174     }
    175 
    176     /*rv = bcm_field_qualify_SrcIp(unit, ent, src_ip, src_ip_mask); 
    177     if (BCM_E_NONE != rv) {
    178         printf("Error in bcm_field_qualify_SrcIp\n");
    179         return rv;
    180     }
    181 
    182     rv = bcm_field_qualify_DstIp(unit, ent, dst_ip, dst_ip_mask); 
    183     if (BCM_E_NONE != rv) {
    184         printf("Error in bcm_field_qualify_DstIp\n");
    185         return rv;
    186     }
    187     
    188     rv = bcm_field_qualify_EtherType(unit, ent, ether_type, 0xFFFF);
    189     if (BCM_E_NONE != rv) {
    190         printf("Error in bcm_field_qualify_EtherType\n");
    191         return rv;
    192     }*/
    193 
    194     rv = bcm_field_qualify_OuterVlan(unit, ent, 5, 0xFFFF);
    195     if (BCM_E_NONE != rv) {
    196         printf("Error in bcm_field_qualify_EtherType\n");
    197         return rv;
    198     }
    199 
    200     /*rv = bcm_field_qualify_InPort(unit, ent, 40, 0xFFFFFFFF);
    201     if (BCM_E_NONE != rv) {
    202         printf("Error in bcm_field_qualify_EtherType\n");
    203         return rv;
    204     }*/
    205 
    206     /* Trap the packets to SAT engine, and update the FHEI header as followed.
    207      * Trap-Code:           trap_id
    208      * Trap-Qualifier: ctf_id
    209      * 
    210      * In this case, 
    211      *  As for the Trap-Code, viewed it as the trap origin
    212      *  As for the Trap-Qualifier, viewed it as the SAT test flow-id
    213      */
    214 
    215 
    216     trap_code_qualifier = ctf_id;
    217     rv = bcm_field_action_add(unit, ent, bcmFieldActionTrap, sat_gport, trap_code_qualifier); 
    218     if (BCM_E_NONE != rv) {
    219         printf("Error in bcm_field_action_add -- bcmFieldActionTrap\n");
    220         return rv;
    221     }
    222 
    223     rv = bcm_field_action_add(unit, ent, bcmFieldActionOam, oam_value, 0);
    224     if (BCM_E_NONE != rv) {
    225         printf("Error in bcm_field_action_add -- bcmFieldActionOam\n");
    226         return rv;
    227     }
    228 
    229     rv = bcm_field_entry_install(unit, ent);
    230     if (BCM_E_NONE != rv) {
    231         printf("Error in bcm_field_entry_install\n");
    232         return rv;
    233     }
    234 
    235     return 0;
    236 }
    237 
    238 /*
    239  * Set followed CTF configuration.
    240  *   Set recieved packet information.
    241  *   Add trap id, it is used to mapping identification to specific flow.
    242  *   Set a mapping between trap qualifier and session id.
    243  *   Set a mapping between identification and specific flow.
    244  *   Set Statistic collecting configuration.
    245  *   Set Availability configuration
    246  */
    247 int ctf_general_config(int unit, bcm_sat_ctf_t ctf_id) {
    248  
    249     bcm_sat_ctf_packet_info_t packet_info;
    250     bcm_sat_ctf_stat_config_t stat_config;
    251     bcm_sat_ctf_availability_config_t availability_config;
    252     bcm_sat_ctf_bin_limit_t bins[9];
    253     int i = 0;
    254     int rv = 0;
    255 
    256     /* Set the recieved packet information */
    257     bcm_sat_ctf_packet_info_t_init(&packet_info);
    258     packet_info.sat_header_type = bcmSatHeaderUserDefined;
    259     if (gtf_timestamp_offset != 0) {
    260         packet_info.offsets.timestamp_offset = gtf_timestamp_offset - gtf_pkt_len_of_int_hdr;
    261     }
    262     else {
    263         packet_info.offsets.timestamp_offset = gtf_timestamp_offset;
    264     }
    265     if (gtf_seq_number_offset != -1) {
    266         packet_info.offsets.seq_number_offset = gtf_seq_number_offset - gtf_pkt_len_of_int_hdr;
    267     }
    268     else {
    269         packet_info.offsets.seq_number_offset = gtf_seq_number_offset;
    270     }
    271     
    272     /*packet_info.offsets.seq_number_offset = 30;*/
    273     /*packet_info.offsets.timestamp_offset = 22;*/
    274     
    275     packet_info.offsets.payload_offset = 32;
    276     packet_info.payload.payload_type = bcmSatPayloadConstant4Bytes;
    277     packet_info.offsets.crc_byte_offset = gtf_crc_byte_offset;
    278     packet_info.flags = BCM_SAT_CTF_PACKET_INFO_ADD_END_TLV | BCM_SAT_CTF_PACKET_INFO_ADD_CRC;
    279     rv = bcm_sat_ctf_packet_config (unit, ctf_id, &packet_info);
    280     if (BCM_E_NONE != rv) {
    281         printf("Error in bcm_sat_ctf_packet_config\n");
    282         return rv;
    283     }
    284 
    285     /* Add trap id, it is used to mapping identification to specific flow
    286      * Needn't add trap id for saber2 device as trap_id always is 0.
    287      * and it's same with default value.
    288      */
    289     if (is_xgs == 0) {
    290         rv = bcm_sat_ctf_trap_add(unit, trap_id);
    291         if (BCM_E_NONE != rv) {
    292             printf("Error in bcm_sat_ctf_trap_add\n");
    293             return rv;
    294         }
    295     }
    296     /* Map trap data to session id  */
    297     rv = bcm_sat_ctf_trap_data_to_session_map(unit, trap_code_qualifier, 0xff, 0);
    298     if (BCM_E_NONE != rv) {
    299         printf("Error in bcm_sat_ctf_trap_data_to_session_map\n");
    300         return rv;
    301     }
    302 
    303     /* Map identification to specific flow */
    304     bcm_sat_ctf_identifier_t_init(&identifier); 
    305     identifier.session_id = 0; /* the result from trap data mapping */
    306     identifier.trap_id = 0; /* index in trap_id array */
    307     identifier.color = 1;
    308     identifier.tc = 0;
    309     rv = bcm_sat_ctf_identifier_unmap(unit, &identifier);
    310     if (BCM_E_NONE != rv) {
    311         printf("Error in bcm_sat_ctf_identifier_unmap\n");
    312         return rv;
    313     }
    314     rv = bcm_sat_ctf_identifier_map(unit, &identifier, ctf_id);
    315     if (BCM_E_NONE != rv) {
    316         printf("Error in bcm_sat_ctf_identifier_map\n");
    317         return rv;
    318     }
    319 
    320     /* Statistic collecting configuration */
    321     bcm_sat_ctf_stat_config_t_init(stat_config);
    322     stat_config.use_global_bin_config = 0;
    323     stat_config.bin_min_delay = 50;
    324     stat_config.bin_step = 10;
    325     stat_config.update_counters_in_unvavail_state = 1;
    326     rv = bcm_sat_ctf_stat_config_set(unit, ctf_id, &stat_config);
    327     if (BCM_E_NONE != rv) {
    328         printf("Error in bcm_sat_ctf_stat_config_set\n");
    329         return rv;
    330     }
    331 
    332     /* If want to set configuration for each bin, please use followed BCM API */
    333     for (i = 0; i < 9; i++)
    334     {
    335         bins[i].bin_select = i;
    336         bins[i].bin_limit = 100 + i*100;
    337     }
    338     rv = bcm_sat_ctf_bin_limit_set(unit, 9, &bins);
    339     if (BCM_E_NONE != rv) {
    340         printf("Error in bcm_sat_ctf_bin_limit_set\n");
    341         return rv;
    342     }
    343 
    344     /* SAT Availability */
    345     bcm_sat_ctf_availability_config_t_init(&availability_config);
    346     availability_config.switch_state_num_of_slots = 10;
    347     availability_config.switch_state_threshold_per_slot = 100;
    348     rv = bcm_sat_ctf_availability_config_set(unit, ctf_id, &availability_config);
    349     if (BCM_E_NONE != rv) {
    350         printf("Error in bcm_sat_ctf_availability_config_set\n");
    351         return rv;
    352     }
    353 
    354     return 0;
    355 }
    356 
    357 /* Get the collected information */
    358 int ctf_general_show_results(int unit, bcm_sat_ctf_t ctf_id, int read_clear) {
    359  
    360     bcm_sat_ctf_stat_t stat;
    361     int i  = 0;
    362     int rv  = 0;
    363     uint32 flags = 0;
    364 
    365     if (read_clear == 0) {
    366         flags = BCM_SAT_CTF_STAT_DO_NOT_CLR_ON_READ;
    367     }
    368     rv = bcm_sat_ctf_stat_get (unit, ctf_id, flags, &stat);
    369     if (BCM_E_NONE != rv) {
    370         printf("Error in bcm_sat_ctf_stat_get\n");
    371         return rv;
    372     }
    373 
    374     printf("STAT informations:\n");
    375     print stat;
    376 
    377     return 0;
    378 }
    379 
    380 int cb_sat(int unit,
    381             bcm_sat_event_type_t event_type,
    382             bcm_sat_report_event_data_t *event_data,
    383             void *user_data) {
    384 
    385     print unit;
    386     print event_type;
    387     print *event_data;
    388 
    389     return 0;
    390 }
    391 
    392 int ctf_setup(int unit) {
    393 
    394     int rv = BCM_E_NONE;
    395 
    396     /* Create a CTF */
    397     rv = bcm_sat_ctf_create(unit, 0, &ctf_id);
    398     if (BCM_E_NONE != rv) {
    399         printf("Error in bcm_sat_ctf_create\n");
    400         return rv;
    401     }
    402 
    403     /* Capture the matched packets to SAT engine.
    404      * In Jericho, use PMF to capture packets to SAT engine.
    405      * In Saber2, use bcm_sat_endpoint_create() to capture 
    406      * packets to SAT engine.
    407      */
    408     if (is_xgs) {
    409 
    410       /* Configure OLP header - already implemented in olp_config() .
    411          * These bcm command should be convert to BCM APIs by IDC
    412          * as IDC is owner of this feature.
    413          */
    414 
    415         /*bshell(unit, "modify EGR_OLP_DGLP_CONFIG 0 1 DGLP=0x5 MACDA=0xD0C0");
    416         bshell(unit, "modify EGR_OLP_DGLP_CONFIG 1 1 DGLP=0x1f84 MACDA=0x100020304051");
    417         bshell(unit, "modify EGR_OLP_CONFIG 0 1 MACSA=0x202122232425 ETHERTYPE=0xb4b4 VLAN_TPID=0x8100");
    418         bshell(unit, "modify EGR_OLP_HEADER_TYPE_MAPPING 0 1 HDR_TYPE=1 HDR_SUBTYPE=12");
    419         bshell(unit, "modreg EGR_OLP_VLAN VLAN_TAG=0x8002");
    420         bshell(unit, "modreg EGR_OAM_RX_MODE_FOR_CPU ADD_OLP=1");*/
    421 
    422 
    423         /* Configure endpoint to trap the packet to OAMP port.
    424          * These bcm command should be convert to BCM APIs by IDC
    425          * as IDC is owner of this feature.
    426          */
    427 
    428         /*bshell(unit, "write ING_SAT_SAMP_TCAM 0 1 VALID=0x3 GLP=1 OTAG_VALID=1 OVID=0x100 MACSA=0xcafe5a MACDA=0xcafeda ETHERTYPE=0x8902 GLP_MASK=0xFFFF OTAG_VALID_MASK=0x1 OVID_MASK=0xFFF MACSA_MASK=0xFFFFFFFFFFFF MACDA_MASK=0xFFFFFFFFFFFF");
    429         bshell(unit, "write ING_SAT_SAMP_DATA 0 1 FORWARD_ACTION=0x1 COPYTO_CPU=0 DESTINATION=0x5 ADD_OLP_HDR=0x1 SAMPLE_TIMESTAMP=1 TIMESTAMP_TYPE=1 SAT_SESSION_ID=0xFF INT_PRI=0 OLP_HDR_TYPE_COMPRESSED=0x0");*/
    430 
    431       bcm_sat_endpoint_info_t endpoint_info;
    432 
    433       /* UPMEP SAT TCAM Key fields */
    434       endpoint_info.flags = BCM_SAT_ENDPOINT_DOWNMEP | 
    435                             BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN;
    436 
    437       endpoint_info.outer_vlan = pkt_vlan_pri[0]<<13 | pkt_vlan_cfi[0]<<12 | pkt_vlans[0];
    438       endpoint_info.src_gport = 0x8000001;
    439       endpoint_info.ether_type = pkt_ether_type;
    440 	  sal_memcpy(endpoint_info.src_mac_address, pkt_smac, 6);
    441 	  sal_memcpy(endpoint_info.dst_mac_address, pkt_dmac, 6);
    442 
    443       /* UPMEP SAT TCAM Data fields */
    444       endpoint_info.action_flags = BCM_SAT_ACTION_FWD_ACTION_REDIRECT;
    445       endpoint_info.action_flags |= BCM_SAT_ACTION_SAMPLE_TIMESTAMP;
    446       endpoint_info.dest_gport = 0x8000005;
    447       endpoint_info.timestamp_format = 1;
    448       endpoint_info.session_id = 0xff;
    449 
    450       rv = bcm_sat_endpoint_create(unit, &endpoint_info);
    451       if(rv != BCM_E_NONE)
    452       {
    453         printf("Error ! Failed to create SAT endpoint rv %d \n",rv);
    454         return rv;
    455       }
    456       /* It will be used as trap_data in bcm_sat_ctf_trap_data_to_session_map() */
    457       trap_code_qualifier = endpoint_info.session_id;
    458     } else {
    459         rv = ctf_jer_specific_config(unit, ctf_id);
    460         if (BCM_E_NONE != rv) {
    461             printf("Error in ctf_jer_specific_config\n");
    462             return rv;
    463         }
    464     }
    465     /* Set CTF configuration */
    466     rv = ctf_general_config(unit, ctf_id);
    467     if (BCM_E_NONE != rv) {
    468         printf("Error in ctf_general_config\n");
    469         return rv;
    470     }
    471 
    472     /*Set CTF Report*/
    473     bcm_sat_ctf_report_config_t ctf_report_config;
    474     bcm_sat_ctf_report_config_t_init(&ctf_report_config);
    475     ctf_report_config.report_sampling_percent = 90;
    476     ctf_report_config.flags = BCM_SAT_CTF_REPORT_ADD_SEQ_NUM;
    477     rv = bcm_sat_ctf_reports_config_set(unit, ctf_id, &ctf_report_config);  
    478     if (BCM_E_NONE != rv) {
    479         printf("Error in bcm_sat_ctf_reports_config_set\n");
    480         return rv;
    481     }
    482 
    483    /* Sat event register
    484     rv = bcm_sat_event_register(unit, bcmSATEventReport, cb_sat, (void*)1);
    485     if (BCM_E_NONE != rv) {
    486         printf("Error in bcm_sat_event_register\n");
    487         return rv;
    488     }
    489     */
    490 
    491     /* Get the collected information */
    492     rv = ctf_general_show_results(unit, ctf_id, 1);
    493     if (BCM_E_NONE != rv) {
    494         printf("Error in ctf_general_show_results\n");
    495         return rv;
    496     }
    497 
    498     return rv;
    499 
    500 }
    501 
    502 /* Clean up CTF configuration */
    503 int ctf_setup_cleanup(int unit) {
    504 
    505     int rv = BCM_E_NONE;
    506 
    507     /* clean up */
    508     /* Set the CTF flow as invalid  */
    509     rv = bcm_sat_ctf_identifier_unmap(unit, &identifier);
    510     if (BCM_E_NONE != rv) {
    511         printf("Error in soc_sat_ctf_identifier_unmap\n");
    512         return rv;
    513     }
    514 
    515     /* Remove all trap id */
    516     rv = bcm_sat_ctf_trap_remove_all(unit);
    517     if (BCM_E_NONE != rv) {
    518         printf("Error in bcm_sat_ctf_trap_add\n");
    519         return rv;
    520     }
    521 
    522     /* Destroy the CTF flow */
    523     rv = bcm_sat_ctf_destroy(unit, ctf_id);
    524     if (BCM_E_NONE != rv) {
    525         printf("Error in bcm_sat_ctf_destroy\n");
    526         return rv;
    527     }
    528 
    529     return rv;
    530 
    531 }
    532 
    533 /**************Gtf Structure*********************************/
    534 enum gtf_test_mode_e {
    535     gtf_test_mode_fl_down,         /* Test SAT Frame LM Packet for Down Mep */
    536     gtf_test_mode_fl_up,           /* Test SAT Frame LM Packet for Up   Mep */
    537     gtf_test_mode_fd_down,         /* Test SAT Frame DM Packet for Down Mep */
    538     gtf_test_mode_fd_up            /* Test SAT Frame DM Packet for Up   Mep */
    539 };
    540 
    541 /**************Envrionment Configure**********************/
    542 int gtf_debug_on = 1;                       /* Gtf Debug */
    543 
    544 int gtf_test_mode = gtf_test_mode_fl_down;
    545 uint32 gtf_counters = 0;
    546 
    547 /**************Gtf Object*********************************/
    548 bcm_sat_gtf_t gtf_id;
    549 
    550 /**************Gtf Packet Parameter***********************/
    551 bcm_sat_header_type_t gtf_header_type = bcmSatHeaderUserDefined;
    552 
    553 bcm_sat_payload_type_t gtf_payload_type = bcmSatPayloadConstant8Bytes;
    554 uint8 gtf_payload_pattern[BCM_SAT_PAYLOAD_MAX_PATTERN_SIZE] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
    555 
    556 uint32 gtf_packet_length[BCM_SAT_GTF_NUM_OF_PRIORITIES][BCM_SAT_GTF_PACKET_LENGTH_NUM_OF_PATTERNS] = {                                                /* 6bytes dune header + 64bytes */
    557     {64, 128, 256, 512, 1024, 1280, 1518, 9000},
    558 	{64, 128, 256, 512, 1024, 1280, 1518, 9000}};
    559 uint32 gtf_packet_length_pattern[BCM_SAT_GTF_NUM_OF_PRIORITIES][BCM_SAT_GTF_PACKET_MAX_PATTERN_LENGTH] = {
    560     {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},
    561 	{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}};
    562 uint32 gtf_pattern_length[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {1,1};
    563 
    564 bcm_sat_stamp_type_t gtf_stamp_type[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {
    565     {bcmSatStampConstant2Bit, bcmSatStampCounter8Bit, bcmSatStampCounter16Bit},
    566     {bcmSatStampConstant2Bit, bcmSatStampCounter8Bit, bcmSatStampCounter16Bit}};
    567 bcm_sat_stamp_field_t gtf_stamp_field[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {
    568     {bcmSatStampFieldUserDefined, bcmSatStampFieldOuterVlan, bcmSatStampFieldSrcMac},
    569     {bcmSatStampFieldUserDefined, bcmSatStampFieldOuterVlan, bcmSatStampFieldSrcMac}};
    570 uint32 gtf_stamp_inc_step[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {
    571     {1, 1, 1},
    572 	{1, 1, 1}};
    573 uint32 gtf_stamp_inc_period_packets[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {
    574     {1, 1, 1},
    575     {1, 1, 1}};
    576 uint32 gtf_stamp_value[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {
    577     {1, 0, 0},
    578     {2, 0, 0}};
    579 uint32 gtf_stamp_offset[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = {                      /* start from ethernet header, index of first bit is 1 */ 
    580     {50, 1, 1},            /* stamp last two bits of SMAC to differentiate cir and eir */
    581     {50, 1, 1}};
    582 uint32 gtf_number_of_stamps[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {0,0};
    583 
    584 uint32 gtf_number_of_ctfs[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {1,1};
    585 
    586 uint32 gtf_add_data_tlv = 0;                          /* valid only when there is one paket length for one GTF */
    587 uint32 gtf_add_end_tlv = 1;
    588 uint32 gtf_add_crc = 0;
    589 uint32 gtf_crc_byte_offset = 38;
    590 
    591 /* FD Packet Related Rarameter */
    592 uint32 gtf_ts_offset = 22;                            /* length of ethernet header + offset in FD PDU */
    593 
    594 /**************Gtf Bandwidth Parameter*********************/
    595 uint32 gtf_bw_cir_rate = 100;                             /* traffic rate - 5G.  Units: kbps */
    596 uint32 gtf_bw_cir_max_burst = 1000;                     /* traffic burst - 1Mbit. Units: kbit */
    597 uint32 gtf_bw_eir_rate = 100;                             /* traffic rate - 5G.  Units: kbps */
    598 uint32 gtf_bw_eir_max_burst = 1000;                     /* traffic burst - 1Mbit. Units: kbit */
    599 
    600 /**************Gtf Rate Pattern Parameter******************/
    601 bcm_sat_gtf_rate_pattern_mode_t gtf_rate_pattern_mode = bcmSatGtfRatePatternInterval;
    602 uint32 gtf_rate_pattern_high = 10;               /* 10kbits */
    603 uint32 gtf_rate_pattern_low = 10;                /* 10kbits */
    604 uint32 gtf_rate_pattern_stop_iter_count = 1000;      /* Stop after 1000 iterations */
    605 uint32 gtf_rate_pattern_stop_burst_count = 10000;
    606 uint32 gtf_rate_pattern_stop_interval_count = 10000; 
    607 uint32 gtf_rate_pattern_burst_packet_weight = 1;     /* Every packet in burst state increases the counter by 1 */
    608 uint32 gtf_rate_pattern_interval_packet_weight = 1;  /* Every packet in interval state increases the counter by 1 */
    609 
    610 /**************GTF Packet Parameter - Packet Header******************/
    611 bcm_port_t gtf_source_port = 13;    /* For UP-MEP case, port from where traffic will exit ASIC */
    612 bcm_port_t gtf_dst_port = 0;        /* Port where MEP resides. GTF simulate traffic generation from this port */
    613 int        gtf_dst_modid = 0;                        /* relevant to XGS */
    614 
    615 uint16 gtf_tpids[2] = {0x8100, 0x9100};
    616 int gtf_no_tags = 1;
    617 
    618 uint8 gtf_mel = 0x3;
    619 uint8 gtf_version = 0x0;
    620 uint8 gtf_fl_opcode = 43;
    621 uint8 gtf_fd_opcode = 47;
    622 uint8 gtf_flags = 0;
    623 uint16 gtf_source_mep_id = 0;
    624 uint32 gtf_session_id = 0x12345678;
    625 int   gtf_fd_timestamp_offset = 22; 
    626 
    627 /* Temp varible */
    628 bcm_gport_t gtf_dst_sys_port = 0;
    629 uint32 gtf_pkt_len_of_int_hdr = 0;
    630 uint32 gtf_data_tlv_type = 3;
    631 uint16 gtf_data_tlv_len = 0;
    632 
    633 /**********************OLP Parameter**************************/
    634 bcm_mac_t olp_mac = {0xc0, 0x94, 0x2f, 0xc3, 0x83, 0x9e};
    635 bcm_mac_t xgs_mac = {0xf2, 0x44, 0x49, 0x39, 0x30, 0xec};
    636 uint16 olp_tpid = 0xa96d;
    637 uint16 olp_vlan = 0xdd4;
    638 uint16 olp_ether_type = 0x5843;
    639 bcm_port_t olp_port = 5;
    640 uint32 olp_tx_header_subtype = 2;
    641 int olp_timestamp_action = 1;
    642 
    643 
    644 int olp_config(int unit) {
    645     int rv = BCM_E_NONE;
    646     int station_id;
    647     bcm_l2_station_t station;
    648     bcm_gport_t gport;
    649 
    650     rv = bcm_port_gport_get(unit, olp_port, &gport); 
    651     if (rv != BCM_E_NONE) {
    652         printf("Failed($rv) in bcm_port_gport_get\n");
    653         return rv;
    654     }
    655 
    656     /* set olp tpid */
    657     rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipTpid, olp_tpid);
    658     if (rv != BCM_E_NONE) {
    659         printf("Failed($rv) in bcmSwitchOamOlpChipEtherType\n");
    660         return rv;
    661     }
    662 
    663     /* set VLAN for olp-xgs communication */
    664     rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipVlan, olp_vlan);
    665     if (rv != BCM_E_NONE) {
    666         printf("Failed($rv) in bcmSwitchOamOlpChipVlan\n");
    667         return rv;
    668     }
    669 
    670     /* set olp ethertype */
    671     rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipEtherType, olp_ether_type);
    672     if (rv != BCM_E_NONE) {
    673         printf("Failed($rv) in bcmSwitchOamOlpChipEtherType\n");
    674         return rv;
    675     }
    676 
    677     /* set olp mac */
    678     station.flags = BCM_L2_STATION_OLP;
    679     station.src_port = gport;
    680     station.dst_mac[0] = olp_mac[0];
    681     station.dst_mac[1] = olp_mac[1];
    682     station.dst_mac[2] = olp_mac[2];
    683     station.dst_mac[3] = olp_mac[3];
    684     station.dst_mac[4] = olp_mac[4];
    685     station.dst_mac[5] = olp_mac[5];
    686     rv = bcm_l2_station_add(unit, &station_id, &station);
    687     if (rv != BCM_E_NONE) {
    688         printf("Failed($rv) in setting olp mac\n");
    689         return rv;
    690     }
    691 
    692     /* set xgs mac */
    693     station.flags = BCM_L2_STATION_XGS_MAC;
    694     station.src_port = gport;
    695     station.dst_mac[0] = xgs_mac[0];
    696     station.dst_mac[1] = xgs_mac[1];
    697     station.dst_mac[2] = xgs_mac[2];
    698     station.dst_mac[3] = xgs_mac[3];
    699     station.dst_mac[4] = xgs_mac[4];
    700     station.dst_mac[5] = xgs_mac[5];
    701     rv = bcm_l2_station_add(unit, &station_id, &station);
    702     if (rv != BCM_E_NONE) {
    703         printf("Failed($rv) in setting xgs mac\n");
    704         return rv;
    705     }
    706 	
    707 	return rv;
    708 }
    709 
    710 int l2_addr_add(int unit, bcm_mac_t mac, uint16 vid, bcm_gport_t port) {
    711     int rv = BCM_E_NONE;
    712 	bcm_l2_addr_t l2addr;
    713 
    714 	bcm_l2_addr_t_init(&l2addr, mac, vid);
    715     l2addr.port = port;
    716 	
    717     rv = bcm_l2_addr_add(unit, &l2addr);
    718     if (rv != BCM_E_NONE) {
    719         printf("Failed($rv) in bcm_l2_addr_add\n");
    720         return rv;
    721     }
    722 	
    723 	return rv;
    724 }
    725 
    726 int set_port_keep_tag(int unit, uint16 vid, bcm_port_t port) {
    727     int rv = BCM_E_NONE;
    728     bcm_pbmp_t pbmp, ut_pbmp;
    729 
    730     BCM_PBMP_PORT_SET(pbmp, port);
    731     BCM_PBMP_CLEAR(ut_pbmp);
    732     rv = bcm_vlan_port_remove(unit, vid, pbmp);
    733     if (rv != BCM_E_NONE) {
    734         printf("Failed($rv) in bcm_vlan_port_remove\n");
    735         return rv;
    736     }
    737 
    738     rv =  bcm_vlan_port_add(unit, vid, pbmp, ut_pbmp);
    739     if (rv != BCM_E_NONE) {
    740         printf("Failed($rv) in bcm_vlan_port_add\n");
    741         return rv;
    742     }
    743 	
    744 	return rv;
    745 }
    746 
    747 /* 
    748  *  PTCH-2 Header format:
    749  *    Field                      Size            Bit/s
    750  *    Parser-Program-Control     1               15
    751  *    Opaque-PT-Attributes       3               14:12
    752  *    Reserved                   4               11:8
    753  *    PP-SSP                     8               7:0
    754  */
    755 int _insert_dnx_ptch2(uint8* buffer, int byte_start_offset, 
    756     uint8 next_header_is_itmh, 
    757 	uint8 opaque_value, 
    758 	uint8 pp_ssp) 
    759 {
    760     int offset = byte_start_offset;
    761 	int parser_program_ctl = 0;
    762 
    763     parser_program_ctl = next_header_is_itmh ? 0 : 1;
    764     buffer[offset++] = (parser_program_ctl<<7) | (opaque_value<<4);
    765     buffer[offset++] = pp_ssp;
    766     
    767     return offset;
    768 }
    769 
    770 /* 
    771  *  Jericho-style ITMH Header format:
    772  *    Field                      Size            Bit/s
    773  *    PPH_TYPE                   2               31:30
    774  *    IN_MIRR_DISABLE            1               29
    775  *    FWD_DP                     2               28:27
    776  *    FWD_DEST_INFO              19              26:8
    777  *    SNOOP_CMD                  4               7:4
    778  *    FWD_TRAFFIC_CLASS          3               3:1
    779  *    ITMH_DESTINATION_INFO      1               0
    780  *    EXTENSION_EXISTS
    781  *
    782  *    Jericho-style FWD_DEST_INFO(19bits)
    783  *    1 1        Flow-ID(17)
    784  *    1 0      Multicast-ID(17)
    785  *    0 1     FEC-Pointer-ID(17)
    786  *    0 0 1   Dest-System-Port-Agr(16)
    787  */
    788 
    789 int _insert_dnx_itmh_jer(uint8* buffer, int byte_start_offset, 
    790     int dst_sys_port, 
    791 	uint8 fwd_tc, 
    792 	uint8 fwd_dp, 
    793 	uint8 snoop_cmd, 
    794 	uint8 in_mirr_flag, 
    795 	uint8 pph_type)
    796 {
    797     int offset = byte_start_offset;
    798     int fwd_dest_info = 1<<16 | dst_sys_port;
    799     int dest_exten = 0;
    800 
    801     buffer[offset++] = ((pph_type&0x3)<<6)|((in_mirr_flag&0x1)<<5)|((fwd_dp&0x3)<<3)|((fwd_dest_info&0x70000)>>16);
    802     buffer[offset++] = ((fwd_dest_info&0xff00)>>8);
    803     buffer[offset++] = (fwd_dest_info&0xff);
    804     buffer[offset++] = ((snoop_cmd&0xf)<<4)|((fwd_tc&0x7)<<1)|(dest_exten&0x1);
    805     
    806     return offset;
    807 }
    808 
    809 /* 
    810  *  Arad-style ITMH Header format:
    811  *    Field                      Size            Bit/s
    812  *    PPH_TYPE                   2               31:30
    813  *    IN_MIRR_DISABLE            1               29
    814  *    SNOOP_CMD                  4               28:25
    815  *    FWD_TRAFFIC_CLASS          3               24:22
    816  *    FWD_DP                     2               21:20
    817  *    FWD_DEST_INFO              20              19:0
    818  *
    819  *    Arad-style FWD_DEST_INFO(20bits)
    820 
    821  *    0         Multicast-ID(19)
    822  *    1 0 0     ISQ-Flow-ID(17)
    823  *    1 1 1        OUTLIT(17)
    824  *    1 1 0 0   Dest-System-Port-Agr(16)
    825  *    1 1 0 1    Multicast-Flow-ID(17)
    826  *    1 1 1        Flow-ID(17)
    827  */
    828 
    829 int _insert_dnx_itmh_arad(uint8* buffer, int byte_start_offset, 
    830     int dst_sys_port, 
    831 	uint8 fwd_tc, 
    832 	uint8 fwd_dp, 
    833 	uint8 snoop_cmd, 
    834 	uint8 in_mirr_flag, 
    835 	uint8 pph_type)
    836 {
    837     int offset = byte_start_offset;
    838     int fwd_dest_info = 0xc0000 | dst_sys_port;
    839     int dest_exten = 0;
    840 
    841     buffer[offset++] = ((pph_type&0x3)<<6)|((in_mirr_flag&0x1)<<5)|((snoop_cmd&0xf)<<1)|((fwd_tc&0x4)>>2);
    842     buffer[offset++] = ((fwd_tc&0x3)<<6) | ((fwd_dp&0x3)<<4) | ((fwd_dest_info&0xf0000)>>16);
    843     buffer[offset++] = (fwd_dest_info&0xff00)>>8;
    844     buffer[offset++] = (fwd_dest_info&0xff);
    845 
    846     return offset;
    847 }
    848 
    849 /* 
    850  *  OAM-TS Header format:
    851  *    Field                      Size            Bit/s
    852  *    Type                       2               47:46
    853  *    OAM-Sub-Type               3               45:43
    854  *    MEP-Type                   1               42
    855  *    OAM-TS-Data                34              41:8
    856  *    Offset                     8               7:0
    857  */
    858 
    859 int _insert_dnx_oam_ts(uint8* buffer, int byte_start_offset, 
    860 	uint8 type, 
    861 	uint8 sub_type,
    862 	uint8 is_up_mep,
    863 	uint64 ts_data,
    864 	uint8 ts_offset) 
    865 {
    866     int offset = byte_start_offset;
    867     int mep_type;
    868 	int ts_data_hi = 0, ts_data_lo = 0;	
    869 
    870     mep_type = is_up_mep?1:0;
    871 	ts_data_hi = COMPILER_64_HI(ts_data);
    872 	ts_data_lo = COMPILER_64_LO(ts_data);
    873     buffer[offset++] = ((type&0x3)<<6)|((sub_type&0x7)<<3)|((mep_type&0x1)<<2)|(ts_data_hi&0x3);	
    874     buffer[offset++] = (ts_data_lo&0xff000000)>>24;
    875 	buffer[offset++] = (ts_data_lo&0xff0000)>>16;
    876 	buffer[offset++] = (ts_data_lo&0xff00)>>8;
    877 	buffer[offset++] = (ts_data_lo&0xff);
    878     buffer[offset++] = ts_offset&0xff;
    879 
    880     return offset;
    881 }
    882 
    883 int _insert_dnx_pph_arad(uint8* buffer, int byte_start_offset)
    884 {
    885     int offset = byte_start_offset;
    886 
    887     buffer[offset++] = 0;
    888     buffer[offset++] = 0;
    889     buffer[offset++] = 0;
    890     buffer[offset++] = 0;
    891     buffer[offset++] = 0;
    892     buffer[offset++] = 0;
    893     buffer[offset++] = 0;
    894     
    895     return offset;
    896 }
    897 
    898 /* 
    899  *  XGS OLP L2 Header
    900  *    Field                      Size
    901  *    OLP-DA                     48
    902  *    OLP-SA                     48
    903  *    OLP-VLAN                   32
    904  */
    905 int _insert_xgs_olp_l2(uint8* buffer, int byte_start_offset, 
    906     bcm_mac_t dest_addr, 
    907 	bcm_mac_t src_addr, 
    908     uint16 tpid, 
    909 	bcm_vlan_t vlan, 
    910 	uint8 vlan_pri, 
    911 	uint8 vlan_cfi, 
    912 	uint16 ether_type) 
    913 {
    914     int i = 0, offset = byte_start_offset; 
    915     for (i = 0; i < 6; i++) {
    916         buffer[offset++] = dest_addr[i];
    917     }
    918     for (i = 0; i < 6; i++) {
    919         buffer[offset++] = src_addr[i];
    920     }
    921 
    922     buffer[offset++] = (tpid>>8)&0xff;
    923     buffer[offset++] = tpid&0xff;
    924     buffer[offset++] = (vlan_pri<<5)|((vlan_cfi&&0x1)<<4)|((vlan>>8)&0xff);        
    925     buffer[offset++] = vlan&0xff;
    926     
    927     buffer[offset++] = (ether_type>>8)&0xff;
    928     buffer[offset++] = ether_type&0xff;
    929 
    930     return offset;
    931 }
    932 
    933 /* 
    934  *  XGS OLP TX Header
    935  *  From SB2_OLP_Architecture_Spec_0.94_Clean.docx
    936  *    Field                                     Size     Bit/s    Bytes    Description
    937  *    Version                                      4     127:124  15       Version =0 for Saber 2 & Katana 2
    938  *    HEADER_TYPE                                  8     123:116  15-14    00=OAM_TX_HEADER
    939  *    HEADER_SUBTYPE                               8     115:108  14-13    03 = SAT_DOWN_MEP_TX
    940  *                                                                         04 = SAT_UPMEP_TX
    941  *    INT_PRI                                      4     107:104  13       Internal Priority used for UP-MEP Tx. DP is assumed to be green. 
    942  *    PORT_ID                                      16    103:88   12-11    [15-8] : MODID
    943  *                                                                         [7-0]  : PORT_NUM 
    944  *    COUNTER_1_LOCATION                           1     87       10       0 = in IP 
    945  *                                                                         1 = in EP
    946  *    COUNTER_1_ID                                 15    86:72    10-9     Counter ID to be incremented or sampled by this packet
    947  *    COUNTER_1_ACTION                             2     71:70    8        00: No-op 
    948  *                                                                         01: Increment 
    949  *                                                                         10: Sample
    950  *                                                                         11: reserved
    951  *    COUNTER_2_LOCATION                           1     69       8
    952  *    COUNTER_2_ID                                 15    68:54    8-6
    953  *    COUNTER_2_ACTION                             2     53:52    6
    954  *    TIMESTAMP_ACTION                             2     51:50    6        00: No-op 
    955  *                                                                         01: Sample 1588 Timestamp 
    956  *                                                                         10: Sample NTP Timestamp 
    957  *                                                                         11: Reserved
    958  *    OAM_REPLACEMENT_OFFSET                       8     49:42    6-5
    959  *    RELATIVE_LM_REPLACEMENT_OFFSET               4     41:38    5-4
    960  *    RELATIVE_LM_REPLACEMENT_OFFSET_ADD_OR_SUB    1     37       4
    961  *    COUNTER_3_LOCATION                           1     36       4
    962  *    COUNTER_3_ID                                 15    35:21    4-2
    963  *    COUNTER_3_ACTION                             2     20:19    2
    964  *    COUNTER1_OFFSET_TO_LM_PAYLOAD                6     18:13    2-1
    965  *    COUNTER2_OFFSET_TO_LM_PAYLOAD                6     12:7     1-0
    966  *    COUNTER3_OFFSET_TO_LM_PAYLOAD                6     6:1      0
    967  *    Reserved                                     1     0        0
    968  *    Total                      128
    969  */
    970 int _insert_xgs_olp_tx(uint8* buffer, int byte_start_offset, 
    971     int is_down_mep, 
    972 	int modid, 
    973 	int port, 
    974 	int timestamp_action,
    975 	int oam_offset) 
    976 {
    977     int offset = byte_start_offset;
    978     int version = 0;
    979 	int header_type = 0;
    980 	int header_subtype = (is_down_mep) ? (2) : (3);
    981 	int int_pri = 0;
    982 	
    983 	int oam_replacement_offset = 0;
    984 
    985     int counter_1_location = 0;
    986 	int counter_1_id = 0;
    987 	int counter_1_action = 0;
    988 	int counter_1_offset_to_lm_payload = 0;
    989     int counter_2_location = 0;
    990 	int counter_2_id = 0;
    991 	int counter_2_action = 0;
    992 	int counter_2_offset_to_lm_payload = 0;
    993     int counter_3_location = 0;
    994 	int counter_3_id = 0;
    995 	int counter_3_action = 0;
    996 	int counter_3_offset_to_lm_payload = 0;
    997 	
    998 	int relative_lm_repalce_offset = 0;
    999 	int relative_lm_repalce_offset_add_or_sub = 0;
   1000 	
   1001 	oam_replacement_offset = (oam_offset - 14) / 2;
   1002 
   1003     /* byte 15: Version    [3:0]->[7:4], 
   1004 	 *          header_type[7:4]->[3:0]
   1005 	 */
   1006     buffer[offset++] = ((version&0xf)<<4)|((header_type&0xf0)>>4); 
   1007 	/* byte 14: header_type   [3:0]->[7:4], 
   1008 	 *          header_subtype[7:4]->[3:0]
   1009 	 */
   1010 	buffer[offset++] = ((header_type&0xf)<<4)|((header_subtype&0xf0)>>4);        
   1011     /* byte 13: header_subtype[3:0]->[7:4], 
   1012      *          int_pri       [3:0]->[3:0]
   1013      */
   1014 	buffer[offset++] = ((header_subtype&0xf)<<4)|((int_pri&0xf)>>4);
   1015     /* byte 12: MODID [7:0]->[7:0] */
   1016 	buffer[offset++] = (modid&0xff);
   1017     /* byte 11: port  [7:0]->[7:0] */
   1018 	buffer[offset++] = (port&0xff);
   1019     /* byte 10: COUNTER_1_LOCATION [0]->[7]
   1020      *          COUNTER_1_ID       [14:8]->[6:0]
   1021 	 */
   1022     buffer[offset++] = 0;
   1023     /* byte  9: COUNTER_1_ID       [7:0]->[7:0] */
   1024     buffer[offset++] = 0;
   1025     /* byte  8: COUNTER_1_ACTION   [1:0]->[7:6]
   1026      *          COUNTER_2_LOCATION [0]->[5]
   1027 	 *          COUNTER_2_ID       [14:10]->[4:0]
   1028 	 */
   1029     buffer[offset++] = 0;
   1030     /* byte  7: COUNTER_2_ID       [9:2]->[7:0]
   1031 	 */
   1032     buffer[offset++] = 0;
   1033     /* byte  6: COUNTER_2_ID           [1:0]->[7:6]
   1034      *          COUNTER_2_ACTION       [1:0]->[5:4]
   1035 	 *          TIMESTAMP_ACTION       [1:0]->[3:2]
   1036 	 *          OAM_REPLACEMENT_OFFSET [7:6]->[1:0]
   1037 	 */
   1038     buffer[offset++] = ((timestamp_action&0x3)<<2)|((oam_replacement_offset&0xc0)>>6);
   1039     /* byte  5: OAM_REPLACEMENT_OFFSET         [5:0]->[7:2]
   1040 	 *          RELATIVE_LM_REPLACEMENT_OFFSET [3:2]->[1:0]
   1041  */
   1042     buffer[offset++] = (oam_replacement_offset&0x3f)<<2;
   1043     /* byte  4: RELATIVE_LM_REPLACEMENT_OFFSET            [1:0]->[7:6]
   1044 	 *          RELATIVE_LM_REPLACEMENT_OFFSET_ADD_OR_SUB [0]->[5]
   1045 	 *          COUNTER_3_LOCATION                        [0]->[4]
   1046 	 *          COUNTER_3_ID                              [14:11]->[3:0]
   1047 	 */
   1048     buffer[offset++] = 0;
   1049     /* byte  3: COUNTER_3_ID                              [10:3]->[7:0] */
   1050     buffer[offset++] = 0;
   1051     /* byte  2: COUNTER_3_ID                              [2:0]->[7:5]
   1052 	 *          COUNTER_3_ACTION                          [1:0]->[4:3]
   1053      *		    COUNTER1_OFFSET_TO_LM_PAYLOAD             [5:3]->[2:0]
   1054 	 */
   1055     buffer[offset++] = 0;
   1056     /* byte  1: COUNTER1_OFFSET_TO_LM_PAYLOAD             [2:0]->[7:5]
   1057 	 *          COUNTER2_OFFSET_TO_LM_PAYLOAD             [5:1]->[4:0]
   1058 	 */
   1059     buffer[offset++] = 0;
   1060     /* byte  0: COUNTER2_OFFSET_TO_LM_PAYLOAD             [0]->[7]
   1061 	 *          COUNTER2_OFFSET_TO_LM_PAYLOAD             [5:0]->[6:1]
   1062 	 *          Reserved                                  [0]->[0]
   1063 	 */
   1064     buffer[offset++] = 0;
   1065 
   1066     return offset;
   1067 }
   1068 
   1069 /* 
   1070  *  Insert Ethernet Header
   1071  */
   1072 int _insert_eth(uint8* buffer, int byte_start_offset,
   1073     bcm_mac_t dest_addr,
   1074 	bcm_mac_t src_addr, 
   1075     uint16* tpids,
   1076 	bcm_vlan_t* vlans,
   1077 	uint8* vlan_pri,
   1078 	uint8* vlan_cfi,
   1079 	int no_tags,
   1080 	uint16 ether_type) 
   1081 {
   1082     int i = 0, offset = byte_start_offset; 
   1083     for (i = 0; i < 6; i++) {
   1084         buffer[offset++] = dest_addr[i];
   1085     }
   1086     for (i = 0; i < 6; i++) {
   1087         buffer[offset++] = src_addr[i];
   1088     }
   1089     i = 0;
   1090     while (no_tags) {
   1091         buffer[offset++] = (tpids[i]>>8)&0xff;
   1092         buffer[offset++] = tpids[i]&0xff;
   1093         buffer[offset++] = (vlan_pri[i]<<5)|((vlan_cfi[i]&&0x1)<<4)|((vlans[i]>>8)&0xff);
   1094         buffer[offset++] = vlans[i]&0xff;
   1095         --no_tags;
   1096         i++;
   1097     }
   1098     
   1099     buffer[offset++] = (ether_type>>8)&0xff;
   1100     buffer[offset++] = ether_type&0xff;
   1101     
   1102     return offset;
   1103 }
   1104 
   1105 /* 
   1106  *  FL PDU Header format: Refer to MEF Sat spec.
   1107  */
   1108 int _insert_fl_pdu(uint8* buffer, int byte_start_offset, 
   1109     uint8 mel, 
   1110 	uint8 version,
   1111 	uint8 opcode,
   1112 	uint8 flags,
   1113 	uint8 tlv_offset,
   1114 	uint16 source_mep_id,
   1115 	uint32 session_id,
   1116 	uint8 add_data_tlv)
   1117 {    
   1118     int tmp = 0, offset = byte_start_offset; 
   1119     buffer[offset++] = ((mel&0x7)<<5)|(version&0x1f);
   1120     buffer[offset++] = opcode;
   1121     buffer[offset++] = flags;
   1122     buffer[offset++] = tlv_offset;                    /* TLV Offset: 16 */
   1123     buffer[offset++] = source_mep_id>>8;
   1124     buffer[offset++] = source_mep_id&0xff;
   1125     buffer[offset++] = 0;                             /* Reserved */
   1126     buffer[offset++] = 0;                             /* Reserved */
   1127     buffer[offset++] = (session_id>>24)&0xff;
   1128     buffer[offset++] = (session_id>>16)&0xff;
   1129     buffer[offset++] = (session_id>>8)&0xff;
   1130     buffer[offset++] = (session_id&0xff);
   1131     gtf_seq_number_offset = offset;                   /* Sequence Number */
   1132     offset += 4;
   1133     buffer[offset++] = 0;                             /* Reserved */
   1134     buffer[offset++] = 0;                             /* Reserved */
   1135     buffer[offset++] = 0;                             /* Reserved */ 
   1136     buffer[offset++] = 0;                             /* Reserved */
   1137 
   1138     if (add_data_tlv) {
   1139         tmp = offset - gtf_pkt_len_of_int_hdr;
   1140         gtf_data_tlv_len = gtf_packet_length[0][0] - tmp - 4 - 3;     /* 4bytes CRC for whole packet + 3bytes Data TLV Header */
   1141         gtf_data_tlv_len = gtf_add_crc?(gtf_data_tlv_len-4):gtf_data_tlv_len;
   1142         gtf_data_tlv_len = gtf_add_end_tlv?(gtf_data_tlv_len-1):gtf_data_tlv_len;
   1143 	
   1144         buffer[offset++] = gtf_data_tlv_type;                      /* Data TLV Type */
   1145         buffer[offset++] = (gtf_data_tlv_len>>8)&0xff;             /* Data TLV Length */
   1146         buffer[offset++] = (gtf_data_tlv_len&0xff);                /* Data TLV Length */
   1147     }
   1148     
   1149     return offset;
   1150 }
   1151 
   1152 /* 
   1153  *  FD PDU Header format: Refer to MEF Sat spec.
   1154  */
   1155 int _insert_fd_pdu(uint8* buffer, int byte_start_offset, 
   1156     uint8 mel, 
   1157 	uint8 version,
   1158 	uint8 opcode,
   1159 	uint8 flags,
   1160 	uint8 tlv_offset,
   1161 	uint8 add_data_tlv)
   1162 {    
   1163     int i = 0, tmp = 0, offset = byte_start_offset; 
   1164 	
   1165     buffer[offset++] = ((mel&0x7)<<5)|(version&0x1f);
   1166     buffer[offset++] = opcode;
   1167     buffer[offset++] = flags;
   1168     buffer[offset++] = tlv_offset;                    /* TLV Offset: 32 */
   1169 
   1170     gtf_timestamp_offset = offset;
   1171     for (i = 0; i < 8; i++) {                    /* TxTimeStampf: 8bytes */
   1172         buffer[offset++] = 0;
   1173     }
   1174 	
   1175     for (i = 0; i < 8; i++) {                    /* RxTimeStampf: 8bytes */
   1176         buffer[offset++] = 0;
   1177     }
   1178 
   1179     for (i = 0; i < 8; i++) {                    /* TxTimeStampb: 8bytes */
   1180         buffer[offset++] = 0;
   1181     }
   1182 
   1183     for (i = 0; i < 8; i++) {                    /* Reserved for DMR receiving equipment: 8bytes */
   1184         buffer[offset++] = 0x0;
   1185     }
   1186    
   1187     return offset;
   1188 }
   1189 
   1190 /* 
   1191  *  Dump data in buffer - For debug usage.
   1192  */
   1193 void _buffer_dump(uint8* buffer, int len) {
   1194     int i = 0;
   1195     printf("  len:%d\n", len);
   1196     printf("  data:");
   1197     for (i = 0; i < len; i++) {
   1198         if ((i % 16) == 0) printf("\n");
   1199         else if ((i % 4) == 0)  printf(" ");
   1200         printf("%02x", buffer[i]);
   1201     }
   1202     printf("\n\n");
   1203 }
   1204 
   1205 /* 
   1206  *  FL Packet format will be :
   1207  *    PTCH_2-O-ITMH-O-PPH-O-EthernetHeader-O-FL PDU for Down MEPs
   1208  */
   1209 int _sat_gtf_packet_header_config_fl_down(int unit, uint8* pkt_data) {
   1210     int offset = 0;
   1211 
   1212     /* 1. Prepare internal header */
   1213     if (!is_xgs) {
   1214         /* 1.1 Prepare internal DUNE header: PTCH */
   1215         offset = _insert_dnx_ptch2(pkt_data, offset, 
   1216             /* next_header_is_itmh */ 1, 
   1217             /* opaque_value */ 7, 
   1218             /* pp_ssp */ gtf_source_port);
   1219         if (gtf_debug_on) {
   1220             printf("After _insert_dnx_ptch2:\n");
   1221     		_buffer_dump(pkt_data, offset);
   1222         }
   1223     
   1224         /* 1.2 Prepare internal DUNE header: ITMH */
   1225         offset = _insert_dnx_itmh_jer(pkt_data, offset, 
   1226             /* dst_sys_port */ gtf_dst_sys_port, 
   1227             /* fwd_tc */ 3, 
   1228             /* fwd_dp */ 0, 
   1229             /* snoop_cmd */ 0, 
   1230             /* in_mirr_flag */ 0, 
   1231             /* pph_type */ 1);
   1232         if (gtf_debug_on) {
   1233             printf("After _insert_dnx_itmh:\n");
   1234             _buffer_dump(pkt_data, offset);
   1235         }
   1236 
   1237        /* 1.3 Prepare internal DUNE header: PPH */
   1238        offset = _insert_dnx_pph_arad(pkt_data, offset);    
   1239        if (gtf_debug_on) {
   1240            printf("After _insert_dnx_pph:\n");
   1241            _buffer_dump(pkt_data, offset);
   1242        }
   1243     }
   1244 	else {
   1245 	    /* 1.1 Prepare XGS OLP L2 Header */
   1246         offset = _insert_xgs_olp_l2(pkt_data, offset, 
   1247             /* dest_addr */ xgs_mac, 
   1248             /* src_addr */ olp_mac, 
   1249             /* tpid */ olp_tpid, 
   1250             /* vlan */ olp_vlan, 
   1251             /* vlan_pri */ 0, 
   1252             /* vlan_cfi */ 0, 
   1253 			/* ether_type */ olp_ether_type);
   1254         if (gtf_debug_on) {
   1255             printf("After _insert_xgs_olp_l2:\n");
   1256             _buffer_dump(pkt_data, offset);
   1257         }
   1258 		
   1259 		/* 1.2 Prepare XGS OLP TX Header */
   1260         offset = _insert_xgs_olp_tx(pkt_data, offset, 
   1261             /* is_down_mep */ 1, 
   1262             /* modid */ gtf_dst_modid, 
   1263             /* port */ gtf_dst_port,
   1264             /* timestamp_action */ 0,
   1265             /* oam_offset */ 0);
   1266         if (gtf_debug_on) {
   1267             printf("After _insert_xgs_olp_tx:\n");
   1268             _buffer_dump(pkt_data, offset);
   1269         }
   1270 	}
   1271 
   1272     gtf_pkt_len_of_int_hdr = offset;
   1273 
   1274     /* 2. Prepare Ethernet header */
   1275     offset = _insert_eth(pkt_data, offset, 
   1276         pkt_dmac, 
   1277         pkt_smac, 
   1278         gtf_tpids,
   1279         pkt_vlans, 
   1280         pkt_vlan_pri, 
   1281         pkt_vlan_cfi, 
   1282         gtf_no_tags, 
   1283         pkt_ether_type);
   1284     if (gtf_debug_on) {
   1285         printf("After _insert_eth:\n");
   1286         _buffer_dump(pkt_data, offset);
   1287     }
   1288     
   1289     /* 3. Prepare FL PDU header */
   1290     offset = _insert_fl_pdu(pkt_data, offset, 
   1291         gtf_mel, 
   1292         gtf_version, 
   1293         gtf_fl_opcode, 
   1294         gtf_flags, 
   1295 		/* tlv_offset */ 16,
   1296         gtf_source_mep_id, 
   1297         gtf_session_id, 
   1298         gtf_add_data_tlv);
   1299     if (gtf_debug_on) {
   1300         printf("After _insert_fl_pdu:\n");
   1301         _buffer_dump(pkt_data, offset);
   1302     }
   1303     
   1304     return offset;
   1305 }
   1306 
   1307 /* 
   1308  *  FL Packet format will be :
   1309  *    PTCH-2-O-EthernetHeader-O-FL PDU for Up MEPs
   1310  */
   1311 int _sat_gtf_packet_header_config_fl_up(int unit, uint8* pkt_data) {
   1312     int offset = 0;
   1313 
   1314     /* 1. Prepare internal header */
   1315     if (!is_xgs) {
   1316         /*1.1 Prepare internal DUNE header: PTCH */
   1317         offset = _insert_dnx_ptch2(pkt_data, offset, 
   1318             /* next_header_is_itmh */ 0, 
   1319             /* opaque_value */ 7, 
   1320             /* pp_ssp */ gtf_source_port);
   1321         if (gtf_debug_on) {
   1322             printf("After _insert_dnx_ptch2:\n");
   1323             _buffer_dump(pkt_data, offset);
   1324         }
   1325     }
   1326 	else {
   1327 	    /* 1.1 Prepare XGS OLP L2 Header */
   1328         offset = _insert_xgs_olp_l2(pkt_data, offset, 
   1329             /* dest_addr */ xgs_mac, 
   1330             /* src_addr */ olp_mac, 
   1331             /* tpid */ olp_tpid, 
   1332             /* vlan */ olp_vlan, 
   1333             /* vlan_pri */ 0, 
   1334             /* vlan_cfi */ 0, 
   1335 			/* ether_type */ olp_ether_type);
   1336         if (gtf_debug_on) {
   1337             printf("After _insert_xgs_olp_l2:\n");
   1338             _buffer_dump(pkt_data, offset);
   1339         }
   1340 		
   1341 		/* 1.2 Prepare XGS OLP TX Header */
   1342         offset = _insert_xgs_olp_tx(pkt_data, offset, 
   1343             /* is_down_mep */ 0, 
   1344             /* modid */ gtf_dst_modid, 
   1345             /* port */ gtf_dst_port,
   1346             /* timestamp_action */ 0,
   1347             /* oam_offset */ 0);
   1348         if (gtf_debug_on) {
   1349             printf("After _insert_xgs_olp_tx:\n");
   1350             _buffer_dump(pkt_data, offset);
   1351         }
   1352 	}
   1353 
   1354     
   1355 	gtf_pkt_len_of_int_hdr = offset;
   1356 	
   1357     /*2. Prepare Ethernet header */
   1358     offset = _insert_eth(pkt_data, offset, 
   1359         pkt_dmac, 
   1360 		pkt_smac, 
   1361 		gtf_tpids, 
   1362 		pkt_vlans, 
   1363 		pkt_vlan_pri, 
   1364 		pkt_vlan_cfi, 
   1365 		gtf_no_tags, 
   1366 		pkt_ether_type);
   1367     if (gtf_debug_on) {
   1368         printf("After _insert_eth:\n");
   1369         _buffer_dump(pkt_data, offset);
   1370     }
   1371     
   1372     /*3. Prepare FL PDU header */
   1373     offset = _insert_fl_pdu(pkt_data, offset, 
   1374         gtf_mel,
   1375         gtf_version,
   1376         gtf_fl_opcode,
   1377         gtf_flags,
   1378 		/* tlv_offset */ 16,
   1379         gtf_source_mep_id,
   1380         gtf_session_id, 
   1381         gtf_add_data_tlv);
   1382     if (gtf_debug_on) {
   1383         printf("After _insert_fl_pdu:\n");
   1384         _buffer_dump(pkt_data, offset);
   1385     }
   1386     
   1387     return offset;
   1388 }
   1389 
   1390 /* 
   1391  *  FD Packet format will be :
   1392  *    PTCH-2-O-ITMH-O-OAM-TS-O-EthernetHeader-O-FL PDU for Down MEPs
   1393  */
   1394 int _sat_gtf_packet_header_config_fd_down(int unit, uint8* pkt_data) {
   1395     int offset = 0;
   1396     int oam_sub_type = 3;
   1397     uint64 oam_ts_data;
   1398 
   1399     /* 1. Prepare internal header */
   1400     if (!is_xgs) {
   1401         /*1.1 Prepare internal DUNE header: PTCH */
   1402         offset = _insert_dnx_ptch2(pkt_data, offset, 
   1403             /* next_header_is_itmh */ 1, 
   1404             /* opaque_value */ 7, 
   1405             /* pp_ssp */ gtf_source_port);
   1406         if (gtf_debug_on) {
   1407             printf("After _insert_dnx_ptch2:\n");
   1408             _buffer_dump(pkt_data, offset);
   1409         }
   1410     
   1411         /*1.2 Prepare internal DUNE header: ITMH */
   1412         offset = _insert_dnx_itmh_jer(pkt_data, offset, 
   1413             /* dst_sys_port */ gtf_dst_sys_port, 
   1414             /* fwd_tc */ 3, 
   1415             /* fwd_dp */ 0, 
   1416             /* snoop_cmd */ 0, 
   1417             /* in_mirr_flag */ 0, 
   1418             /* pph_type */ 3);
   1419         if (gtf_debug_on) {
   1420             printf("After _insert_dnx_itmh:\n");
   1421             _buffer_dump(pkt_data, offset);
   1422         }
   1423 
   1424         /*1.3 Prepare internal DUNE header: OAM-TS */
   1425         bcm_sat_config_t config;
   1426         int rv = BCM_E_NONE;
   1427         rv = bcm_sat_config_get(unit, &config);
   1428         if (BCM_E_NONE != rv) {
   1429             printf("Error in bcm_sat_config_get\n");
   1430             return rv;
   1431         }
   1432         if (config.timestamp_format == bcmSATTimestampFormatIEEE1588v1){
   1433             oam_sub_type = 2;
   1434         }
   1435             
   1436         
   1437         COMPILER_64_ZERO(oam_ts_data);
   1438         offset = _insert_dnx_oam_ts(pkt_data, offset, 
   1439             /* type */ 0, 
   1440             /* sub_type */ oam_sub_type,
   1441             /* is_up_mep */ 0,
   1442             /* ts_data */ oam_ts_data,
   1443             /* ts_offset */ gtf_ts_offset);
   1444         if (gtf_debug_on) {
   1445             printf("After _insert_dns_oam_ts:\n");
   1446             _buffer_dump(pkt_data, offset);
   1447         }
   1448 
   1449         /*1.4 Prepare internal DUNE header: PPH */
   1450        offset = _insert_dnx_pph_arad(pkt_data, offset);    
   1451        if (gtf_debug_on) {
   1452            printf("After _insert_dnx_pph:\n");
   1453            _buffer_dump(pkt_data, offset);
   1454        }
   1455     }
   1456     else {
   1457 	    /* 1.1 Prepare XGS OLP L2 Header */
   1458         offset = _insert_xgs_olp_l2(pkt_data, offset, 
   1459             /* dest_addr */ xgs_mac, 
   1460             /* src_addr */ olp_mac, 
   1461             /* tpid */ olp_tpid, 
   1462             /* vlan */ olp_vlan, 
   1463             /* vlan_pri */ 0, 
   1464             /* vlan_cfi */ 0, 
   1465 			/* ether_type */ olp_ether_type);
   1466         if (gtf_debug_on) {
   1467             printf("After _insert_xgs_olp_l2:\n");
   1468             _buffer_dump(pkt_data, offset);
   1469         }
   1470 		
   1471 		/* 1.2 Prepare XGS OLP TX Header */
   1472         offset = _insert_xgs_olp_tx(pkt_data, offset, 
   1473             /* is_down_mep */ 1, 
   1474             /* modid */ gtf_dst_modid, 
   1475             /* port */ gtf_dst_port,
   1476             /* timestamp_action */ olp_timestamp_action,
   1477             /* oam_offset */ gtf_fd_timestamp_offset);
   1478         if (gtf_debug_on) {
   1479             printf("After _insert_xgs_olp_tx:\n");
   1480             _buffer_dump(pkt_data, offset);
   1481         }
   1482     }
   1483 
   1484     gtf_pkt_len_of_int_hdr = offset;
   1485 
   1486     /*4. Prepare Ethernet header */
   1487     offset = _insert_eth(pkt_data, offset, 
   1488         pkt_dmac, 
   1489         pkt_smac, 
   1490         gtf_tpids, 
   1491         pkt_vlans, 
   1492         pkt_vlan_pri, 
   1493         pkt_vlan_cfi, 
   1494         gtf_no_tags, 
   1495         pkt_ether_type);
   1496     if (gtf_debug_on) {
   1497         printf("After _insert_eth:\n");
   1498         _buffer_dump(pkt_data, offset);
   1499     }
   1500     
   1501     /*5. Prepare FD PDU header */
   1502     offset = _insert_fd_pdu(pkt_data, offset,
   1503         gtf_mel, 
   1504         gtf_version, 
   1505         gtf_fd_opcode,
   1506         gtf_flags,
   1507         /* tlv_offset */ 32,
   1508         gtf_add_data_tlv);
   1509     if (gtf_debug_on) {
   1510         printf("After _insert_fd_pdu:\n");
   1511         _buffer_dump(pkt_data, offset);
   1512     }
   1513     
   1514     return offset;
   1515 }
   1516 
   1517 /*
   1518  * setup an gtf:
   1519  *    1. Create an GTF Object
   1520  *    2. Configure packet info, including header type, header info, payload, packet edit info and packet offset.
   1521  *    3. Set Bandwidth
   1522  *    4. Set Rate Pattern
   1523  */
   1524 int sat_gtf_setup(int unit, bcm_sat_gtf_t *gtf_id) {
   1525     int rv = 0;    
   1526     bcm_sat_gtf_packet_config_t config;
   1527     bcm_pkt_t *sat_header;
   1528     uint8 pkt_data[128] = {0};
   1529     int pkt_size = 0;
   1530     bcm_sat_gtf_bandwidth_t bw;
   1531     bcm_sat_gtf_rate_pattern_t rate_pattern;
   1532     int i = 0, priority = 0;
   1533     bcm_gport_t dst_local_port;
   1534     bcm_gport_t dst_sys_port;
   1535 
   1536     if (!is_xgs) {
   1537         BCM_GPORT_LOCAL_SET(dst_local_port, gtf_dst_port);    
   1538         rv = bcm_stk_gport_sysport_get(unit, dst_local_port, &dst_sys_port);
   1539         if (rv != BCM_E_NONE) {
   1540             printf("Failed($rv) in bcm_stk_gport_sysport_get\n");
   1541             return rv;
   1542         }
   1543         gtf_dst_sys_port = BCM_GPORT_SYSTEM_PORT_ID_GET(dst_sys_port);
   1544         print gtf_dst_sys_port;
   1545     }
   1546 
   1547     if ((gtf_test_mode == gtf_test_mode_fl_up) || (gtf_test_mode == gtf_test_mode_fd_up)) {
   1548         bcm_port_t port;
   1549 
   1550         if (!is_xgs) {
   1551             port = gtf_dst_port;
   1552         } else {
   1553             port = gtf_source_port;
   1554             printf("UP-MEP: Simulate Traffic generated from %d and egress from %d \n", gtf_dst_port, gtf_source_port); 
   1555         }
   1556         
   1557         /* add l2 addr for UP Mep test */
   1558         rv = l2_addr_add(unit, pkt_dmac, pkt_vlans[0], port);
   1559         if (rv != BCM_E_NONE) {
   1560             printf("Failed($rv) in l2_addr_add\n");
   1561             return rv;
   1562         }
   1563 		
   1564         /* for egress port, configure to be transmitted as tagged */
   1565         rv = set_port_keep_tag(unit, pkt_vlans[0], port);
   1566         if (rv != BCM_E_NONE) {
   1567             printf("Failed($rv) in set_port_keep_tag\n");
   1568             return rv;
   1569         }
   1570     } 
   1571 
   1572     /* 1. Create GTF */
   1573     rv = bcm_sat_gtf_create(unit, 0, gtf_id);
   1574     if (rv != BCM_E_NONE) {
   1575         printf("Failed($rv) in bcm_sat_gtf_create\n");
   1576         return rv;
   1577     }
   1578     if (gtf_debug_on) printf("bcm_sat_gtf_create success\n");
   1579 
   1580     /* 2. Set Bandwidth */
   1581     bw.rate = gtf_bw_cir_rate;
   1582     bw.max_burst = gtf_bw_cir_max_burst;
   1583     rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, 0, &bw);
   1584     if (rv != BCM_E_NONE) {
   1585         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1586         return rv;
   1587     }
   1588     if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for cir success\n");
   1589 
   1590     bw.rate = gtf_bw_eir_rate;
   1591     bw.max_burst = gtf_bw_eir_max_burst;
   1592     rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, 1, &bw);
   1593     if (rv != BCM_E_NONE) {
   1594         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1595         return rv;
   1596     }
   1597     if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for eir success\n");
   1598 
   1599     bw.rate = gtf_bw_cir_rate + gtf_bw_eir_rate;
   1600     bw.max_burst = gtf_bw_cir_max_burst+ gtf_bw_eir_max_burst;
   1601     rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, -1, &bw);
   1602     if (rv != BCM_E_NONE) {
   1603         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1604         return rv;
   1605     }
   1606     if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for eir success\n");
   1607 
   1608     /* 3. Set Rate Pattern */
   1609     rate_pattern.rate_pattern_mode = gtf_rate_pattern_mode;
   1610     rate_pattern.high_threshold = gtf_rate_pattern_high;
   1611     rate_pattern.low_threshold = gtf_rate_pattern_low;
   1612     rate_pattern.stop_iter_count = gtf_rate_pattern_stop_iter_count;
   1613     rate_pattern.stop_burst_count = gtf_rate_pattern_stop_burst_count;
   1614     rate_pattern.stop_interval_count = gtf_rate_pattern_stop_interval_count;
   1615     rate_pattern.burst_packet_weight = gtf_rate_pattern_burst_packet_weight;
   1616     rate_pattern.interval_packet_weight = gtf_rate_pattern_interval_packet_weight;
   1617     rv = bcm_sat_gtf_rate_pattern_set(unit, *gtf_id, 0, &rate_pattern);
   1618     if (rv != BCM_E_NONE) {
   1619         printf("Failed($rv) in bcm_sat_gtf_rate_pattern_set\n");
   1620         return rv;
   1621     }
   1622     if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_set success\n");
   1623 
   1624     rv = bcm_sat_gtf_rate_pattern_set(unit, *gtf_id, 1, &rate_pattern);
   1625     if (rv != BCM_E_NONE) {
   1626         printf("Failed($rv) in bcm_sat_gtf_rate_pattern_set\n");
   1627         return rv;
   1628     }
   1629     if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_set success\n");
   1630 
   1631     /* 4. Configure packet */
   1632     bcm_sat_gtf_packet_config_t_init(&config);
   1633     
   1634     /* 4.1 Configure header type*/
   1635     config.sat_header_type = gtf_header_type;
   1636     
   1637     /* 4.2 Configure header info */
   1638     rv = bcm_pkt_alloc(unit, 128, 0, &sat_header); 
   1639     if (rv != BCM_E_NONE) {
   1640         printf("Failed($rv) in bcm_pkt_alloc\n");
   1641         return rv;
   1642     }
   1643     if (gtf_debug_on) printf("bcm_pkt_alloc success\n");
   1644 
   1645     switch(gtf_test_mode) {
   1646         case gtf_test_mode_fl_down:
   1647             pkt_size = _sat_gtf_packet_header_config_fl_down(unit, sat_header->pkt_data->data);
   1648             break;
   1649         case gtf_test_mode_fl_up:
   1650             pkt_size = _sat_gtf_packet_header_config_fl_up(unit, sat_header->pkt_data->data);
   1651             break;
   1652         case gtf_test_mode_fd_down:
   1653 		    pkt_size = _sat_gtf_packet_header_config_fd_down(unit, sat_header->pkt_data->data);
   1654 			break;
   1655         default:
   1656             printf("ERR: wrong gtf_test_mode(%d)\n", gtf_test_mode);
   1657             return BCM_E_PARAM;
   1658     }
   1659 
   1660     sat_header->pkt_data->len = pkt_size;
   1661 
   1662     config.header_info.pkt_data = sat_header->pkt_data;    
   1663     config.header_info.blk_count = 1;
   1664 
   1665     /* 4.3 Configure payload */
   1666     config.payload.payload_type = gtf_payload_type;
   1667 	if (config.payload.payload_type != bcmSatPayloadPRBS) {
   1668         for (i = 0; i < BCM_SAT_PAYLOAD_MAX_PATTERN_SIZE; i++) {
   1669 	        config.payload.payload_pattern[i] = gtf_payload_pattern[i];
   1670 	    }
   1671 	}
   1672     
   1673     /* 4.4 Configure packet edit */
   1674     for (priority = 0; priority < 2; priority++) {
   1675         for (i = 0; i < BCM_SAT_GTF_PACKET_LENGTH_NUM_OF_PATTERNS; i++) {
   1676             config.packet_edit[priority].packet_length[i] = gtf_packet_length[priority][i] + gtf_pkt_len_of_int_hdr - 4;  /* subtract 4bytes CRC for whole packet */
   1677         }
   1678         config.packet_edit[priority].pattern_length = gtf_pattern_length[priority];
   1679         for (i = 0; i < gtf_pattern_length[priority]; i++) {
   1680             config.packet_edit[priority].packet_length_pattern[i] = gtf_packet_length_pattern[priority][i];
   1681         }
   1682         config.packet_edit[priority].number_of_stamps = gtf_number_of_stamps[priority];
   1683         for (i = 0; i < gtf_number_of_stamps[priority]; i++) {
   1684             config.packet_edit[priority].stamps[i].stamp_type = gtf_stamp_type[priority][i];
   1685             config.packet_edit[priority].stamps[i].field_type = gtf_stamp_field[priority][i];
   1686             config.packet_edit[priority].stamps[i].inc_step = gtf_stamp_inc_step[priority][i];
   1687             config.packet_edit[priority].stamps[i].inc_period_packets = gtf_stamp_inc_period_packets[priority][i];
   1688             config.packet_edit[priority].stamps[i].value = gtf_stamp_value[priority][i];
   1689             config.packet_edit[priority].stamps[i].offset = gtf_stamp_offset[priority][i] + gtf_pkt_len_of_int_hdr*8;
   1690         }
   1691         config.packet_edit[priority].number_of_ctfs = gtf_number_of_ctfs[priority];
   1692 
   1693         if (gtf_add_end_tlv) {
   1694             config.packet_edit[priority].flags |= BCM_SAT_GTF_PACKET_EDIT_ADD_END_TLV;
   1695         }
   1696         if (gtf_add_crc) {
   1697             config.packet_edit[priority].flags |= BCM_SAT_GTF_PACKET_EDIT_ADD_CRC;
   1698         }
   1699     }
   1700 
   1701     /* 4.5 Configure packet offset */
   1702     config.offsets.seq_number_offset = gtf_seq_number_offset;
   1703     config.offsets.crc_byte_offset = gtf_crc_byte_offset + gtf_pkt_len_of_int_hdr;
   1704     config.offsets.timestamp_offset = gtf_timestamp_offset;
   1705 
   1706     if (is_xgs == 0) {
   1707 	    config.packet_context_id = 0;
   1708     }
   1709 	
   1710     rv = bcm_sat_gtf_packet_config(unit, *gtf_id, &config);
   1711     if (rv != BCM_E_NONE) {
   1712         printf("Failed($rv) in bcm_sat_gtf_packet_config\n");
   1713         return rv;
   1714     }
   1715     if (gtf_debug_on) printf("bcm_sat_gtf_packet_config success\n");
   1716 
   1717     /* 5. Start packet generation */
   1718     rv = bcm_sat_gtf_packet_start(unit, *gtf_id, bcmSatGtfPriAll);
   1719     if (rv != BCM_E_NONE) {
   1720         printf("Failed($rv) in bcm_sat_gtf_packet_start\n");
   1721         return rv;
   1722     }
   1723     if (gtf_debug_on) printf("bcm_sat_gtf_packet_start success\n");
   1724 
   1725     printf("create gtf(%d) success\n", *gtf_id);
   1726     return rv;  
   1727 }
   1728 
   1729 int sat_gtf_cleanup(int unit, bcm_sat_gtf_t gtf_id) {
   1730     int rv = 0;
   1731     bcm_sat_gtf_bandwidth_t bw;
   1732 
   1733     /* Reset GTF bandwidth */
   1734     bw.rate = 0;
   1735     bw.max_burst = 0;  
   1736     rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw);
   1737     if (rv != BCM_E_NONE) {
   1738         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1739         return rv;
   1740     }
   1741     rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw);
   1742     if (rv != BCM_E_NONE) {
   1743         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1744         return rv;
   1745     }
   1746     rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw);
   1747     if (rv != BCM_E_NONE) {
   1748         printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n");
   1749         return rv;
   1750     }
   1751 
   1752     /* Destroy the GTF Object */
   1753     rv = bcm_sat_gtf_destroy(unit, gtf_id);
   1754     if (BCM_E_NONE != rv) {
   1755         printf("Failed($rv) in bcm_sat_gtf_destroy\n");
   1756         return rv;
   1757     }
   1758     if (gtf_debug_on) printf("bcm_sat_gtf_destroy success\n");
   1759 
   1760     return rv;
   1761 }
   1762 
   1763 int sat_gtf_enable(int unit, bcm_sat_gtf_t gtf_id, int priority, int is_enable) {
   1764     int rv = 0;
   1765 
   1766     if (is_enable) {
   1767         /* Start packet generation */
   1768         rv = bcm_sat_gtf_packet_start(unit, gtf_id, priority);
   1769         if (BCM_E_NONE != rv) {
   1770             printf("Failed($rv) in bcm_sat_gtf_packet_start\n");
   1771             return rv;
   1772         }
   1773         if (gtf_debug_on) printf("bcm_sat_gtf_packet_start success\n");
   1774     }
   1775     else {
   1776         /* Stop packet generation */
   1777         rv = bcm_sat_gtf_packet_stop(unit, gtf_id, priority);
   1778         if (BCM_E_NONE != rv) {
   1779             printf("Failed($rv) in bcm_sat_gtf_packet_stop\n");
   1780             return rv;
   1781         }
   1782         if (gtf_debug_on) printf("bcm_sat_gtf_packet_stop success\n");
   1783     }
   1784 
   1785     return rv;
   1786 }
   1787 
   1788 int sat_gtf_show(int unit, bcm_sat_gtf_t gtf_id) {
   1789     int rv = 0;
   1790     bcm_sat_gtf_bandwidth_t bw;
   1791     bcm_sat_gtf_rate_pattern_t rate_pattern; 
   1792     uint64 stat_value;
   1793     int priority = 0;
   1794 
   1795     /* 1. Get Bandwidth */
   1796     for (priority = -1; priority < 2; priority++) {
   1797         rv = bcm_sat_gtf_bandwidth_get(unit, gtf_id, priority, &bw);
   1798         if (rv != BCM_E_NONE) {
   1799             printf("Failed($rv) in bcm_sat_gtf_bandwidth_get\n");
   1800             return rv;
   1801         }
   1802         if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_get success\n");
   1803         print bw;
   1804     }
   1805 
   1806     /* 2. Get Rate Pattern */
   1807     for (priority = 0; priority < 2; priority++) {
   1808         rv = bcm_sat_gtf_rate_pattern_get(unit, gtf_id, priority, &rate_pattern);
   1809         if (rv != BCM_E_NONE) {
   1810             printf("Failed($rv) in bcm_sat_gtf_rate_pattern_get\n");
   1811             return rv;
   1812         }
   1813         if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_get success\n");
   1814         print rate_pattern;
   1815     }
   1816 
   1817     /* 3. Get Stat */
   1818     for (priority = 0; priority < 2; priority++) {
   1819         rv = bcm_sat_gtf_stat_get(unit, gtf_id, priority, 0, bcmSatGtfStatPacketCount, &stat_value);
   1820         if (rv != BCM_E_NONE) {
   1821             printf("Failed($rv) in bcm_sat_gtf_stat_get\n");
   1822             return rv;
   1823         }
   1824         if (gtf_debug_on) printf("bcm_sat_gtf_stat_get success\n");
   1825         print stat_value;
   1826     }
   1827     
   1828     return 0;
   1829 }
   1830 
   1831 int sat_gtf_stat_show(int unit, bcm_sat_gtf_t gtf_id) {
   1832     int rv = 0;
   1833     uint64 stat_value;
   1834     int priority = 0;
   1835 
   1836     /* 1. Get Stat */
   1837     for (priority = 0; priority < 2; priority++) {
   1838         rv = bcm_sat_gtf_stat_get(unit, gtf_id, priority, 0, bcmSatGtfStatPacketCount, &stat_value);
   1839         if (rv != BCM_E_NONE) {
   1840             printf("Failed($rv) in bcm_sat_gtf_stat_get\n");
   1841             return rv;
   1842         }
   1843         if (gtf_debug_on) printf("bcm_sat_gtf_stat_get success\n");
   1844         print stat_value;
   1845     }
   1846     
   1847     return 0;
   1848 }
   1849 
   1850 /*
   1851 *  In Jericho, the gtf counters can't get correctly both during the SAT traffic and also after stopping SAT traffic
   1852 *  The workaround is avariable  if the sequence number is enabled.
   1853 */
   1854 int get_gtf_tx_counter(int chip, bcm_sat_gtf_t gtf_id_wk)
   1855 {
   1856     int rv=0;
   1857     int priority=0;
   1858     uint32 flags=0;
   1859     bcm_sat_gtf_stat_counter_t type=0;
   1860     uint32 value_last=0;
   1861     int cnt;
   1862     uint32 total_hi=0;
   1863     uint32 total_lo=0;
   1864     uint32 lo_work=0;
   1865     mem_val value = {0};
   1866 
   1867     /*start GTF pkt*/
   1868     rv |= bcm_sat_gtf_packet_start(chip, gtf_id_wk, bcmSatGtfPriCir);
   1869 
   1870     printf("The transmission of pkt begins.\n");
   1871     printf("... It waits for 10 seconds.\n");
   1872     sal_sleep(10);
   1873 
   1874     for(cnt=0; cnt<10; cnt++)
   1875     {
   1876         lo_work = total_lo;
   1877         /*get sequence number*/
   1878         diag_mem_field_get(0, "OAMP_SAT_TX_GEN_PARAMS", "SEQ_NUM_NXT_VALUE", (16 + gtf_id_wk), value);
   1879 
   1880         total_lo += (value[0] - value_last);
   1881         if(total_lo < lo_work)
   1882         {
   1883             total_hi += 1;
   1884         }
   1885         /*printf("[cnt=%04d] %08x %08x   ", cnt, total_hi, total_lo);
   1886         print (value[0] - value_last);*/
   1887         value_last = value[0];
   1888     }
   1889 
   1890     /*stop  pkt*/
   1891     rv |= bcm_sat_gtf_packet_stop(chip, gtf_id_wk, bcmSatGtfPriCir);
   1892 
   1893     printf("The transmission of pkt is stopped.\n");
   1894     printf("... It waits for 1 seconds.\n");
   1895     sal_sleep(1);
   1896 
   1897     /*get sequence number*/
   1898     diag_mem_field_get(0, "OAMP_SAT_TX_GEN_PARAMS", "SEQ_NUM_NXT_VALUE", (16 + gtf_id_wk) , value);
   1899 
   1900     total_lo += (value[0] - value_last);
   1901     if(total_lo < lo_work)
   1902     {
   1903         total_hi += 1;
   1904     }
   1905 
   1906     printf("[cnt=%04d] %08x %08x   ", cnt, total_hi, total_lo);
   1907     print value[0];
   1908     gtf_counters = value[0];
   1909     
   1910     return 0;
   1911 }
   1912 int sat_setup(int unit) {
   1913 
   1914     bcm_sat_config_t config;
   1915     int rv = BCM_E_NONE;
   1916 
   1917     /* global configuration */
   1918     bcm_sat_config_t_init(&config);
   1919     config.timestamp_format = bcmSATTimestampFormatNTP;
   1920     config.config_flags = 0;
   1921     rv = bcm_sat_config_set(unit, &config);
   1922     if (BCM_E_NONE != rv) {
   1923         printf("Error in bcm_sat_config_set\n");
   1924         return rv;
   1925     }
   1926 
   1927     /* setup a GTF */
   1928     rv = sat_gtf_setup(unit, &gtf_id);
   1929     if (BCM_E_NONE != rv) {
   1930         printf("Failed($rv) in sat_gtf_setup\n");
   1931         return rv;
   1932     }
   1933 
   1934     /* show GTF info */
   1935     rv = sat_gtf_show(unit, gtf_id);
   1936     if (BCM_E_NONE != rv) {
   1937         printf("Failed($rv) in sat_gtf_show\n");
   1938         return rv;
   1939     }
   1940 
   1941     /* setup a CTF */
   1942     rv = ctf_setup(unit);
   1943     if (BCM_E_NONE != rv) {
   1944         printf("Error in ctf_setup\n");
   1945         return rv;
   1946     }
   1947 
   1948     return rv;
   1949 
   1950 }
   1951 /**
   1952 * \brief
   1953 *  Add the PMF field group that SAT uses it to capture matched packets to SAT engine.
   1954 * \param [in] unit  - Device ID
   1955 * \param [in] in_port  - IN port
   1956 * \param [in] ctf_id   - CTF  ID
   1957 * \param [in] oam_offset - OAM offset to set in the OAM PMF action
   1958 * \return
   1959 *   int - Error Type
   1960 * \remark
   1961 *   * None
   1962 * \see
   1963 *   * None
   1964 */
   1965 int ctf_pmf_config_jr2(int unit,int in_port,bcm_gport_t sat_gport,int ctf_id,int oam_offset )
   1966 {
   1967     bcm_field_group_info_t fg_info;
   1968     bcm_field_group_attach_info_t attach_info;
   1969     bcm_field_entry_info_t ent_info;
   1970     bcm_field_context_info_t context_info;
   1971     bcm_field_presel_entry_data_t p_data;
   1972     bcm_field_presel_entry_id_t p_id;
   1973     int rv = BCM_E_NONE;
   1974     int trap_code_qualifier;
   1975     uint32 attach_presel = 5;
   1976     bcm_gport_t gport;
   1977 
   1978     bcm_field_group_info_t_init(&fg_info);
   1979     fg_info.fg_type = bcmFieldGroupTypeTcam;
   1980     fg_info.stage = bcmFieldStageIngressPMF1;
   1981 
   1982     /* Set quals */
   1983     fg_info.nof_quals = 1;
   1984     fg_info.qual_types[0] = bcmFieldQualifyInPort;
   1985     /*fg_info.qual_types[1] = bcmFieldQualifyStageIngress;*/
   1986 
   1987     /* Set actions */
   1988     fg_info.nof_actions = 2;
   1989     fg_info.action_types[0] = bcmFieldActionTrap;  /*bcmFieldActionTrapCodeQualifier */
   1990     fg_info.action_types[1] = bcmFieldActionOam;
   1991 
   1992     rv = bcm_field_group_add(unit, BCM_FIELD_FLAG_MSB_RESULT_ALIGN, &fg_info, &sat_fg_id);
   1993     if (rv != BCM_E_NONE)
   1994     {
   1995         printf("Error (%d), in bcm_field_group_add\n", rv);
   1996         return rv;
   1997     }
   1998     printf("Created TCAM field group (%d) in iPMF1 \n", sat_fg_id);
   1999 
   2000     /**Attach context**/
   2001     bcm_field_group_attach_info_t_init(&attach_info);
   2002     bcm_field_context_info_t_init(&context_info);
   2003 
   2004     rv = bcm_field_context_create(unit, 0, bcmFieldStageIngressPMF1, &context_info, &sat_field_context_id);
   2005     if (rv != BCM_E_NONE)
   2006     {
   2007         printf("Error (%d), in bcm_field_context_create\n", rv);
   2008         return rv;
   2009     }
   2010 
   2011     attach_info.key_info.nof_quals = fg_info.nof_quals;
   2012     attach_info.payload_info.nof_actions = fg_info.nof_actions;
   2013     attach_info.key_info.qual_types[0] = fg_info.qual_types[0];
   2014     attach_info.payload_info.action_types[0] = fg_info.action_types[0];
   2015     attach_info.payload_info.action_types[1] = fg_info.action_types[1];
   2016 
   2017     attach_info.key_info.qual_info[0].input_type = bcmFieldInputTypeMetaData;
   2018     attach_info.key_info.qual_info[0].input_arg = 1;
   2019     attach_info.key_info.qual_info[0].offset = 0;
   2020 
   2021 
   2022     rv = bcm_field_group_context_attach(unit, 0, sat_fg_id, sat_field_context_id, &attach_info);
   2023     if (rv != BCM_E_NONE)
   2024     {
   2025         printf("Error (%d), in bcm_field_group_context_attach\n", rv);
   2026         return rv;
   2027     }
   2028     printf("Attached  FG (%d) to context (%d)\n",sat_fg_id,sat_field_context_id);
   2029 
   2030     bcm_field_entry_info_t_init(&ent_info);
   2031     ent_info.priority = 1;
   2032     ent_info.nof_entry_quals = 1;
   2033 
   2034     ent_info.entry_qual[0].type = fg_info.qual_types[0];
   2035     /**in port 13*/
   2036     BCM_GPORT_LOCAL_SET(gport, in_port);
   2037     ent_info.entry_qual[0].value[0] = gport;
   2038     ent_info.entry_qual[0].mask[0] = 0xffffffff;
   2039 
   2040     trap_code_qualifier = ctf_id;
   2041     ent_info.nof_entry_actions = 2;
   2042     ent_info.entry_action[0].type = fg_info.action_types[0];
   2043     ent_info.entry_action[0].value[0] = sat_gport;
   2044     ent_info.entry_action[0].value[1] = trap_code_qualifier;
   2045     ent_info.entry_action[1].type = fg_info.action_types[1];
   2046     ent_info.entry_action[1].value[0] = 0;
   2047     ent_info.entry_action[1].value[1] = oam_offset;
   2048     ent_info.entry_action[1].value[2] = 0;
   2049     ent_info.entry_action[1].value[3] = 0;
   2050 
   2051     rv = bcm_field_entry_add(unit, 0, sat_fg_id, &ent_info, &sat_fg_entry_id);
   2052     if (rv != BCM_E_NONE)
   2053     {
   2054        printf("Error (%d), in bcm_field_entry_add\n", rv);
   2055        return rv;
   2056     }
   2057     printf("Entry add: id:(0x%x)  Src_ip:(0x%x) tc_val:(%d)\n",sat_fg_entry_id,ent_info.entry_qual[0].value[0],
   2058                                                                             ent_info.entry_action[0].value[0] );
   2059 
   2060     bcm_field_presel_entry_id_info_init(&p_id);
   2061     bcm_field_presel_entry_data_info_init(&p_data);
   2062 
   2063     p_id.presel_id = attach_presel;
   2064     p_id.stage = bcmFieldStageIngressPMF1;
   2065     p_data.entry_valid = TRUE;
   2066     p_data.context_id = sat_field_context_id;
   2067     p_data.nof_qualifiers = 1;
   2068 
   2069     p_data.qual_data[0].qual_type = bcmFieldQualifyForwardingType;
   2070     p_data.qual_data[0].qual_arg = 0;
   2071     p_data.qual_data[0].qual_value = bcmFieldLayerTypeEth;
   2072     p_data.qual_data[0].qual_mask = 0x1F;
   2073 
   2074     rv = bcm_field_presel_set(unit, 0, &p_id, &p_data);
   2075     if (rv != BCM_E_NONE)
   2076     {
   2077        printf("Error (%d), in dnx_field_presel_set \n", rv);
   2078        return rv;
   2079     }
   2080 
   2081     printf("Presel (%d) was configured for stage(iPMF1) context(%d) fwd_layer(Ethernet) \n",
   2082             attach_presel,sat_field_context_id);
   2083 
   2084     return 0;
   2085 }
   2086 
   2087 
   2088 /**
   2089 * \brief
   2090 *  Delete the PMF field group that SAT uses it.
   2091 * \param [in] unit             - Device ID
   2092 * \return
   2093 *   int - Error Type
   2094 * \remark
   2095 *   * None
   2096 * \see
   2097 *   * None
   2098 */
   2099 int ctf_pmf_destroy_jr2(int unit)
   2100 {
   2101     int rv = BCM_E_NONE;
   2102     int ii= 0;
   2103     bcm_field_entry_qual_t entry_qual_info[BCM_FIELD_NUMBER_OF_QUALS_PER_GROUP];
   2104     uint32 attach_presel = 5;
   2105     bcm_field_presel_entry_data_t p_data;
   2106     bcm_field_presel_entry_id_t p_id;
   2107 
   2108     bcm_field_presel_entry_id_info_init(&p_id);
   2109     bcm_field_presel_entry_data_info_init(&p_data);
   2110 
   2111     p_id.presel_id = attach_presel;
   2112     p_id.stage = bcmFieldStageIngressPMF1;
   2113     p_data.entry_valid = FALSE;
   2114     p_data.context_id = 0;
   2115 
   2116     rv = bcm_field_presel_set(unit, 0, &p_id, &p_data);
   2117     if (rv != BCM_E_NONE)
   2118     {
   2119        printf("Error (%d), in dnx_field_presel_set \n", rv);
   2120        return rv;
   2121     }
   2122 
   2123     rv = bcm_field_group_context_detach(unit, sat_fg_id, sat_field_context_id);
   2124     if(rv != BCM_E_NONE)
   2125     {
   2126         printf("Error (%d), in bcm_field_group_context_detach\n", rv);
   2127         return rv;
   2128     }
   2129 
   2130     rv = bcm_field_context_destroy(unit,bcmFieldStageIngressPMF1,sat_field_context_id);
   2131     if (rv != BCM_E_NONE)
   2132     {
   2133         printf("Error (%d), in bcm_field_context_destroy eth\n", rv);
   2134         return rv;
   2135     }
   2136 
   2137     rv = bcm_field_entry_delete(unit, sat_fg_id, &entry_qual_info, sat_fg_entry_id);
   2138     if (rv != BCM_E_NONE)
   2139     {
   2140         printf("Error (%d), in bcm_field_group_delete\n", rv);
   2141         return rv;
   2142     }
   2143   
   2144     rv = bcm_field_group_delete(unit, sat_fg_id);
   2145     if (rv != BCM_E_NONE)
   2146     {
   2147         printf("Error (%d), in bcm_field_group_delete\n", rv);
   2148         return rv;
   2149     }
   2150     return 0;
   2151 
   2152 }
   2153 
   2154 int sat_cleanup(int unit) {
   2155 
   2156     int rv = BCM_E_NONE;
   2157 
   2158     /* clean up CTF */
   2159     rv = ctf_setup_cleanup(unit);
   2160     if (BCM_E_NONE != rv) {
   2161         printf("Error in ctf_setup_cleanup\n");
   2162         return rv;
   2163     }
   2164 
   2165     /* clean up GTF */
   2166     rv = sat_gtf_cleanup(unit, gtf_id);
   2167     if (BCM_E_NONE != rv) {
   2168         printf("Failed($rv) in sat_gtf_cleanup\n");
   2169         return rv;
   2170     }
   2171 
   2172 
   2173     return rv;
   2174 
   2175 }
   2176