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

flexport_th3.c (83996B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * The flexport test checks the flexport and TDM functionalities by streaming
      8  * L2UC packets on all ports at maximum rate. All ports are configured in
      9  * MAC or PHY loopback mode and each port is associated with one VLAN. The test
     10  * calculates the number of packets needed to saturate each port and send the
     11  * L2UC packets with the port's VLAN tag from the CPU to each port initially.
     12  * Then the packets DLF and flood to the VLAN which contains one port. Port
     13  * bridging is enabled to allow the DLF packet to go back to its ingress port.
     14  * Thus, the packets keep looping back within each port indefinitely. The
     15  * flexport functionality is checked by flexing one or more port macros to
     16  * a different mode/speed/encapsulation. The port macros and mode/speed/
     17  * encapsulation can be specify either by command line or through a series of
     18  * flex_tpl.txt &config_dict.txt files. Once the traffic reaches steady state, rate and packet
     19  * integrity are checked on the flex ports. Then, traffic will be stopped on the
     20  * flex ports before calling the BCM FlexPort API to perform the flexport
     21  * operation. Traffic on the non-flex ports will not be interrupted. The rate
     22  * calculation is done by dividing the transmit packet count changes and
     23  * transmit byte count changes over a programmable interval. The rates are
     24  * checked against expected rates based on port configuration and
     25  * oversubscription ratio. Packet integrity check is achieved by disabling the
     26  * VLAN so the packets go back to the CPU as unknown VLAN. The packets are
     27  * compared against expected packets to ensure packet integrity.
     28  */
     29 
     30 #include <appl/diag/system.h>
     31 #include <shared/alloc.h>
     32 #include <shared/bsl.h>
     33 
     34 #include <soc/cm.h>
     35 #include <soc/dma.h>
     36 #include <soc/drv.h>
     37 #include <soc/dcb.h>
     38 #include <soc/cmicm.h>
     39 #include <soc/cmic.h>
     40 
     41 #include <sal/types.h>
     42 #include <appl/diag/parse.h>
     43 #include <bcm/port.h>
     44 #include <bcm/vlan.h>
     45 #include <bcm/link.h>
     46 /*#include <soc/portmod/portmod.h>*/
     47 /*#include <stdlib.h>*/
     48 #include <sal/core/libc.h>
     49 
     50 #if defined(BCM_TOMAHAWK3_SUPPORT)
     51 
     52 #include <soc/init/tomahawk3_flexport_defines.h>
     53 #include <soc/tomahawk3.h>
     54 
     55 #include "testlist.h"
     56 #include "gen_pkt.h"
     57 #include "streaming_lib.h"
     58 
     59 #if defined(BCM_ESW_SUPPORT) && \
     60            (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \
     61            !defined(NO_SAL_APPL) && (!defined(__KERNEL__))
     62 
     63 typedef struct flex_entry {
     64     uint32 pm_num;
     65     uint32 subport;
     66     uint32 speed;
     67     uint32 num_lanes;
     68     uint32 fec;
     69 } flex_entry_t;
     70 
     71 typedef struct flexport_s {
     72     pbmp_t vlan_pbmp;
     73     pbmp_t port_down_pbmp;
     74     pbmp_t port_up_pbmp;
     75     uint32 pkt_size_param;
     76     uint32 flood_pkt_cnt_param;
     77     uint32 rate_calc_interval_param;
     78     uint32 rate_tolerance_lr_param;
     79     uint32 rate_tolerance_ov_param;
     80     uint32 check_packet_integrity_param;
     81     uint32 emulation_param;
     82     uint32 loopback_mode_param;
     83     uint32 no_speed_change_param;
     84     uint32 init_tsc_shim;
     85     char *tsc_param[65];
     86     uint32 num_del;
     87     uint32 num_add;
     88     bcm_port_resource_t del_resource[SOC_MAX_NUM_PORTS];
     89     bcm_port_resource_t add_resource[SOC_MAX_NUM_PORTS];
     90     int linkscan_enable;
     91     uint32 counter_flags;
     92     int counter_interval;
     93     pbmp_t counter_pbm;
     94     uint32 bad_input;
     95     uint32 test_fail;
     96     uint32 test_fail_iter[20];
     97     uint32 pkt_seed;
     98     int sockfd;
     99     int clear_new_port_counts;
    100     int fec_type_param;
    101     int input_mode_param;
    102     int flex_id_start_param;
    103     int flex_id_end_param;
    104     int flex_iter;
    105     /* TH3 fields */
    106     int num_flex_entries;
    107     flex_entry_t flex_entry[256];
    108     int per_port_pkt_size[SOC_MAX_NUM_PORTS];
    109     int per_port_pkt_cnt[SOC_MAX_NUM_PORTS];
    110     char *tpl_section;
    111     int cut_thru_en;
    112     int sku;
    113     int rand_pm_en;
    114     int rand_pm_shift;
    115 } flexport_t;
    116 
    117 typedef struct rate_calc_s {
    118     uint32 ovs_ratio_x1000[SOC_MAX_NUM_PIPES];
    119     uint32 rand_pkt_sizes[SOC_MAX_NUM_PORTS][TARGET_CELL_COUNT];
    120     uint64 stime[SOC_MAX_NUM_PORTS];
    121     uint64 exp_rate[SOC_MAX_NUM_PORTS];
    122     uint64 exp_max_rate[SOC_MAX_NUM_PORTS];
    123     uint64 tpkt_start[SOC_MAX_NUM_PORTS];
    124     uint64 tbyt_start[SOC_MAX_NUM_PORTS];
    125 } rate_calc_t;
    126 
    127 typedef enum flex_port_phy_fec_e {
    128     FLX_FEC_DEFAULT_REQUEST = -1,
    129     FLX_FEC_INVALID,
    130     FLX_FEC_NONE,
    131     FLX_FEC_BASE_R,
    132     FLX_FEC_RS_FEC,
    133     FLX_FEC_RS_544,
    134     FLX_FEC_RS_272,
    135     FLX_FEC_RS_206,
    136     FLX_FEC_RS_108,
    137     FLX_FEC_RS_545,
    138     FLX_FEC_RS_304,
    139     FLX_FEC_RS_544_2XN,
    140     FLX_FEC_RS_272_2XN,
    141     FLX_FEC_COUNT
    142 } flex_port_phy_fec_t;
    143 
    144 
    145 static flexport_t *flexport_parray[SOC_MAX_NUM_DEVICES];
    146 static rate_calc_t *rate_calc_parray[SOC_MAX_NUM_DEVICES];
    147 
    148 static const char flexport_test_usage[] =
    149 #ifdef COMPILER_STRING_CONST_LIMIT
    150     "\nDocumentation too long to be displayed with -pedantic compiler\n";
    151 #else
    152     "\nFlexPort test usage:\n"
    153     " \n"
    154     "PktSize:      Packet size in bytes. Set to 1 for random packet sizes.\n"
    155     "              Set to 0 (default) for worst case packet sizes on all ports\n"
    156     "              (145B for ENET, 76B for HG2).\n"
    157     "FloodCnt:     Number of packets in each swirl between.\n"
    158     "              Set to 0 (default) for a lossless swirl at full rate.\n"
    159     "RateCalcInt:  Interval in seconds over which rate is to be calculated.\n"
    160     "TolLr:        Rate tolerance percentage for line rate ports.\n"
    161     "              (1% by default)\n"
    162     "TolOv:        Rate tolerance percentage for oversubscribed ports.\n"
    163     "              (3% by default).\n"
    164     "ChkPktInteg:  Set to 0 to disable packet integrity checks.\n"
    165     "              Set to 1 to enable (default).\n"
    166     "Emulation:    Set to 1 to send TSC clock commands for emulation.\n"
    167     "              Set to 0 to disable (default).\n"
    168     "ServerName:   Name or IP address of the TSC clock server.\n"
    169     "              Required for emulation\n."
    170     "SocketNum:    Socket number of the TSC clock server.\n"
    171     "              Required for emulation\n."
    172     "MaxNumCells:  Maximum number of cells for random packet sizes.\n"
    173     "              Set to 0 for random cell sizes. (default is 4)\n"
    174     "LoopbackMode: Loopback mode. Set to 1 for MAC loopback, 2 for PHY loopback.\n"
    175     "              (default is MAC loopback)\n"
    176     "Tsc<num>:     TSC to be flexed and port mode to flex to, e.g. Tsc5=4x10G\n"
    177     "              The supported mode/speed in Ethernet encapsulation are:\n"
    178     "NoSpeedChg:   NOT used in TH3; Do not call the bcm_port_speed change. (default)\n"
    179     "FecType:      Fec Type \n"
    180     "InputMode:    Specifies how user enters flex info \n"
    181     "              0: input directly from command line; flex info passed per port\n"
    182     "              1: input using config_dict.txt in command line; flex info passed per PM/CD\n"
    183     "              2: input using FLEX_ID in flex_tpl.txt file\n"
    184     "              default is 2\n"
    185     "TplSec:       TPL Section\n"
    186     "FlexIdStart:  Initial FLEX_ID in TPL Section\n"
    187     "FlexIdEnd:    Final   FLEX_ID in TPL Section\n"
    188     "CutThruEn:    Enable Cut Thru while flexing\n"
    189     "Sku:          Chip SKU under test\n"
    190     "RandPmEn:     PM Shift Random Enable\n"
    191     ;
    192 #endif
    193 
    194 /*
    195  * Function:
    196  *      flexport_parse_test_params
    197  * Purpose:
    198  *      Parse CLI parameters, create test structure and flag bad inputs.
    199  * Parameters:
    200  *      unit - StrataSwitch Unit #.
    201  *      a - Pointer to arguments
    202  *
    203  * Returns:
    204  *     Nothing
    205  * Notes:
    206  *      flexport_p->bad_input set from here - tells test to crash out in case
    207  *      CLI input combination is invalid.
    208  */
    209 
    210 static void
    211 flexport_parse_test_params(int unit, args_t *a)
    212 {
    213     int i;
    214     parse_table_t parse_table;
    215     flexport_t *flexport_p = flexport_parray[unit];
    216 
    217     flexport_p->bad_input = 0;
    218 
    219     flexport_p->pkt_size_param = 0;
    220     flexport_p->flood_pkt_cnt_param = 0;
    221     flexport_p->rate_calc_interval_param = 5;
    222     flexport_p->rate_tolerance_lr_param = 2;
    223     flexport_p->rate_tolerance_ov_param = 2;
    224     flexport_p->check_packet_integrity_param = 1;
    225     flexport_p->emulation_param = 0;
    226     flexport_p->loopback_mode_param = BCM_PORT_LOOPBACK_PHY;
    227     flexport_p->no_speed_change_param = 1;
    228     flexport_p->init_tsc_shim = 0;
    229     flexport_p->clear_new_port_counts = 0;
    230     flexport_p->fec_type_param = -1;
    231     flexport_p->input_mode_param = 3;
    232     flexport_p->flex_id_start_param = 0;
    233     flexport_p->flex_id_end_param = 0;
    234     flexport_p->cut_thru_en = 1;
    235     flexport_p->sku = 56980;
    236     flexport_p->rand_pm_en = 0;
    237     flexport_p->rand_pm_shift = 0;
    238 
    239     /*Parse CLI opts */
    240 
    241     parse_table_init(unit, &parse_table);
    242     parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0,
    243                     &flexport_p->pkt_size_param, NULL);
    244     parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0,
    245                     &flexport_p->flood_pkt_cnt_param, NULL);
    246     parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0,
    247                     &flexport_p->rate_calc_interval_param, NULL);
    248     parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0,
    249                     &flexport_p->rate_tolerance_lr_param, NULL);
    250     parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0,
    251                     &flexport_p->rate_tolerance_ov_param, NULL);
    252     parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0,
    253                     &flexport_p->check_packet_integrity_param, NULL);
    254     parse_table_add(&parse_table, "Emulation", PQ_INT|PQ_DFL, 0,
    255                     &flexport_p->emulation_param, NULL);
    256     parse_table_add(&parse_table, "LoopbackMode", PQ_INT|PQ_DFL, 0,
    257                     &flexport_p->loopback_mode_param, NULL);
    258     parse_table_add(&parse_table, "Tsc0", PQ_STRING|PQ_DFL, 0,
    259                     &flexport_p->tsc_param[0], NULL);
    260     parse_table_add(&parse_table, "Tsc1", PQ_STRING|PQ_DFL, 0,
    261                     &flexport_p->tsc_param[1], NULL);
    262     parse_table_add(&parse_table, "Tsc2", PQ_STRING|PQ_DFL, 0,
    263                     &flexport_p->tsc_param[2], NULL);
    264     parse_table_add(&parse_table, "Tsc3", PQ_STRING|PQ_DFL, 0,
    265                     &flexport_p->tsc_param[3], NULL);
    266     parse_table_add(&parse_table, "Tsc4", PQ_STRING|PQ_DFL, 0,
    267                     &flexport_p->tsc_param[4], NULL);
    268     parse_table_add(&parse_table, "Tsc5", PQ_STRING|PQ_DFL, 0,
    269                     &flexport_p->tsc_param[5], NULL);
    270     parse_table_add(&parse_table, "Tsc6", PQ_STRING|PQ_DFL, 0,
    271                     &flexport_p->tsc_param[6], NULL);
    272     parse_table_add(&parse_table, "Tsc7", PQ_STRING|PQ_DFL, 0,
    273                     &flexport_p->tsc_param[7], NULL);
    274     parse_table_add(&parse_table, "Tsc8", PQ_STRING|PQ_DFL, 0,
    275                     &flexport_p->tsc_param[8], NULL);
    276     parse_table_add(&parse_table, "Tsc9", PQ_STRING|PQ_DFL, 0,
    277                     &flexport_p->tsc_param[9], NULL);
    278     parse_table_add(&parse_table, "Tsc10", PQ_STRING|PQ_DFL, 0,
    279                     &flexport_p->tsc_param[10], NULL);
    280     parse_table_add(&parse_table, "Tsc11", PQ_STRING|PQ_DFL, 0,
    281                     &flexport_p->tsc_param[11], NULL);
    282     parse_table_add(&parse_table, "Tsc12", PQ_STRING|PQ_DFL, 0,
    283                     &flexport_p->tsc_param[12], NULL);
    284     parse_table_add(&parse_table, "Tsc13", PQ_STRING|PQ_DFL, 0,
    285                     &flexport_p->tsc_param[13], NULL);
    286     parse_table_add(&parse_table, "Tsc14", PQ_STRING|PQ_DFL, 0,
    287                     &flexport_p->tsc_param[14], NULL);
    288     parse_table_add(&parse_table, "Tsc15", PQ_STRING|PQ_DFL, 0,
    289                     &flexport_p->tsc_param[15], NULL);
    290     parse_table_add(&parse_table, "Tsc16", PQ_STRING|PQ_DFL, 0,
    291                     &flexport_p->tsc_param[16], NULL);
    292     parse_table_add(&parse_table, "Tsc17", PQ_STRING|PQ_DFL, 0,
    293                     &flexport_p->tsc_param[17], NULL);
    294     parse_table_add(&parse_table, "Tsc18", PQ_STRING|PQ_DFL, 0,
    295                     &flexport_p->tsc_param[18], NULL);
    296     parse_table_add(&parse_table, "Tsc19", PQ_STRING|PQ_DFL, 0,
    297                     &flexport_p->tsc_param[19], NULL);
    298     parse_table_add(&parse_table, "Tsc20", PQ_STRING|PQ_DFL, 0,
    299                     &flexport_p->tsc_param[20], NULL);
    300     parse_table_add(&parse_table, "Tsc21", PQ_STRING|PQ_DFL, 0,
    301                     &flexport_p->tsc_param[21], NULL);
    302     parse_table_add(&parse_table, "Tsc22", PQ_STRING|PQ_DFL, 0,
    303                     &flexport_p->tsc_param[22], NULL);
    304     parse_table_add(&parse_table, "Tsc23", PQ_STRING|PQ_DFL, 0,
    305                     &flexport_p->tsc_param[23], NULL);
    306     parse_table_add(&parse_table, "Tsc24", PQ_STRING|PQ_DFL, 0,
    307                     &flexport_p->tsc_param[24], NULL);
    308     parse_table_add(&parse_table, "Tsc25", PQ_STRING|PQ_DFL, 0,
    309                     &flexport_p->tsc_param[25], NULL);
    310     parse_table_add(&parse_table, "Tsc26", PQ_STRING|PQ_DFL, 0,
    311                     &flexport_p->tsc_param[26], NULL);
    312     parse_table_add(&parse_table, "Tsc27", PQ_STRING|PQ_DFL, 0,
    313                     &flexport_p->tsc_param[27], NULL);
    314     parse_table_add(&parse_table, "Tsc28", PQ_STRING|PQ_DFL, 0,
    315                     &flexport_p->tsc_param[28], NULL);
    316     parse_table_add(&parse_table, "Tsc29", PQ_STRING|PQ_DFL, 0,
    317                     &flexport_p->tsc_param[29], NULL);
    318     parse_table_add(&parse_table, "Tsc30", PQ_STRING|PQ_DFL, 0,
    319                     &flexport_p->tsc_param[30], NULL);
    320     parse_table_add(&parse_table, "Tsc31", PQ_STRING|PQ_DFL, 0,
    321                     &flexport_p->tsc_param[31], NULL);
    322     parse_table_add(&parse_table, "Tsc32", PQ_STRING|PQ_DFL, 0,
    323                     &flexport_p->tsc_param[32], NULL);
    324     parse_table_add(&parse_table, "Tsc33", PQ_STRING|PQ_DFL, 0,
    325                     &flexport_p->tsc_param[33], NULL);
    326     parse_table_add(&parse_table, "Tsc34", PQ_STRING|PQ_DFL, 0,
    327                     &flexport_p->tsc_param[34], NULL);
    328     parse_table_add(&parse_table, "Tsc35", PQ_STRING|PQ_DFL, 0,
    329                     &flexport_p->tsc_param[35], NULL);
    330     parse_table_add(&parse_table, "Tsc36", PQ_STRING|PQ_DFL, 0,
    331                     &flexport_p->tsc_param[36], NULL);
    332     parse_table_add(&parse_table, "Tsc37", PQ_STRING|PQ_DFL, 0,
    333                     &flexport_p->tsc_param[37], NULL);
    334     parse_table_add(&parse_table, "Tsc38", PQ_STRING|PQ_DFL, 0,
    335                     &flexport_p->tsc_param[38], NULL);
    336     parse_table_add(&parse_table, "Tsc39", PQ_STRING|PQ_DFL, 0,
    337                     &flexport_p->tsc_param[39], NULL);
    338     parse_table_add(&parse_table, "Tsc40", PQ_STRING|PQ_DFL, 0,
    339                     &flexport_p->tsc_param[40], NULL);
    340     parse_table_add(&parse_table, "Tsc41", PQ_STRING|PQ_DFL, 0,
    341                     &flexport_p->tsc_param[41], NULL);
    342     parse_table_add(&parse_table, "Tsc42", PQ_STRING|PQ_DFL, 0,
    343                     &flexport_p->tsc_param[42], NULL);
    344     parse_table_add(&parse_table, "Tsc43", PQ_STRING|PQ_DFL, 0,
    345                     &flexport_p->tsc_param[43], NULL);
    346     parse_table_add(&parse_table, "Tsc44", PQ_STRING|PQ_DFL, 0,
    347                     &flexport_p->tsc_param[44], NULL);
    348     parse_table_add(&parse_table, "Tsc45", PQ_STRING|PQ_DFL, 0,
    349                     &flexport_p->tsc_param[45], NULL);
    350     parse_table_add(&parse_table, "Tsc46", PQ_STRING|PQ_DFL, 0,
    351                     &flexport_p->tsc_param[46], NULL);
    352     parse_table_add(&parse_table, "Tsc47", PQ_STRING|PQ_DFL, 0,
    353                     &flexport_p->tsc_param[47], NULL);
    354     parse_table_add(&parse_table, "Tsc48", PQ_STRING|PQ_DFL, 0,
    355                     &flexport_p->tsc_param[48], NULL);
    356     parse_table_add(&parse_table, "Tsc49", PQ_STRING|PQ_DFL, 0,
    357                     &flexport_p->tsc_param[49], NULL);
    358     parse_table_add(&parse_table, "Tsc50", PQ_STRING|PQ_DFL, 0,
    359                     &flexport_p->tsc_param[50], NULL);
    360     parse_table_add(&parse_table, "Tsc51", PQ_STRING|PQ_DFL, 0,
    361                     &flexport_p->tsc_param[51], NULL);
    362     parse_table_add(&parse_table, "Tsc52", PQ_STRING|PQ_DFL, 0,
    363                     &flexport_p->tsc_param[52], NULL);
    364     parse_table_add(&parse_table, "Tsc53", PQ_STRING|PQ_DFL, 0,
    365                     &flexport_p->tsc_param[53], NULL);
    366     parse_table_add(&parse_table, "Tsc54", PQ_STRING|PQ_DFL, 0,
    367                     &flexport_p->tsc_param[54], NULL);
    368     parse_table_add(&parse_table, "Tsc55", PQ_STRING|PQ_DFL, 0,
    369                     &flexport_p->tsc_param[55], NULL);
    370     parse_table_add(&parse_table, "Tsc56", PQ_STRING|PQ_DFL, 0,
    371                     &flexport_p->tsc_param[56], NULL);
    372     parse_table_add(&parse_table, "Tsc57", PQ_STRING|PQ_DFL, 0,
    373                     &flexport_p->tsc_param[57], NULL);
    374     parse_table_add(&parse_table, "Tsc58", PQ_STRING|PQ_DFL, 0,
    375                     &flexport_p->tsc_param[58], NULL);
    376     parse_table_add(&parse_table, "Tsc59", PQ_STRING|PQ_DFL, 0,
    377                     &flexport_p->tsc_param[59], NULL);
    378     parse_table_add(&parse_table, "Tsc60", PQ_STRING|PQ_DFL, 0,
    379                     &flexport_p->tsc_param[60], NULL);
    380     parse_table_add(&parse_table, "Tsc61", PQ_STRING|PQ_DFL, 0,
    381                     &flexport_p->tsc_param[61], NULL);
    382     parse_table_add(&parse_table, "Tsc62", PQ_STRING|PQ_DFL, 0,
    383                     &flexport_p->tsc_param[62], NULL);
    384     parse_table_add(&parse_table, "Tsc63", PQ_STRING|PQ_DFL, 0,
    385                     &flexport_p->tsc_param[63], NULL);
    386     parse_table_add(&parse_table, "NoSpeedChg", PQ_INT|PQ_DFL, 0,
    387                     &flexport_p->no_speed_change_param, NULL);
    388     parse_table_add(&parse_table, "InitTscShim", PQ_INT|PQ_DFL, 0,
    389                     &flexport_p->init_tsc_shim, NULL);
    390     parse_table_add(&parse_table, "ClrNewPortCounts", PQ_INT|PQ_DFL, 0,
    391                     &flexport_p->clear_new_port_counts, NULL);
    392     parse_table_add(&parse_table, "FecType", PQ_INT|PQ_DFL, 0,
    393                     &flexport_p->fec_type_param, NULL);
    394     parse_table_add(&parse_table, "InputMode", PQ_INT|PQ_DFL, 0,
    395                     &flexport_p->input_mode_param, NULL);
    396     parse_table_add(&parse_table, "FlexIdStart", PQ_INT|PQ_DFL, 0,
    397                     &flexport_p->flex_id_start_param, NULL);
    398     parse_table_add(&parse_table, "FlexIdEnd", PQ_INT|PQ_DFL, 0,
    399                     &flexport_p->flex_id_end_param, NULL);
    400     parse_table_add(&parse_table, "TplSec", PQ_STRING|PQ_DFL, 0,
    401                     &flexport_p->tpl_section, NULL);
    402     parse_table_add(&parse_table, "CutThruEn", PQ_INT|PQ_DFL, 0,
    403                     &flexport_p->cut_thru_en, NULL);
    404     parse_table_add(&parse_table, "Sku", PQ_INT|PQ_DFL, 0,
    405                     &flexport_p->sku, NULL);
    406     parse_table_add(&parse_table, "RandPmEn", PQ_INT|PQ_DFL, 0,
    407                     &flexport_p->rand_pm_en, NULL);
    408 
    409     for (i = 0; i < 64; i++) {
    410         char flx_str[20]="flx";
    411         char flx_num_str[10];
    412 
    413         /*flx_str = (char *) sal_alloc(sizeof(char) * 20, "flx_str");
    414         sal_strcpy(flx_str)*/
    415 
    416         /*cli_out("DB01 i=%0d flx_str= %s\n", i, flx_str);*/
    417         sal_itoa(flx_num_str, i, 10, 0, 0);
    418         /*cli_out("DB02 i=%0d flx_num_str= %s\n", i, flx_num_str);*/
    419         strcat(flx_str, flx_num_str);
    420         /*cli_out("DB03 i=%0d flx_str= %s\n", i, flx_str);*/
    421         parse_table_add(&parse_table, flx_str, PQ_STRING|PQ_DFL, 0,
    422                     &flexport_p->tsc_param[i], NULL);
    423         if (flexport_p->tsc_param[i] != NULL) {
    424             cli_out("\n DBG0 i=%0d  = %s", i, flexport_p->tsc_param[i]);
    425         }
    426     }
    427 
    428     if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) {
    429         cli_out("%s", flexport_test_usage);
    430         test_error(unit, "\n*ERROR PARSING ARGS\n");
    431     }
    432 
    433     flexport_p->flex_iter = 0;
    434     flexport_p->num_flex_entries = 0;
    435 
    436     sal_srand( (int)sal_time() );
    437     flexport_p->rand_pm_shift = sal_rand() % _TH3_NUM_OF_TSCBH;
    438 
    439     cli_out("\n ------------- PRINTING TEST PARAMS ------------------");
    440     cli_out("\nPktSize      = %0d", flexport_p->pkt_size_param);
    441     cli_out("\nRateCalcInt  = %0d ms", flexport_p->rate_calc_interval_param * 100);
    442     cli_out("\nFloodCnt     = %0d", flexport_p->flood_pkt_cnt_param);
    443     cli_out("\nTolLr        = %0d", flexport_p->rate_tolerance_lr_param);
    444     cli_out("\nTolOv        = %0d", flexport_p->rate_tolerance_ov_param);
    445     cli_out("\nChkPktInteg  = %0d", flexport_p->check_packet_integrity_param);
    446     cli_out("\nEmulation    = %0d", flexport_p->emulation_param);
    447     cli_out("\nLoopbackMode = %0d", flexport_p->loopback_mode_param);
    448     cli_out("\nClrNewPortCounts   = %0d",  flexport_p->clear_new_port_counts);
    449     cli_out("\nFecType      = %0d",  flexport_p->fec_type_param);
    450     cli_out("\nInputMode    = %0d",  flexport_p->input_mode_param);
    451     cli_out("\nFlexIdStart  = %0d",  flexport_p->flex_id_start_param);
    452     cli_out("\nFlexIdEnd    = %0d",  flexport_p->flex_id_end_param);
    453     cli_out("\nCutThruEn    = %0d",  flexport_p->cut_thru_en);
    454     cli_out("\nSku          = %0d",  flexport_p->sku);
    455     cli_out("\nRandPmEn     = %0d",  flexport_p->rand_pm_en);
    456     if (flexport_p->rand_pm_en == 1) {
    457     cli_out("\nRandPM Shift = %0d",  flexport_p->rand_pm_shift);
    458     }
    459 
    460     if (flexport_p->tpl_section != NULL) {
    461         cli_out("\nTplSec       = %s",  flexport_p->tpl_section);
    462     }
    463 
    464     for (i = 0; i < 65; i++) {
    465        if (flexport_p->tsc_param[i] != NULL) {
    466            cli_out("\nTsc%2d       = %s", i, flexport_p->tsc_param[i]);
    467        }
    468     }
    469 
    470     cli_out("\nNoSpeeedChg   = %0d", flexport_p->no_speed_change_param);
    471     cli_out("\nInitTscShim   = %0d", flexport_p->init_tsc_shim);
    472     cli_out("\n -----------------------------------------------------");
    473 
    474     if (flexport_p->pkt_size_param == 0) {
    475       if(SOC_IS_TRIDENT3X(unit))
    476         cli_out
    477             ("\nUsing worst case packet sizes - 64B for Ethernet and HG2");
    478       else
    479         cli_out
    480             ("\nUsing worst case packet sizes - 145B for Ethernet and "
    481              "76B for HG2");
    482     } else if (flexport_p->pkt_size_param == 1) {
    483         cli_out("\nUsing random packet sizes");
    484     } else if (flexport_p->pkt_size_param < MIN_PKT_SIZE) {
    485         test_error(unit,"*ERROR: Packet size cannot be lower than %0dB\n",
    486                 MIN_PKT_SIZE);
    487         flexport_p->bad_input = 1;
    488     } else if (flexport_p->pkt_size_param > MTU) {
    489         test_error(unit,"*ERROR: Packet size higher than %0dB (Device MTU)\n",
    490                 MTU);
    491         flexport_p->bad_input = 1;
    492     }
    493 
    494     if (flexport_p->flood_pkt_cnt_param == 0) {
    495         cli_out("\nFloodCnt=0, automatically calculate number of packets to "
    496                 "flood each port");
    497     }
    498 
    499     if ((flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_MAC) &&
    500         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY) &&
    501         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY_REMOTE) &&
    502         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_NONE)) {
    503         /*
    504          *   0 - no loopback; only to be used with chip external loopbacks.
    505          *   1 - MAC outer loopback.
    506          *   2 - PCS local loopback, close to PMD boundary.
    507          *   3 - PMD local loopback, close to AFE.
    508          */
    509         test_error(unit,"*ERROR: Loopback mode must be either 0, 1, 2 or 3\n");
    510         flexport_p->bad_input = 1;
    511     }
    512 
    513     if ((flexport_p->input_mode_param < 0) ||
    514         (flexport_p->input_mode_param > 3) ) {
    515         test_error(unit,"*ERROR: Please specify a valid InputMode; Current one is InputMode=%0d\n",
    516                    flexport_p->input_mode_param);
    517         flexport_p->bad_input = 1;
    518     }
    519 
    520     flexport_p->test_fail = 0;
    521     for (i = 0; i < 20; i++) {
    522         flexport_p->test_fail_iter[i] = 0;
    523     }
    524 }
    525 
    526 static void get_mac_da(int unit,
    527     int port,
    528     bcm_mac_t mac_addr)
    529 {
    530     int i;
    531     bcm_mac_t l_mac_addr = {0x12, 0x34, 0x56, 0x78, 0x9a, 0x00};
    532 
    533     for (i = 0; i < 6; i++) {
    534         mac_addr[i] = l_mac_addr[i];
    535     }
    536     mac_addr[5] = port;
    537 }
    538 
    539 static void get_mac_sa(int unit,
    540     int port,
    541     bcm_mac_t mac_addr)
    542 {
    543     int i;
    544     bcm_mac_t l_mac_addr = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54};
    545 
    546     for (i = 0; i < 6; i++) {
    547         mac_addr[i] = l_mac_addr[i];
    548     }
    549 }
    550 
    551 static uint32 get_vlan_id(
    552     int unit,
    553     int port)
    554 {
    555     return (0x0a00 + port);
    556 }
    557 
    558 
    559 
    560 static void
    561 get_per_pipe_log_port_range(int unit, int pport,
    562               int *log_start, int *log_end, int *pipe) {
    563 
    564     if(SOC_IS_TOMAHAWK2(unit)) {
    565         *pipe = (pport - 1) / 64;
    566         *log_start = (*pipe) * 34;
    567         *log_end = (*pipe) * 34 + 34 - 1;
    568     } else if (SOC_IS_TOMAHAWK3(unit)) {
    569         /* Only front panel ports */
    570         *pipe = (pport - 1) / 32;
    571         *log_start = ((*pipe) == 0) ? 1 : (*pipe) * 20;
    572         *log_end = ((*pipe) == 0) ? 18 : 17 + ((*pipe) * 20);
    573     } else {
    574         *pipe = 0;
    575         *log_start = 0;
    576         *log_end = SOC_MAX_NUM_PORTS;
    577     }
    578 }
    579 
    580 
    581 /* Get BST counters
    582  * temp API until main bcm API is working
    583  */
    584 static int th3_get_bst_total_queue(
    585     int unit,
    586     int port,
    587     int queue,
    588     int *count)
    589 {
    590     uint32 pipe, itm;
    591     uint32 entry[SOC_MAX_MEM_WORDS];
    592     int index, is_mc, copyno;
    593     soc_mem_t mem;
    594 
    595     pipe = port / 20;
    596     itm = SOC_INFO(unit).ipipe_itm_map[pipe];
    597     itm -= 1;
    598     /*itm = ((pipe < 2) || (pipe > 5)) ? 0 : 1;*/
    599     /*for (i = 0; i < 8; i++) {
    600         cli_out("th3_get_bst_total_queue ipipe_itm_map[%0d]=%0d\n",
    601              i, SOC_INFO(unit).ipipe_itm_map[i]);
    602     }*/
    603 
    604     is_mc = 0;
    605     soc_th3_chip_queue_num_get(unit,
    606         port, queue, is_mc, &index);
    607 
    608     mem = (itm == 0) ?
    609         MMU_THDO_BST_TOTAL_QUEUE_ITM0m :
    610         MMU_THDO_BST_TOTAL_QUEUE_ITM1m;
    611 
    612     copyno = -1;
    613     sal_memset(&entry, 0, sizeof(entry));
    614 
    615     /*Read only from the 1st memory in list*/
    616     SOC_IF_ERROR_RETURN(soc_mem_read
    617         (unit, mem, copyno, index, entry));
    618 
    619     *count = entry[0];
    620 
    621     cli_out("th3_get_bst_total_queue port=%0d itm=%0d queue=%0d index=%0d BST_TOTAL_QUEUE=%0d\n",
    622              port, itm, queue, index, *count);
    623 
    624     return SOC_E_NONE;
    625 }
    626 
    627 
    628 static bcm_error_t th3_check_cdport_intr_status(
    629     int unit,
    630     int port)
    631 {
    632     bcm_error_t rv = BCM_E_NONE;
    633     /*uint32 rval32;*/
    634     uint64 rval64;
    635     int phy_port;
    636     /*flexport_t *flexport_p = flexport_parray[unit];*/
    637     int fail = 0;
    638     soc_info_t *si = &SOC_INFO(unit);
    639 
    640     phy_port = si->port_l2p_mapping[port];
    641 
    642     /*
    643     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    644           CDPORT_INTR_STATUSr, phy_port, 0, &rval32));
    645     if (rval32 != 0) {
    646         cli_out("*ERROR th3_check_cdport_intr_status() port=%0d phy_port=%0d CDPORT_INTR_STATUSr=0x%x and !=0\n",
    647                 port, phy_port, rval32);
    648         fail = 1;
    649     }
    650     */
    651 
    652     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit,
    653           CDPORT_TSC_INTR_STATUSr, phy_port, 0, &rval64));
    654     if (!COMPILER_64_IS_ZERO(rval64)) {
    655         cli_out("*ERROR th3_check_cdport_intr_status() port=%0d phy_port=%0d CDPORT_TSC_INTR_STATUSr= HI=0x%x LO=0x%x and !=0\n",
    656                 port, phy_port, COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
    657         fail = 1;
    658     } else {
    659     /*  cli_out("th3_check_cdport_intr_status() port=%0d phy_port=%0d CDPORT_TSC_INTR_STATUSr= HI=0x%x LO=0x%x\n",
    660      *      port, phy_port, COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
    661      */
    662     }
    663 
    664     if (fail == 1) {
    665         /*flexport_p->test_fail = 1;
    666         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;*/
    667     }
    668 
    669     return rv;
    670 }
    671 
    672 
    673 /* NEW FRAMEWORK */
    674 static bcm_error_t flexport_pre_traffic_checks(
    675     int unit,
    676     pbmp_t pbmp)
    677 {
    678     bcm_error_t rv = BCM_E_NONE;
    679     int port;
    680 
    681     if (BCM_PBMP_NOT_NULL(pbmp)) {
    682         PBMP_ITER(pbmp, port) {
    683             if ((port < SOC_MAX_NUM_PORTS) &&
    684                 (!IS_MANAGEMENT_PORT(unit,port))) {
    685                 th3_check_cdport_intr_status(unit, port);
    686             }
    687         }
    688     }
    689 
    690     return rv;
    691 }
    692 
    693 
    694 /*
    695  * Function:
    696  *      flexport_call_bcm_api
    697  * Purpose:
    698  *      Call the bcm_port_resource_multi_set API
    699  * Parameters:
    700  *      unit - StrataSwitch Unit #.
    701  *
    702  * Returns:
    703  *     SOC_E_XXXX
    704  */
    705 
    706 static bcm_error_t
    707 flexport_call_bcm_api(int unit)
    708 {
    709     flexport_t *flexport_p = flexport_parray[unit];
    710     int i;
    711     bcm_port_t lport;
    712     uint32 nports;
    713     bcm_port_resource_t *resource;
    714     bcm_error_t rv;
    715 
    716     nports = flexport_p->num_del + flexport_p->num_add;
    717     resource = (bcm_port_resource_t *) sal_alloc(nports *
    718                                                  sizeof(bcm_port_resource_t),
    719                                                  "flexport_resource_array");
    720     sal_memset(resource, 0, sizeof(bcm_port_resource_t));
    721 
    722     for (i = 0; i < flexport_p->num_del; i ++) {
    723         resource[i] = flexport_p->del_resource[i];
    724     }
    725     for (i = 0; i < flexport_p->num_add; i ++) {
    726         resource[flexport_p->num_del + i] = flexport_p->add_resource[i];
    727     }
    728 
    729     PBMP_ITER(flexport_p->port_down_pbmp, lport) {
    730         if (lport < SOC_MAX_NUM_PORTS) {
    731             rv = bcm_port_enable_set(unit, lport, 0);
    732             if (BCM_FAILURE(rv)) {
    733                 cli_out("\nbcm_port_disable_set %0d: %s", lport, bcm_errmsg(rv));
    734                 sal_free(resource);
    735                 return rv;
    736             }
    737         }
    738     }
    739 
    740     cli_out("flexport_call_bcm_api() Disabled ports DOWN");
    741     flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
    742 
    743     for (i = 0; i < nports; i ++) {
    744         LOG_INFO(BSL_LS_APPL_TESTS,
    745                  (BSL_META_U(unit, "resource[%0d]: physical_port = %0d\n"),
    746                              i, resource[i].physical_port));
    747         LOG_INFO(BSL_LS_APPL_TESTS,
    748                  (BSL_META_U(unit, "resource[%0d]: port  = %0d\n"),
    749                              i, resource[i].port));
    750         LOG_INFO(BSL_LS_APPL_TESTS,
    751                  (BSL_META_U(unit, "resource[%0d]: speed = %0d\n"),
    752                              i, resource[i].speed));
    753         LOG_INFO(BSL_LS_APPL_TESTS,
    754                  (BSL_META_U(unit, "resource[%0d]: lanes = %0d\n"),
    755                              i, resource[i].lanes));
    756         LOG_INFO(BSL_LS_APPL_TESTS,
    757                  (BSL_META_U(unit, "resource[%0d]: encap = %0d\n"),
    758                              i, resource[i].encap));
    759         LOG_INFO(BSL_LS_APPL_TESTS,
    760                  (BSL_META_U(unit, "resource[%0d]: fec_type = %0d\n\n"),
    761                              i, resource[i].fec_type));
    762         /*cli_out("\nresource[%0d]: physical_port =%0d port=%0d speed=%0dG lanes=%0d encap=%0d fec_type=%0d link_training=%0d\n",
    763                 i, resource[i].physical_port, resource[i].port, resource[i].speed, 
    764                 resource[i].lanes, resource[i].encap, resource[i].fec_type, resource[i].link_training);*/
    765     }
    766 
    767     LOG_INFO(BSL_LS_APPL_TESTS,
    768              (BSL_META_U(unit, "Calling bcm_port_resource_multi:\n")));
    769     rv = bcm_port_resource_multi_set(unit, nports, resource);
    770     if (BCM_FAILURE(rv)) {
    771         cli_out("\nbcm_port_resource_multi_set: %s", bcm_errmsg(rv));
    772         sal_free(resource);
    773         flexport_p->test_fail = 1;
    774         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
    775         return rv;
    776     }
    777 
    778     cli_out("Wait 0.1s for TSC configuration changes to take effect\n");
    779     sal_usleep(100000);
    780 
    781     cli_out("flexport_call_bcm_api() Enabled ports UP");
    782     flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
    783 
    784 
    785     PBMP_ITER(flexport_p->port_up_pbmp, lport) {
    786         if (lport < SOC_MAX_NUM_PORTS) {
    787             rv = bcm_port_enable_set(unit, lport, 1);
    788             if (BCM_FAILURE(rv)) {
    789                 cli_out("\nbcm_port_enable_set %0d: %s", lport, bcm_errmsg(rv));
    790                 sal_free(resource);
    791                 return rv;
    792             }
    793         }
    794     }
    795 
    796     sal_free(resource);
    797 
    798     return BCM_E_NONE;
    799 }
    800 
    801 
    802 /* NEW FRAMEWORK */
    803 static int flex_get_phy_port(
    804     int unit,
    805     flex_entry_t *flex_entry)
    806 {
    807     if (SOC_IS_TOMAHAWK3(unit)){
    808         return (1 + (8 * flex_entry->pm_num) + flex_entry->subport);
    809     } else {
    810         return (1 + (4 * flex_entry->pm_num) + flex_entry->subport);
    811     }
    812 }
    813 
    814 /* NEW FRAMEWORK */
    815 static int get_flex_entry(
    816     int unit,
    817     char *str,
    818     flex_entry_t *flex_entry,
    819     int start_indx)
    820 {
    821     char str2[20]= "_";
    822     char c_temp[10];
    823     int entry_indx, i;
    824     int value;
    825     int fec_type;
    826     flexport_t *flexport_p = flexport_parray[unit];
    827 
    828     strcat(str, str2);
    829     /*cli_out("\n Original str=%s\n", str);*/
    830 
    831     fec_type = 0;
    832     entry_indx = start_indx;
    833     i = 0;
    834     /*while(*str && (*str != '\0')) {*/
    835     flex_entry->fec = 0;
    836     do {
    837         /*cli_out("test=%0d", *str);*/
    838         if ((*str != '_') && (*str !='\0')) {
    839             c_temp[i] = *str;
    840             i++;
    841         } else {
    842             c_temp[i] = '\0';
    843             value = sal_atoi(c_temp);
    844             switch (entry_indx) {
    845                 case 0 :  flex_entry->pm_num = value; break;
    846                 case 1 :  flex_entry->subport = value; break;
    847                 case 2 :  flex_entry->speed = value; break;
    848                 case 3 :  flex_entry->num_lanes = value; break;
    849                 case 4 :  fec_type = value; break;
    850                 default : cli_out("\n char_convert() to many entries entry_indx=%0d\n",
    851                           entry_indx); break;
    852             }
    853             i = 0;
    854             entry_indx++;
    855         }
    856         str++;
    857     } while (*str && (*str != '\0'));
    858 
    859     if (flexport_p->fec_type_param != -1) {
    860         fec_type = flexport_p->fec_type_param;
    861     }
    862 
    863     switch(fec_type) {
    864         case   0 : flex_entry->fec = FLX_FEC_NONE;   break; /**< no FEC */
    865         case  74 : flex_entry->fec = FLX_FEC_BASE_R; break; /**< CL74/Base-R. 64/66b KR FEC for fabric */
    866         case 528 : flex_entry->fec = FLX_FEC_RS_FEC; break; /**< CL91/RS-FEC also knwon as RS 528*/
    867         case 544 : if (flex_entry->speed == 400) {
    868                        flex_entry->fec = FLX_FEC_RS_544_2XN;  /**< Rs544 2xN*/
    869                    } else {
    870                        flex_entry->fec = FLX_FEC_RS_544;  /**< Rs544 1xN*/
    871                    }
    872                    break;
    873         case 5442: flex_entry->fec = FLX_FEC_RS_544_2XN; break;   /**< Rs544 2xN*/
    874         case 272 : flex_entry->fec = FLX_FEC_RS_272; break; /**< Rs272 */
    875         default  : flex_entry->fec = FLX_FEC_NONE;   break; /**< no FEC */
    876     }
    877 
    878     return SOC_E_NONE;
    879 }
    880 
    881 /* NEW FRAMEWORK */
    882 static int find_str_dict(
    883     int unit,
    884     char *new_cdmac_config_str,
    885     char *cdmac_config[4],
    886     int *num_entries)
    887 {
    888     char fname[20] = "cdmac_cfg.dict";
    889     FILE *fp;
    890     char line[256];
    891     int len;
    892     char cfg_key_str[30] = "CDMAC_CONFIG=";
    893     char *cdmac_config_str;
    894     int parse_current_config;
    895     int cdmac_config_found;
    896     int i;
    897     flexport_t *flexport_p = flexport_parray[unit];
    898 
    899     /* Open bcm config file */
    900     fp = fopen(fname, "r");
    901     if (fp == NULL) {
    902         cli_out("\n*ERROR: Cannot open bcm config file: '%s'\n", fname);
    903     } else {
    904         cli_out("Loading bcm config file: '%s'\n", fname);
    905     }
    906 
    907     parse_current_config = 0;
    908     cdmac_config_found = 0;
    909     i = 0;
    910     while (fgets(line, sizeof(line), fp)) {
    911         if (sal_strstr(line, "#") != line) {
    912             len = strlen(line);
    913             if (len > 30) {
    914                 fclose(fp);
    915                 return SOC_E_FAIL;
    916             }
    917 
    918             if(len > 1) {
    919                 /*cli_out("FILE: line_size=%0d  =%s", len, line);*/
    920                 if (sal_strstr(line, cfg_key_str) == line) {
    921                     /*cli_out("CDMAC_CONFIG: %s", line);*/
    922                     cdmac_config_str = sal_strtok(line, cfg_key_str);
    923                     /*cli_out("CDMAC_CONFIG is %s", cdmac_config_str);*/
    924                     sal_strtok(cdmac_config_str, "\n");
    925                     if (sal_strcmp(cdmac_config_str, new_cdmac_config_str) == 0) {
    926                         cli_out("CDMAC_CONFIG found %s\n", new_cdmac_config_str);
    927                         parse_current_config = 1;
    928                         cdmac_config_found = 1;
    929                     } else {
    930                         parse_current_config = 0;
    931                     }
    932                 } else {
    933                     if (parse_current_config == 1) {
    934                         sal_strtok(line, "\n");
    935                         /*cli_out("MATCHED CONFIG LINE: %s\n", line);*/
    936                         /*cdmac_config[i] = line;*/
    937                         sal_strcpy(cdmac_config[i], line);
    938                         i++;
    939                     }
    940                 }
    941             }
    942         }
    943     }
    944     *num_entries = i;
    945 
    946     if (cdmac_config_found == 0) {
    947         cli_out("\n*ERROR: Could not find CDMAC_CONFIG=%s in config file: '%s'\n", new_cdmac_config_str, fname);
    948         flexport_p->test_fail = 1;
    949         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
    950     }
    951 
    952     fclose(fp);
    953 
    954     return SOC_E_NONE;
    955 }
    956 
    957 
    958 /* NEW FRAMEWORK */
    959 static int process_flex_entry_option(
    960     int unit,
    961     char *flex_entry_str)
    962 {
    963     /*char str_config[20] = "2x100";*/ /*"1x400";*/
    964     char *cdmac_config[4];
    965     flex_entry_t *flex_entry;
    966     int i, num_entries = 0;
    967     char *token;
    968     int base_subport[2];
    969     char *pm_cd, *cd, *cd_cfg;
    970     int is_2nd_mac;
    971     char *cd_1, *cd_cfg_1;
    972     flexport_t *flexport_p = flexport_parray[unit];
    973     int pm_num, entry_num;
    974 
    975     pm_cd = sal_alloc(20*sizeof(char), "char");
    976     cd = sal_alloc(20*sizeof(char), "char");
    977     cd_cfg = sal_alloc(20*sizeof(char), "char");
    978     cd_1 = sal_alloc(20*sizeof(char), "char");
    979     cd_cfg_1 = sal_alloc(20*sizeof(char), "char");
    980 
    981    /* get the first token */
    982    token = sal_strtok(flex_entry_str, "_");
    983    i = 0;
    984    is_2nd_mac = 0;
    985    while( token != NULL ) {
    986       if (i == 0) { sal_strcpy(pm_cd, token);}
    987       if (i == 1) { sal_strcpy(cd, token);}
    988       if (i == 2) { sal_strcpy(cd_cfg, token);}
    989       if (i == 3) { sal_strcpy(cd_1, token);}
    990       if (i == 4) { sal_strcpy(cd_cfg_1, token);}
    991       /*cli_out( "token=%s pm_cd=%s\n", token, pm_cd);*/
    992       token = sal_strtok(NULL, "_");
    993       i++;
    994    }
    995    if (i > 3) { is_2nd_mac = 1;}
    996    /*cli_out( "%s %s\n", pm_num, cdmac_num);
    997    cli_out( "token=%s\n", token);*/
    998 
    999 
   1000    token = sal_strtok(pm_cd, "PM");
   1001    pm_num = sal_atoi(token);
   1002    token = sal_strtok(cd, "CD");
   1003    base_subport[0] = 4 * sal_atoi(token);
   1004    base_subport[1] = 0;
   1005    if(is_2nd_mac == 1) {
   1006        token = sal_strtok(cd_1, "CD");
   1007        base_subport[1] = 4 * sal_atoi(token);
   1008    }
   1009 
   1010    /*cli_out( "pm_num=%0d base_subport0=%0d base_subport1=%0d cd_cfg=%s cd_cfg_1=%s\n",
   1011        pm_num, base_subport[0], base_subport[1], cd_cfg, cd_cfg_1);*/
   1012 
   1013     for (i = 0; i < 4; i++){
   1014         cdmac_config[i] = sal_alloc(20*sizeof(char), "char");
   1015     }
   1016 
   1017     find_str_dict(unit, cd_cfg, cdmac_config, &num_entries);
   1018 
   1019     entry_num = flexport_p->num_flex_entries;
   1020     for (i = 0; i < num_entries; i++){
   1021         flex_entry = &(flexport_p->flex_entry[entry_num]);
   1022         flex_entry->pm_num = pm_num;
   1023         /*cli_out("PM[%0d]_CDMAC[%0d]=%s\n",
   1024            pm_num, i, cdmac_config[i]);*/
   1025         get_flex_entry(unit, cdmac_config[i], flex_entry, 1);
   1026         flex_entry->subport += base_subport[0];
   1027         /*cli_out("\n pm_num=%0d subport=%0d speed=%0d num_lanes=%0d fec=%0d\n",
   1028             flex_entry->pm_num, flex_entry->subport, flex_entry->speed,
   1029             flex_entry->num_lanes, flex_entry->fec);*/
   1030         /*if fec specified as global param, add it here*/
   1031         entry_num++;
   1032     }
   1033     flexport_p->num_flex_entries = entry_num;
   1034 
   1035     if (is_2nd_mac == 1) {
   1036         find_str_dict(unit, cd_cfg_1, cdmac_config, &num_entries);
   1037         entry_num = flexport_p->num_flex_entries;
   1038         for (i = 0; i < num_entries; i++){
   1039             flex_entry = &(flexport_p->flex_entry[entry_num]);
   1040             flex_entry->pm_num = pm_num;
   1041             /*cli_out("PM[%0d]_CDMAC[%0d]=%s\n",
   1042                pm_num, i, cdmac_config[i]);*/
   1043             get_flex_entry(unit, cdmac_config[i], flex_entry, 1);
   1044             flex_entry->subport += base_subport[1];
   1045             /*cli_out("\n pm_num=%0d subport=%0d speed=%0d num_lanes=%0d fec=%0d\n",
   1046                 flex_entry->pm_num, flex_entry->subport, flex_entry->speed,
   1047                 flex_entry->num_lanes, flex_entry->fec);*/
   1048             /*if fec specified as global param, add it here*/
   1049             entry_num++;
   1050         }
   1051         flexport_p->num_flex_entries = entry_num;
   1052    }
   1053 
   1054     sal_free(pm_cd);
   1055     sal_free(cd);
   1056     sal_free(cd_cfg);
   1057     sal_free(cd_1);
   1058     sal_free(cd_cfg_1);
   1059 
   1060     for (i = 0; i < 4; i++){
   1061         sal_free(cdmac_config[i]);
   1062     }
   1063 
   1064     return SOC_E_NONE;
   1065 }
   1066 
   1067 
   1068 
   1069 /* NEW FRAMEWORK */
   1070 static int flexport_get_new_lport(
   1071     int unit,
   1072     int pport,
   1073     pbmp_t log_pbmp,
   1074     int *new_lport)
   1075 {
   1076     int rv = BCM_E_NONE;
   1077     int p;
   1078     int log_start, log_end, pipe;
   1079     int lport_found;
   1080 
   1081     get_per_pipe_log_port_range(unit, pport,
   1082         &log_start, &log_end, &pipe);
   1083 
   1084     *new_lport = 0;
   1085     lport_found = 0;
   1086     /* find the first available log port in pipe */
   1087     for (p = log_start; p <= log_end; p++) {
   1088         if (!SOC_PBMP_MEMBER(log_pbmp, p)) {
   1089             *new_lport = p;
   1090             lport_found = 1;
   1091             break;
   1092         }
   1093     }
   1094 
   1095     if (lport_found == 0) {
   1096         rv = BCM_E_FAIL;
   1097         cli_out("\nflexport_get_new_lport() Unable to find an available log port for phy_port=%0d",
   1098                    pport);
   1099     }
   1100 
   1101     return rv;
   1102 }
   1103 
   1104 /* NEW FRAMEWORK */
   1105 static int flexport_apply_sku_constraints(
   1106     int unit)
   1107 {
   1108     flexport_t *flexport_p = flexport_parray[unit];
   1109     int rv = BCM_E_NONE;
   1110     int i, old_pm, new_pm, quadrant, shift = 0;
   1111 
   1112     /* If SKU 9.6T then :
   1113      * pm[3] is not valid in pipes {0,1,4,5}
   1114      * pm[0] is not valid in pipes {2,3,6,7}
   1115      * have a deterministic transformation to PM[0:2] / PM[1:3]
   1116      */
   1117     if (flexport_p->sku == 56981) {
   1118         for (i = 0; i < flexport_p->num_flex_entries; i++) {
   1119             old_pm = flexport_p->flex_entry[i].pm_num;
   1120             quadrant = old_pm / 8;
   1121             shift = ((quadrant % 2) == 0) ? 0 : 1;
   1122             new_pm = ((old_pm / 4) * 4) + (old_pm % 3) + shift;
   1123             flexport_p->flex_entry[i].pm_num = new_pm;
   1124         }
   1125     }
   1126 
   1127     /* Half Chip SKU :
   1128      * pipes active are {0,1,6,7}
   1129      * move a pm from non valid pipe to a valid one
   1130      */
   1131     if (flexport_p->sku == 56983) {
   1132         for (i = 0; i < flexport_p->num_flex_entries; i++) {
   1133             old_pm = flexport_p->flex_entry[i].pm_num;
   1134             if (((old_pm + (_TH3_NUM_OF_TSCBH / 4)) % _TH3_NUM_OF_TSCBH) >= (_TH3_NUM_OF_TSCBH / 2)) {
   1135                 new_pm = (old_pm + (_TH3_NUM_OF_TSCBH / 2)) % _TH3_NUM_OF_TSCBH;
   1136                 flexport_p->flex_entry[i].pm_num = new_pm;
   1137             }
   1138         }
   1139     }
   1140 
   1141     return rv;
   1142 }
   1143 
   1144 /* NEW FRAMEWORK */
   1145 static int flexport_apply_transformation(
   1146     int unit)
   1147 {
   1148     flexport_t *flexport_p = flexport_parray[unit];
   1149     int rv = BCM_E_NONE;
   1150     int i, old_pm, new_pm;
   1151 
   1152     /* Apply random transformation
   1153      * Circular shift: new_pm = (old_pm + RAND) % CHIP_NUM_PMs
   1154      * RAND is randomized at the beginning of the test &
   1155      * fixed for the entire test run
   1156      */
   1157     if (flexport_p->rand_pm_en == 1) {
   1158         for (i = 0; i < flexport_p->num_flex_entries; i++) {
   1159             old_pm = flexport_p->flex_entry[i].pm_num;
   1160             new_pm = (old_pm + flexport_p->rand_pm_shift) % _TH3_NUM_OF_TSCBH;
   1161             flexport_p->flex_entry[i].pm_num = new_pm;
   1162         }
   1163     }
   1164 
   1165     return rv;
   1166 }
   1167 
   1168 
   1169 
   1170 /* NEW FRAMEWORK */
   1171 static int process_flex_entries(
   1172     int unit)
   1173 {
   1174     int i;
   1175     int pport, lport;
   1176     int curr_speed, curr_num_lanes;
   1177     int new_speed, new_num_lanes;
   1178     int rv = BCM_E_NONE;
   1179     pbmp_t log_pbmp;
   1180     int new_lport, lane;
   1181     soc_info_t *si;
   1182     flexport_t *flexport_p = flexport_parray[unit];
   1183 
   1184     si = &SOC_INFO(unit);
   1185 
   1186     /* pbm used to get available log ports */
   1187     log_pbmp = PBMP_PORT_ALL(unit);
   1188 
   1189     flexport_apply_transformation(unit);
   1190     flexport_apply_sku_constraints(unit);
   1191 
   1192     /* Firstly, delete ports */
   1193     flexport_p->num_del = 0;
   1194     for (i = 0; i < flexport_p->num_flex_entries; i++) {
   1195         pport = flex_get_phy_port(unit, &(flexport_p->flex_entry[i]));
   1196         lport = si->port_p2l_mapping[pport];
   1197         if (lport != -1) {
   1198             rv = bcm_port_speed_get(unit, lport, &curr_speed);
   1199             if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
   1200                 cli_out("\nbcm_port_speed_get %0d %0d: %s",
   1201                         lport, rv, bcm_errmsg(rv));
   1202                 return rv;
   1203             }
   1204             curr_num_lanes = si->port_num_lanes[lport];
   1205         } else {
   1206             curr_speed = 0;
   1207             curr_num_lanes = 0;
   1208         }
   1209         new_speed = flexport_p->flex_entry[i].speed;
   1210         new_speed = new_speed * 1000;
   1211         new_num_lanes = flexport_p->flex_entry[i].num_lanes;
   1212 
   1213         /* Delete port if:
   1214          * curr_speed != 0
   1215          * AND curr_speed/num_lanes different that new_speed/num_lanes
   1216          */
   1217         if ((curr_speed != 0) &&
   1218             ((curr_speed != new_speed) ||
   1219              (curr_num_lanes != new_num_lanes))) {
   1220             cli_out("Removing phy_port=%0d log_port=%0d\n",
   1221                        pport, lport);
   1222             bcm_port_resource_t_init(
   1223                 &flexport_p->del_resource[flexport_p->num_del]);
   1224             flexport_p->del_resource[flexport_p->num_del].physical_port = -1;
   1225             flexport_p->del_resource[flexport_p->num_del].port = lport;
   1226             flexport_p->num_del++;
   1227             SOC_PBMP_PORT_ADD(flexport_p->port_down_pbmp, lport);
   1228             /* Free log port to be reused */
   1229             SOC_PBMP_PORT_REMOVE(log_pbmp, lport);
   1230             SOC_PBMP_PORT_REMOVE(flexport_p->counter_pbm, lport);
   1231         }
   1232 
   1233         /* Also, remove all actvie ports in [pport : pport+new_num_lanes-1] range */
   1234         for (lane = 1; lane < new_num_lanes; lane ++) {
   1235             lport = si->port_p2l_mapping[pport + lane];
   1236             if (lport != -1) {
   1237                 cli_out("Removing also phy_port=%0d log_port=%0d\n",
   1238                        pport + lane, lport);
   1239                 bcm_port_resource_t_init(
   1240                     &flexport_p->del_resource[flexport_p->num_del]);
   1241                 flexport_p->del_resource[flexport_p->num_del].physical_port = -1;
   1242                 flexport_p->del_resource[flexport_p->num_del].port = lport;
   1243                 flexport_p->num_del++;
   1244                 SOC_PBMP_PORT_ADD(flexport_p->port_down_pbmp, lport);
   1245                 /* Free log port to be reused */
   1246                 SOC_PBMP_PORT_REMOVE(log_pbmp, lport);
   1247                 SOC_PBMP_PORT_REMOVE(flexport_p->counter_pbm, lport);
   1248             }
   1249         }
   1250     }
   1251 
   1252 
   1253     /* Secondly, add ports */
   1254     flexport_p->num_add = 0;
   1255     for (i = 0; i < flexport_p->num_flex_entries; i++) {
   1256         pport = flex_get_phy_port(unit, &(flexport_p->flex_entry[i]));
   1257         lport = si->port_p2l_mapping[pport];
   1258         if (lport != -1) {
   1259             rv = bcm_port_speed_get(unit, lport, &curr_speed);
   1260             if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
   1261                 cli_out("\nbcm_port_speed_get %0d %0d: %s",
   1262                         lport, rv, bcm_errmsg(rv));
   1263                 return rv;
   1264             }
   1265             curr_num_lanes = si->port_num_lanes[lport];
   1266         } else {
   1267             curr_speed = 0;
   1268             curr_num_lanes = 0;
   1269         }
   1270         new_speed = flexport_p->flex_entry[i].speed;
   1271         new_speed = new_speed * 1000;
   1272         new_num_lanes = flexport_p->flex_entry[i].num_lanes;
   1273 
   1274         /* Add port if:
   1275          * new_speed != 0
   1276          * AND curr_speed/num_lanes different that new_speed/num_lanes
   1277          */
   1278         if ((new_speed != 0) &&
   1279             ((curr_speed != new_speed) ||
   1280              (curr_num_lanes != new_num_lanes))) {
   1281             rv = flexport_get_new_lport(unit, pport, log_pbmp, &new_lport);
   1282             if (BCM_FAILURE(rv)) {
   1283                 cli_out("\nUnable to find available port");
   1284                 flexport_p->test_fail = 1;
   1285                 flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   1286                 return rv;
   1287             }
   1288             bcm_port_resource_t_init(
   1289                 &flexport_p->add_resource[flexport_p->num_add]);
   1290             cli_out("Adding phy_port=%0d log_port=%0d speed=%0dG num_lanes=%0d\n",
   1291                        pport, new_lport, new_speed/1000, new_num_lanes);
   1292             flexport_p->add_resource[flexport_p->num_add].physical_port = pport;
   1293             flexport_p->add_resource[flexport_p->num_add].port  = new_lport;
   1294             flexport_p->add_resource[flexport_p->num_add].speed = new_speed;
   1295             flexport_p->add_resource[flexport_p->num_add].lanes = new_num_lanes;
   1296             flexport_p->add_resource[flexport_p->num_add].encap = BCM_PORT_ENCAP_IEEE; /* Only ETH for now */
   1297             flexport_p->add_resource[flexport_p->num_add].fec_type = flexport_p->flex_entry[i].fec;
   1298             flexport_p->add_resource[flexport_p->num_add].link_training = 0;
   1299             flexport_p->num_add++;
   1300             SOC_PBMP_PORT_ADD(flexport_p->port_up_pbmp, new_lport);
   1301             SOC_PBMP_PORT_ADD(log_pbmp, new_lport);
   1302             SOC_PBMP_PORT_ADD(flexport_p->counter_pbm, new_lport);
   1303         }
   1304     }
   1305 
   1306     return rv;
   1307 }
   1308 
   1309 /* NEW FRAMEWORK */
   1310 static int process_flex_id(
   1311     int unit,
   1312     int flex_id,
   1313     char *section)
   1314 {
   1315     char fname[20] = "flexport_th3.tpl";
   1316     FILE *fp;
   1317     char line[256];
   1318     int len;
   1319     char flex_key_str[60] = "FLEX_ID=";
   1320     char *line_flex_str;
   1321     int parse_current_config;
   1322     int string_found;
   1323     int i, line_flex_id;
   1324     flexport_t *flexport_p = flexport_parray[unit];
   1325     char sec_key_str[30] = "SECTION=";
   1326     int input_mode;
   1327     int found_section;
   1328 
   1329     input_mode = flexport_p->input_mode_param;
   1330     found_section = (input_mode == 2) ? 1 : 0;
   1331 
   1332     fp = fopen(fname, "r");
   1333     if (fp == NULL) {
   1334         cli_out("\n*ERROR: Cannot open bcm config file: '%s'\n", fname);
   1335     } else {
   1336         cli_out("\nLoading bcm config file: '%s'\n", fname);
   1337     }
   1338 
   1339     parse_current_config = 0;
   1340     string_found = 0;
   1341     i = 0;
   1342     while (fgets(line, sizeof(line), fp)) {
   1343         if (sal_strstr(line, "#") != line) {
   1344             len = strlen(line);
   1345             if (len > 60) {
   1346                 fclose(fp);
   1347                 return SOC_E_FAIL;
   1348             }
   1349 
   1350             if(len > 1) {
   1351                 if ((input_mode == 3) &&
   1352                     (sal_strstr(line, sec_key_str) == line)) {
   1353                     line_flex_str = sal_strtok(line, sec_key_str);
   1354                     sal_strtok(line_flex_str, "\n");
   1355                     if (sal_strcmp(line_flex_str, section) == 0) {
   1356                         found_section = 1;
   1357                         cli_out("FOUND SECTION: %s\n", line_flex_str);
   1358                     } else {
   1359                         found_section = 0;
   1360                         parse_current_config = 0;
   1361                     }
   1362                 } else if ((sal_strstr(line, flex_key_str) == line) &&
   1363                     (found_section == 1) ) {
   1364                     line_flex_str = sal_strtok(line, flex_key_str);
   1365                     sal_strtok(line_flex_str, "\n");
   1366                     line_flex_id = sal_atoi(line_flex_str);
   1367                     if (line_flex_id == flex_id) {
   1368                         /*cli_out("FLEX_ID found %s %0d\n", line_flex_str, line_flex_id);*/
   1369                         parse_current_config = 1;
   1370                         string_found = 1;
   1371                     } else {
   1372                         parse_current_config = 0;
   1373                     }
   1374                 } else {
   1375                     if (parse_current_config == 1) {
   1376                         sal_strtok(line, "\n");
   1377                         /*cli_out("MATCHED FLEX ENTRY LINE: %s\n", line);*/
   1378                         process_flex_entry_option(unit, line);
   1379                         i++;
   1380                     }
   1381                 }
   1382             }
   1383         }
   1384     }
   1385 
   1386     if (string_found == 0) {
   1387         cli_out("\n*ERROR: Could not find FLEX_%04d in config file: '%s'\n", flex_id, fname);
   1388         flexport_p->test_fail = 1;
   1389         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   1390     }
   1391 
   1392     fclose(fp);
   1393 
   1394     return SOC_E_NONE;
   1395 }
   1396 
   1397 
   1398 
   1399 
   1400 /* NEW FRAMEWORK */
   1401 static int flexport_by_entries(
   1402     int unit)
   1403 {
   1404     flexport_t *flexport_p = flexport_parray[unit];
   1405     int i, entry_num;
   1406     int flex_id;
   1407 
   1408 /* Input Mode: per port in CLI */
   1409 if(flexport_p->input_mode_param == 0) {
   1410     entry_num = 0;
   1411     for (i = 0; i < 64; i++) {
   1412         if (flexport_p->tsc_param[i] != NULL) {
   1413             get_flex_entry(unit, flexport_p->tsc_param[i], &(flexport_p->flex_entry[entry_num]), 0);
   1414             entry_num++;
   1415         }
   1416     }
   1417     flexport_p->num_flex_entries = entry_num;
   1418 /* Input Mode: per PM using config_dict.txt */
   1419 } else if(flexport_p->input_mode_param == 1) {
   1420     for (i = 0; i < 64; i++) {
   1421         if (flexport_p->tsc_param[i] != NULL) {
   1422             process_flex_entry_option(unit, flexport_p->tsc_param[i]);
   1423         }
   1424     }
   1425 /* Input Mode: per FLEX_ID using flex_tpl.txt & config_dict.txt */
   1426 } else {
   1427     flex_id = flexport_p->flex_id_start_param + flexport_p->flex_iter;
   1428     process_flex_id(unit, flex_id, flexport_p->tpl_section);
   1429 }
   1430 
   1431     process_flex_entries(unit);
   1432 
   1433     return BCM_E_NONE;
   1434 }
   1435 
   1436 
   1437 /*
   1438  * Function:
   1439  *      set_up_ports
   1440  * Purpose:
   1441  *      Enable port bridging and HiGig lookup for HG2 ports
   1442  * Parameters:
   1443  *      unit - StrataSwitch Unit #.
   1444  *      pbmp - Device port bitmap
   1445  *
   1446  * Returns:
   1447  *     Nothing
   1448  */
   1449 
   1450 static void
   1451 set_up_ports(int unit, pbmp_t pbmp)
   1452 {
   1453     int i, p;
   1454     lport_tab_entry_t lport_tab_entry;
   1455     port_tab_entry_t port_tab_entry;
   1456     soc_field_t ihg_lookup_fields[] =
   1457         { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf,
   1458         REMOVE_MH_SRC_PORTf
   1459     };
   1460     uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 };
   1461 
   1462     cli_out("CALL set_up_ports\n");
   1463 
   1464     PBMP_ITER(pbmp, p) {
   1465         if (p < SOC_MAX_NUM_PORTS && IS_HG_PORT(unit, p)) {
   1466             soc_reg_fields32_modify(unit, IHG_LOOKUPr, p, 5,
   1467                                     ihg_lookup_fields, ihg_lookup_values);
   1468         }
   1469     }
   1470 
   1471     cli_out("\nEnabling Port bridging");
   1472 
   1473     for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) {
   1474         (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i,
   1475                      lport_tab_entry.entry_data);
   1476 if (!SOC_IS_TOMAHAWK3(unit)){
   1477         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   1478                             ALLOW_SRC_MODf, 0x1);
   1479 }
   1480         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   1481                             PORT_BRIDGEf, 0x1);
   1482         (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i,
   1483                       lport_tab_entry.entry_data);
   1484     }
   1485 
   1486     for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) {
   1487         (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i,
   1488                      port_tab_entry.entry_data);
   1489         soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data,
   1490                             PORT_BRIDGEf, 0x1);
   1491         (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i,
   1492                           port_tab_entry.entry_data);
   1493     }
   1494 }
   1495 
   1496 /*
   1497  * Function:
   1498  *      set_up_streams
   1499  * Purpose:
   1500  *      VLAN programming. Each port is put on an unique VLAN.
   1501  * Parameters:
   1502  *      unit: StrataSwitch Unit #.
   1503  *      pbmp - Device port bitmap
   1504  *      vlan_bmp - bitmap of device ports that have vlan set up
   1505  *
   1506  * Returns:
   1507  *     vlan_pbmp - bitmap of device ports that have vlan set up.
   1508  */
   1509 
   1510 static pbmp_t
   1511 set_up_streams(int unit, pbmp_t pbmp, pbmp_t vlan_pbmp)
   1512 {
   1513     int p;
   1514     pbmp_t pbm, ubm;
   1515     bcm_vlan_t vlan;
   1516 
   1517     BCM_PBMP_CLEAR(ubm);
   1518 
   1519     PBMP_ITER(pbmp, p) {
   1520         if (p < SOC_MAX_NUM_PORTS) {
   1521             vlan = get_vlan_id(unit, p);
   1522             if (SOC_PBMP_MEMBER(vlan_pbmp, p)) {
   1523                 /*cli_out("\n set_up_streams() port=%0d calling stream_set_vlan()", p);*/
   1524                 stream_set_vlan(unit, vlan, 1);
   1525             } else {
   1526                 /*cli_out("\n set_up_streams() port=%0d calling bcm_vlan_port_add()", p);*/
   1527                 BCM_PBMP_CLEAR(pbm);
   1528                 bcm_vlan_create(unit, vlan);
   1529                 BCM_PBMP_PORT_ADD(pbm, p);
   1530                 bcm_vlan_port_add(unit, vlan, pbm, ubm);
   1531             }
   1532         }
   1533     }
   1534 
   1535     SOC_PBMP_OR(vlan_pbmp, pbmp);
   1536 
   1537     return vlan_pbmp;
   1538 }
   1539 
   1540 static void
   1541 set_up_streams_l2(
   1542     int unit,
   1543     pbmp_t pbmp,
   1544     int delete)
   1545 {
   1546     int p;
   1547     bcm_l2_addr_t l2_addr;
   1548     bcm_mac_t mac_da;
   1549     bcm_vlan_t vlan;
   1550 
   1551     PBMP_ITER(pbmp, p) {
   1552         if (p < SOC_MAX_NUM_PORTS) {
   1553             vlan = get_vlan_id(unit, p);
   1554             get_mac_da(unit, p, mac_da);
   1555             if (delete == 0) { /* add L2 entry */
   1556                 bcm_l2_addr_t_init(&l2_addr, mac_da, vlan);
   1557                 l2_addr.port = p;
   1558                 l2_addr.flags = 0;
   1559                 bcm_l2_addr_add(unit, &l2_addr);
   1560             } else { /* delete L2 entry */
   1561                 bcm_l2_addr_delete(unit, mac_da, vlan);
   1562             }
   1563         }
   1564     }
   1565 }
   1566 
   1567 
   1568 /*
   1569  * Function:
   1570  *     send_pkts
   1571  * Purpose:
   1572  *     Sends packet for all the ports in the port bitmap
   1573  * Parameters:
   1574  *      unit: StrataSwitch Unit #.
   1575  *      pbmp - port bitmap
   1576  *      pkt_size_param -
   1577  *      pkt_seed -
   1578  *
   1579  * Returns:
   1580  *     flood packet count for the given port.
   1581  */
   1582 static void
   1583 send_pkts(int unit, pbmp_t pbmp)
   1584 {
   1585     int port;
   1586     bcm_mac_t mac_da;
   1587     bcm_mac_t mac_sa;
   1588     stream_pkt_t *tx_pkt;
   1589     flexport_t *flexport_p = flexport_parray[unit];
   1590     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1591 
   1592     tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt");
   1593     sal_memset(tx_pkt, 0, sizeof(stream_pkt_t));
   1594 
   1595     cli_out("\n==================================================\n");
   1596     cli_out("Sending packets ...\n");
   1597     PBMP_ITER(pbmp, port) {
   1598         if (port < SOC_MAX_NUM_PORTS) {
   1599             tx_pkt->port = port;
   1600             tx_pkt->pkt_seed = flexport_p->pkt_seed;
   1601             tx_pkt->num_pkt = flexport_p->per_port_pkt_cnt[port]; /*lossless_flood_cnt(unit, port);*/
   1602             tx_pkt->pkt_size = flexport_p->per_port_pkt_size[port];
   1603             /*cli_out("\nSending packets on port %0d size %0d num %0d.",
   1604                        port, tx_pkt->pkt_size, tx_pkt->num_pkt);*/
   1605             if(flexport_p->pkt_size_param == 1) {
   1606                 tx_pkt->rand_pkt_size_en = 1;
   1607                 tx_pkt->rand_pkt_size = rate_calc_p->rand_pkt_sizes[port];
   1608             } else {
   1609                 tx_pkt->rand_pkt_size_en = 0;
   1610                 tx_pkt->rand_pkt_size = NULL;
   1611             }
   1612             tx_pkt->tx_vlan = get_vlan_id(unit, port);
   1613             get_mac_da(unit, port, mac_da);
   1614             get_mac_sa(unit, port, mac_sa);
   1615             sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR);
   1616             sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR);
   1617             stream_tx_pkt(unit, tx_pkt);
   1618         }
   1619     }
   1620     sal_free(tx_pkt);
   1621 }
   1622 
   1623 /*
   1624  * Function:
   1625  *      start_rate_measurement
   1626  * Purpose:
   1627  *      Get current time, packet count & byte count needed to calculate port
   1628  *      rate
   1629  * Parameters:
   1630  *      unit - StrataSwitch Unit #.
   1631  *      pbmp - Device port bitmap to be used
   1632  *      emulation_param - 1: test run in emulator platform
   1633  *                        0: test run is actual hardware(chip)
   1634  *
   1635  * Returns:
   1636  *     SOC_E_XXXX
   1637  */
   1638 static bcm_error_t
   1639 start_rate_measurement(int unit, pbmp_t pbmp, uint32 emulation_param)
   1640 {
   1641     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1642 
   1643     return record_rate_information(unit, emulation_param, pbmp, rate_calc_p->stime,
   1644                                  rate_calc_p->tpkt_start, rate_calc_p->tbyt_start);
   1645 
   1646 }
   1647 
   1648 /*
   1649  * Function:
   1650  *      check_rates
   1651  * Purpose:
   1652  *      Check rates against expected rates.
   1653  * Parameters:
   1654  *      unit - StrataSwitch Unit #.
   1655  *      pbmp - Device port bitmap to be checked
   1656  *      tolerance_lr - Percentage of rate tolerance for line rate ports
   1657  *      tolerance_os - Percentage of rate tolerance for oversub ports
   1658  *
   1659  * Returns:
   1660  *     SOC_E_XXXX
   1661  */
   1662 
   1663 static bcm_error_t
   1664 check_rates(int unit, pbmp_t pbmp, uint32 tolerance_lr,
   1665              uint32 tolerance_os, uint32 emulation_param)
   1666 {
   1667     uint64 *etime;
   1668     uint64 *tpkt_end;
   1669     uint64 *tbyt_end;
   1670     uint64 *rate;
   1671     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1672     bcm_error_t rv = BCM_E_NONE;
   1673     flexport_t *flexport_p = flexport_parray[unit];
   1674 
   1675     etime = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1676                                       "etime");
   1677     tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1678                                     "tpkt_end");
   1679     tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1680                                     "tbyt_end");
   1681     rate = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1682                                 "rate");
   1683 
   1684     sal_memset(etime,    0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1685     sal_memset(tpkt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1686     sal_memset(tbyt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1687     sal_memset(rate,     0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1688 
   1689     rv = record_rate_information(unit, emulation_param, pbmp, etime,
   1690                                      tpkt_end, tbyt_end);
   1691 
   1692     calc_act_port_rate(unit, pbmp, rate_calc_p->stime, etime,
   1693                        rate_calc_p->tpkt_start, tpkt_end,
   1694                        rate_calc_p->tbyt_start, tbyt_end, rate);
   1695 
   1696     rv = compare_rates(unit, pbmp, tolerance_lr, tolerance_os,
   1697                   rate_calc_p->exp_rate, rate);
   1698 
   1699     if (rv != BCM_E_NONE) {
   1700         test_error(unit, "********** RATE CHECK FAILED ***********\n");
   1701         flexport_p->test_fail = 1;
   1702         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   1703     } else {
   1704         cli_out("\n********** RATE CHECK PASSED ***********");
   1705     }
   1706 
   1707     sal_free(etime);
   1708     sal_free(tpkt_end);
   1709     sal_free(tbyt_end);
   1710     sal_free(rate);
   1711     return rv;
   1712 }
   1713 
   1714 
   1715 static int flexport_get_lr_pkt_size(
   1716     int unit)
   1717 {
   1718     soc_info_t *si = &SOC_INFO(unit);
   1719     int pkt_size;
   1720     int dpr_freq;
   1721 
   1722     dpr_freq = soc_property_get(unit, spn_DPR_CLOCK_FREQUENCY, -1);
   1723 
   1724     pkt_size = 295;
   1725     /* min pkt size depends also on max IO BW/ SKU */
   1726     if (si->frequency >= 1325) {
   1727         if (dpr_freq >= 1000) { /* SKU 12.8T */
   1728             pkt_size = 295;
   1729         } else {
   1730             pkt_size = 298;
   1731         }
   1732     } else if (si->frequency >= 1000) {
   1733         if (dpr_freq >= 750) { /* SKU 9.6T */
   1734             pkt_size = 297;
   1735         } else {  /* SKU 9.6T */
   1736             pkt_size = 301;
   1737         }
   1738     } else if (si->frequency >= 925) {
   1739         pkt_size = 161;
   1740     }
   1741 
   1742     LOG_INFO(BSL_LS_APPL_TESTS,
   1743             (BSL_META_U(unit,
   1744                "flexport_get_lr_pkt_size() CORE freq=%0d DPR freq=%0d lr_pkt_size=%0d\n"),
   1745                si->frequency, dpr_freq, pkt_size));
   1746 
   1747     return pkt_size;
   1748 }
   1749 
   1750 
   1751 /* NEW FRAMEWORK */
   1752 static bcm_error_t flexport_set_pkt_size(
   1753     int unit,
   1754     pbmp_t pbmp)
   1755 {
   1756     bcm_error_t rv = BCM_E_NONE;
   1757     int final_pkt_size, port;
   1758     flexport_t *flexport_p = flexport_parray[unit];
   1759     int lr_pkt_size;
   1760 
   1761     lr_pkt_size = flexport_get_lr_pkt_size(unit);
   1762 
   1763     final_pkt_size = MIN_PKT_SIZE;
   1764     switch(flexport_p->pkt_size_param) {
   1765         /* random pkt between 64: max pkt */
   1766         case 0 :
   1767             final_pkt_size = lr_pkt_size;
   1768             break;
   1769         case 1 :
   1770             final_pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) +
   1771                              MIN_PKT_SIZE;
   1772             break;
   1773         default :
   1774             final_pkt_size = flexport_p->pkt_size_param;
   1775             break;
   1776     }
   1777 
   1778     PBMP_ITER(pbmp, port) {
   1779         if (port < SOC_MAX_NUM_PORTS) {
   1780             flexport_p->per_port_pkt_size[port] = final_pkt_size;
   1781         }
   1782     }
   1783 
   1784     return rv;
   1785 }
   1786 
   1787 /* NOTE: number of pkts to get full BW depends on:
   1788  * - port speed
   1789  * - avg pkt size
   1790  * - pkt round trip latency which is a function of
   1791  *   - device design
   1792  *   - core clock
   1793  *   - pp clock
   1794  */
   1795 static bcm_error_t th3_stream_get_pkt_cnt(
   1796     int unit,
   1797     int port,
   1798     int avg_pkt_size,
   1799     int loopback_mode,
   1800     int fec_type,
   1801     int traffic_load,
   1802     int *num_pkts)
   1803 {
   1804     bcm_error_t rv = BCM_E_NONE;
   1805     int round_trip_latency, port_speed;
   1806     soc_info_t *si = &SOC_INFO(unit);
   1807     int final_pkt_cnt = 0;
   1808 
   1809     switch (loopback_mode) {
   1810         /* MAC Loopback */
   1811         case BCM_PORT_LOOPBACK_MAC  : round_trip_latency = 1350 / 2 /*1190 / 2*/ /* 1154 */; break;
   1812         /* PHY Loopback */
   1813         case BCM_PORT_LOOPBACK_PHY  : round_trip_latency = 1650 / 2 /*1520 / 2*/ /*1474 */; break;
   1814         /* EXT Loopback; not easy to figure out; cables, etc.*/
   1815         case BCM_PORT_LOOPBACK_NONE : round_trip_latency = 1950 / 2; break;
   1816         default :                     round_trip_latency = 1350 / 2; break;
   1817     }
   1818 
   1819     port_speed = si->port_speed_max[port];
   1820     final_pkt_cnt =
   1821         ((round_trip_latency * (port_speed / 1000)) / ((avg_pkt_size + 20) * 8))
   1822         + 1;
   1823 
   1824     /* If low speed port then add 50% more pkts */
   1825     if (port_speed < 50000) {
   1826         final_pkt_cnt = ((final_pkt_cnt * 150) / 100) + 1;
   1827     } else if(port_speed < 100000) {
   1828         final_pkt_cnt = ((final_pkt_cnt * 120) / 100) + 1;
   1829     } else if(port_speed < 200000) {
   1830         final_pkt_cnt = ((final_pkt_cnt * 110) / 100) + 1;
   1831     }
   1832 
   1833     if (si->frequency < 1000) {
   1834         final_pkt_cnt = ((final_pkt_cnt * 130) / 100) + 1;
   1835     } else if (si->frequency < 1325) {
   1836         final_pkt_cnt = ((final_pkt_cnt * 140) / 100) + 1;
   1837     }
   1838 
   1839     *num_pkts = final_pkt_cnt;
   1840 
   1841     return rv;
   1842 }
   1843 
   1844 
   1845 
   1846 
   1847 /* NEW FRAMEWORK */
   1848 static bcm_error_t flexport_set_pkt_count(
   1849     int unit,
   1850     pbmp_t pbmp)
   1851 {
   1852     bcm_error_t rv = BCM_E_NONE;
   1853     flexport_t *flexport_p = flexport_parray[unit];
   1854     int port;
   1855     int avg_pkt_size, final_pkt_cnt;
   1856     int fec_type, traffic_load;
   1857 
   1858     fec_type = 0;
   1859     traffic_load = 100;
   1860 
   1861     PBMP_ITER(pbmp, port) {
   1862         if (port < SOC_MAX_NUM_PORTS) {
   1863             if(flexport_p->flood_pkt_cnt_param == 0) {
   1864                 /* For now avg pkt size is the actual pkt size */
   1865                 avg_pkt_size = flexport_p->per_port_pkt_size[port];
   1866                 th3_stream_get_pkt_cnt(unit, port,
   1867                                        avg_pkt_size,
   1868                                        flexport_p->loopback_mode_param,
   1869                                        fec_type,
   1870                                        traffic_load,
   1871                                        &final_pkt_cnt);
   1872             } else {
   1873                 final_pkt_cnt = flexport_p->flood_pkt_cnt_param;
   1874             }
   1875             flexport_p->per_port_pkt_cnt[port] = final_pkt_cnt;
   1876         }
   1877     }
   1878 
   1879     return rv;
   1880 }
   1881 
   1882 /* NEW FRAMEWORK */
   1883 static int flexport_get_oversub_ratio(
   1884     int unit,
   1885     int port,
   1886     int pkt_size)
   1887 {
   1888     /* for now assume Line Rate only */
   1889     return 1000;
   1890 }
   1891 
   1892 static bcm_error_t flexport_set_exp_rate(
   1893     int unit,
   1894     pbmp_t pbmp)
   1895 {
   1896     bcm_error_t rv = BCM_E_NONE;
   1897     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1898     flexport_t *flexport_p = flexport_parray[unit];
   1899     soc_info_t *si = &SOC_INFO(unit);
   1900     int oversub_ratio;
   1901     int port;
   1902 
   1903     PBMP_ITER(pbmp, port) {
   1904         if (port < SOC_MAX_NUM_PORTS) {
   1905             COMPILER_64_SET(rate_calc_p->exp_max_rate[port],
   1906                             0, si->port_speed_max[port]);
   1907             oversub_ratio = flexport_get_oversub_ratio(unit, port,
   1908                                 flexport_p->per_port_pkt_size[port]);
   1909             COMPILER_64_SET(rate_calc_p->exp_rate[port],
   1910                             0, si->port_speed_max[port]);
   1911             COMPILER_64_UDIV_32(rate_calc_p->exp_rate[port], oversub_ratio);
   1912             COMPILER_64_UMUL_32(rate_calc_p->exp_rate[port], 1000);
   1913         }
   1914     }
   1915 
   1916     return rv;
   1917 }
   1918 
   1919 /* NEW FRAMEWORK */
   1920 /* Sets 
   1921  * pkt size;
   1922  * the number of pkts to be send out
   1923  * expected rate
   1924  */
   1925 static bcm_error_t flexport_set_port_arrays(
   1926     int unit,
   1927     pbmp_t pbmp)
   1928 {
   1929     bcm_error_t rv = BCM_E_NONE;
   1930 
   1931     BCM_IF_ERROR_RETURN(flexport_set_pkt_size(unit, pbmp));
   1932     BCM_IF_ERROR_RETURN(flexport_set_pkt_count(unit, pbmp));
   1933     BCM_IF_ERROR_RETURN(flexport_set_exp_rate(unit, pbmp));
   1934 
   1935     return rv;
   1936 }
   1937 
   1938 
   1939 static bcm_error_t set_up_cutthru(
   1940     int unit,
   1941     pbmp_t pbmp,
   1942     int asf_mode)
   1943 {
   1944     bcm_error_t rv = BCM_E_NONE;
   1945     int port;
   1946     int curr_asf_mode = 0;
   1947 
   1948     PBMP_ITER(pbmp, port) {
   1949         if (port < SOC_MAX_NUM_PORTS) {
   1950             bcm_switch_control_port_get(unit, port, bcmSwitchAlternateStoreForward, &curr_asf_mode);
   1951             bcm_switch_control_port_set(unit, port, bcmSwitchAlternateStoreForward, asf_mode);
   1952             cli_out("bcm_switch_control_port_get() port=%0d curr_asf_mode=%0d new_asf_mode=%0d\n",
   1953                 port, curr_asf_mode, asf_mode);
   1954         }
   1955     }
   1956 
   1957     return rv;
   1958 }
   1959 
   1960 /* NEW FRAMEWORK */
   1961 static bcm_error_t flexport_setup_switch(
   1962     int unit,
   1963     pbmp_t pbmp,
   1964     int delete)
   1965 {
   1966     bcm_error_t rv = BCM_E_NONE;
   1967     flexport_t *flexport_p = flexport_parray[unit];
   1968     int loopback_mode_param;
   1969 
   1970     loopback_mode_param = (delete == 0) ? flexport_p->loopback_mode_param :
   1971                                           BCM_PORT_LOOPBACK_NONE;
   1972     stream_set_lpbk(unit, pbmp, loopback_mode_param);
   1973     if (delete == 0) { /* Only if ports come UP */
   1974         /*stream_turn_off_fc(unit, pbmp);*/
   1975         set_up_ports(unit, pbmp);
   1976         flexport_p->vlan_pbmp = set_up_streams(unit, pbmp,
   1977                                            flexport_p->vlan_pbmp);
   1978 
   1979         if (flexport_p->cut_thru_en == 1) {
   1980         /* Cut-thru forwarding between same
   1981            speed ports */
   1982             set_up_cutthru(unit, pbmp, 1); /* bcmPortAsfModeSameSpeed = 1 */
   1983         }
   1984     }
   1985     set_up_streams_l2(unit, pbmp, delete);
   1986 
   1987     return rv;
   1988 }
   1989 
   1990 /* NEW FRAMEWORK */
   1991 static bcm_error_t flexport_start_traffic(
   1992     int unit,
   1993     pbmp_t pbmp)
   1994 {
   1995     bcm_error_t rv = BCM_E_NONE;
   1996     int port, queue, count = 0;
   1997     /*flexport_t *flexport_p = flexport_parray[unit];*/
   1998 
   1999     send_pkts(unit, pbmp);
   2000 
   2001     queue = 0;
   2002     if (BCM_PBMP_NOT_NULL(pbmp)) {
   2003         /* After traffic is injected clear BST counters that track traffic from CPU to the port 
   2004          * We want to make sure only port to port traffic is checket for not being in CT
   2005          */
   2006         PBMP_ITER(pbmp, port) {
   2007             if (port < SOC_MAX_NUM_PORTS) {
   2008                 th3_get_bst_total_queue(unit, port, queue, &count);
   2009                 if (count == 0) {
   2010                     cli_out("*WARNING flexport_start_traffic() port=%0d BST THDO should be !=0\n", port);
   2011                     /*flexport_p->test_fail = 1;
   2012                     flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;*/
   2013                 }
   2014             }
   2015         }
   2016     }
   2017 
   2018     return rv;
   2019 }
   2020 
   2021 /* NEW FRAMEWORK */
   2022 static bcm_error_t flexport_start_rate_measurement(
   2023     int unit,
   2024     pbmp_t pbmp)
   2025 {
   2026     bcm_error_t rv = BCM_E_NONE;
   2027     flexport_t *flexport_p = flexport_parray[unit];
   2028 
   2029     cli_out("Wait 0.2s for traffic to stabilize\n");
   2030     sal_usleep(100000);
   2031     start_rate_measurement(unit, pbmp, flexport_p->emulation_param);
   2032 
   2033     return rv;
   2034 }
   2035 
   2036 /* NEW FRAMEWORK */
   2037 static bcm_error_t flexport_get_flex_info(
   2038     int unit,
   2039     int flex_iter)
   2040 {
   2041     bcm_error_t rv = BCM_E_NONE;
   2042     flexport_t *flexport_p = flexport_parray[unit];
   2043 
   2044     flexport_p->num_flex_entries = 0;
   2045     flexport_p->num_del = 0;
   2046     flexport_p->num_add = 0;
   2047 
   2048     SOC_PBMP_CLEAR(flexport_p->port_down_pbmp);
   2049     SOC_PBMP_CLEAR(flexport_p->port_up_pbmp);
   2050 
   2051     flexport_by_entries(unit);
   2052 
   2053     return rv;
   2054 }
   2055 
   2056 
   2057 /* NEW FRAMEWORK */
   2058 static bcm_error_t flexport_check_rate(
   2059     int unit,
   2060     pbmp_t pbmp)
   2061 {
   2062     bcm_error_t rv = BCM_E_NONE;
   2063     flexport_t *flexport_p = flexport_parray[unit];
   2064 
   2065     cli_out("===================================\n");
   2066     cli_out("\nMeasuring Rate over a period of %0d ms\n",
   2067             flexport_p->rate_calc_interval_param * 100);
   2068     sal_usleep(flexport_p->rate_calc_interval_param * 100000);
   2069 
   2070 
   2071     if (BCM_PBMP_NOT_NULL(pbmp)) {
   2072         if (!SOC_IS_TOMAHAWK3(unit)){
   2073             if (stream_chk_mib_counters(unit, pbmp, 0) != BCM_E_NONE) {
   2074                 flexport_p->test_fail = 1;
   2075                 flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   2076             }
   2077         }
   2078         if (check_rates(unit, pbmp,
   2079                        flexport_p->rate_tolerance_lr_param,
   2080                        flexport_p->rate_tolerance_ov_param,
   2081                        flexport_p->emulation_param) != BCM_E_NONE) {
   2082             flexport_p->test_fail = 1;
   2083             flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   2084         }
   2085     }
   2086 
   2087     return rv;
   2088 }
   2089 
   2090 /* NEW FRAMEWORK */
   2091 static bcm_error_t flexport_stop_traffic(
   2092     int unit,
   2093     pbmp_t pbmp)
   2094 {
   2095     bcm_error_t rv = BCM_E_NONE;
   2096     flexport_t *flexport_p = flexport_parray[unit];
   2097     bcm_mac_t mac_da;
   2098     bcm_mac_t mac_sa;
   2099     stream_integrity_t *pkt_intg;
   2100     int port;
   2101 
   2102     if (BCM_PBMP_NOT_NULL(pbmp)) {
   2103         if (flexport_p->check_packet_integrity_param != 0) {
   2104             pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity");
   2105             sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
   2106             pkt_intg->rx_pbmp = pbmp;
   2107             PBMP_ITER(pbmp, port) {
   2108                 if (port < SOC_MAX_NUM_PORTS) {
   2109                     pkt_intg->port_pkt_seed[port] = flexport_p->pkt_seed;
   2110                     pkt_intg->port_flood_cnt[port] = flexport_p->per_port_pkt_cnt[port]; /*lossless_flood_cnt(unit, port);*/
   2111                     pkt_intg->rx_vlan[port] = get_vlan_id(unit, port);
   2112                     pkt_intg->tx_vlan[port] = get_vlan_id(unit, port);
   2113                     get_mac_da(unit, port, mac_da);
   2114                     get_mac_sa(unit, port, mac_sa);
   2115                     sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR);
   2116                     sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR);
   2117                 }
   2118             }
   2119             rv = stream_chk_pkt_integrity(unit, pkt_intg);
   2120             if (rv != BCM_E_NONE) {
   2121                 flexport_p->test_fail = 1;
   2122                 flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   2123             }
   2124             sal_free(pkt_intg);
   2125         }
   2126     }
   2127 
   2128     return rv;
   2129 }
   2130 
   2131 /* NEW FRAMEWORK */
   2132 static bcm_error_t flexport_post_traffic_checks(
   2133     int unit,
   2134     pbmp_t pbmp)
   2135 {
   2136     bcm_error_t rv = BCM_E_NONE;
   2137     flexport_t *flexport_p = flexport_parray[unit];
   2138     int port, queue, count=0;
   2139     int fail = 0;
   2140 
   2141     /* Check CutThru */
   2142     queue = 0;
   2143     fail = 0;
   2144     if (BCM_PBMP_NOT_NULL(pbmp)) {
   2145         PBMP_ITER(pbmp, port) {
   2146             if (port < SOC_MAX_NUM_PORTS) {
   2147                 th3_get_bst_total_queue(unit, port, queue, &count);
   2148                 if (flexport_p->cut_thru_en == 1) {
   2149                     if ((count != 0) && (!IS_MANAGEMENT_PORT(unit,port))) {
   2150                         cli_out("*ERROR flexport_post_traffic_checks() CutThru wasn't fully maintain for port=%0d\n", port);
   2151                         fail = 1;
   2152                     }
   2153                     if ((count == 0) && (IS_MANAGEMENT_PORT(unit,port))) {
   2154                         cli_out("*ERROR flexport_post_traffic_checks() MGM port=%0d should have THDO BST !=0\n", port);
   2155                         fail = 1;
   2156                     }
   2157                 } else {
   2158                     if (count == 0) {
   2159                         cli_out("*ERROR flexport_post_traffic_checks() port=%0d should have THDO BST !=0\n", port);
   2160                         fail = 1;
   2161                     }
   2162                 }
   2163             }
   2164         }
   2165     }
   2166 
   2167     if (fail == 1) {
   2168         flexport_p->test_fail = 1;
   2169         flexport_p->test_fail_iter[flexport_p->flex_iter] = 1;
   2170     }
   2171 
   2172     return rv;
   2173 }
   2174 
   2175 
   2176 /* NEW FRAMEWORK */
   2177 static bcm_error_t flexport_do_flexport(
   2178     int unit)
   2179 {
   2180     bcm_error_t rv = BCM_E_NONE;
   2181     flexport_t *flexport_p = flexport_parray[unit];
   2182     uint64 val64;
   2183 
   2184     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flexport_p->counter_flags,
   2185                                                  &flexport_p->counter_interval,
   2186                                                  &flexport_p->counter_pbm));
   2187 
   2188     if (flexport_p->num_del + flexport_p->num_add > 0) {
   2189         if (flexport_p->counter_interval > 0) {
   2190             cli_out("\nDisabling counter collection before FlexPort\n");
   2191             soc_counter_stop(unit);
   2192         }
   2193         flexport_call_bcm_api(unit);
   2194         if (flexport_p->counter_interval > 0) {
   2195             cli_out("\nEnabling counter collection after FlexPort\n");
   2196             soc_counter_start(unit, flexport_p->counter_flags,
   2197                               flexport_p->counter_interval,
   2198                               flexport_p->counter_pbm);
   2199         }
   2200     }
   2201 
   2202     if (flexport_p->clear_new_port_counts) {
   2203         COMPILER_64_ZERO(val64);
   2204         BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit,
   2205                             flexport_p->port_up_pbmp, val64));
   2206     }
   2207 
   2208     return rv;
   2209 }
   2210 
   2211 
   2212 static bcm_error_t set_up_bst_counters(
   2213     int unit)
   2214 {
   2215     bcm_error_t rv = BCM_E_NONE;
   2216     bcm_switch_control_t type;
   2217     int arg, THDO_en, THDI_en;
   2218     /*int CFAP_en;*/
   2219     uint32 rval;
   2220 
   2221     THDO_en = 0x1 << 0;
   2222     THDI_en = 0x1 << 1;
   2223     /*CFAP_en = 0x1 << 2;*/
   2224 
   2225     arg = THDO_en | THDI_en;
   2226     type = bcmSwitchBstEnable;
   2227     bcm_switch_control_set(unit, type, arg);
   2228     type = bcmSwitchBstTrackingMode;
   2229     bcm_switch_control_set(unit, type, arg);
   2230 
   2231     /* Make COR on */
   2232     READ_MMU_THDO_BST_CONFIGr(unit, &rval);
   2233     soc_reg_field_set(unit, MMU_THDO_BST_CONFIGr,
   2234                 &rval, HWM_CORf, 0x1);
   2235     WRITE_MMU_THDO_BST_CONFIGr(unit, rval);
   2236 
   2237     return rv;
   2238 }
   2239 
   2240 
   2241 /*
   2242  * Function:
   2243  *      flexport_test_init
   2244  * Purpose:
   2245  *      Test init function. Parse CLI params and do necessary init.
   2246  * Parameters:
   2247  *      unit - StrataSwitch Unit #.
   2248  *      a - Pointer to arguments
   2249  *
   2250  * Returns:
   2251  *     SOC_E_XXXX
   2252  */
   2253 
   2254 int
   2255 flexport_th3_test_init(int unit, args_t *a, void **pa)
   2256 {
   2257     flexport_t *flexport_p;
   2258     rate_calc_t *rate_calc_p;
   2259 
   2260     flexport_p = flexport_parray[unit];
   2261     flexport_p = sal_alloc(sizeof(flexport_t), "flexport_test");
   2262     sal_memset(flexport_p, 0, sizeof(flexport_t));
   2263     flexport_parray[unit] = flexport_p;
   2264 
   2265     rate_calc_p = rate_calc_parray[unit];
   2266     rate_calc_p = sal_alloc(sizeof(rate_calc_t), "streaming_library");
   2267     sal_memset(rate_calc_p, 0, sizeof(rate_calc_t));
   2268     rate_calc_parray[unit] = rate_calc_p;
   2269 
   2270     cli_out("\nCalling flexport_test_init");
   2271     flexport_parse_test_params(unit, a);
   2272 
   2273     flexport_p->test_fail = 0;
   2274 
   2275     if(flexport_p->emulation_param) {
   2276         start_cmic_timesync(unit);
   2277     }
   2278 
   2279 /*if (!SOC_IS_TOMAHAWK3(unit)){*/
   2280     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flexport_p->counter_flags,
   2281                                                  &flexport_p->counter_interval,
   2282                                                  &flexport_p->counter_pbm));
   2283 /*
   2284     if (flexport_p->counter_interval > 0) {
   2285         cli_out("\nDisabling counter collection");
   2286         soc_counter_stop(unit);
   2287     }
   2288 }*/
   2289     BCM_IF_ERROR_RETURN(bcm_linkscan_enable_get(unit,
   2290                                                 &flexport_p->linkscan_enable));
   2291     if (flexport_p->linkscan_enable) {
   2292         cli_out("\nDisabling linkscan");
   2293         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
   2294     }
   2295 
   2296     /* Enable BST tracking */
   2297 
   2298     set_up_bst_counters(unit);
   2299 
   2300     return BCM_E_NONE;
   2301 }
   2302 
   2303 
   2304 /* NEW FRAMEWORK */
   2305 /*
   2306  * Function:
   2307  *      flexport_test
   2308  * Purpose:
   2309  *      Set up ports/streams and send packets.
   2310  * Parameters:
   2311  *      unit - StrataSwitch Unit #.
   2312  *      a - Pointer to arguments
   2313  *
   2314  * Returns:
   2315  *     SOC_E_XXXX
   2316  */
   2317 
   2318 int
   2319 flexport_th3_test(int unit, args_t *a, void *pa)
   2320 {
   2321     flexport_t *flexport_p;
   2322     int flex_iter = 0;
   2323     int delete = 0;
   2324     bcm_error_t rv = BCM_E_NONE;
   2325     int num_flex_iterations;
   2326 
   2327     flexport_p = flexport_parray[unit];
   2328 
   2329     if (flexport_p->bad_input) {
   2330         goto done;
   2331     }
   2332 
   2333     cli_out("Calling flexport_test\n");
   2334 
   2335     flexport_p->pkt_seed = sal_rand();
   2336     num_flex_iterations = flexport_p->flex_id_end_param
   2337                           - flexport_p->flex_id_start_param + 1;
   2338 
   2339     /*===  BEFORE flex LOOP  ===*/
   2340     flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2341     flexport_set_port_arrays(unit, PBMP_PORT_ALL(unit));
   2342     delete = 0;
   2343     flexport_setup_switch(unit, PBMP_PORT_ALL(unit), delete);
   2344     flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2345     flexport_start_traffic(unit, PBMP_PORT_ALL(unit));
   2346     flexport_start_rate_measurement(unit, PBMP_PORT_ALL(unit));
   2347 
   2348     /*======== FOR EACH FLEX ITERATION  flex_iter: =======*/ 
   2349 
   2350     for (flex_iter = 0; flex_iter < num_flex_iterations; flex_iter++) {
   2351         cli_out("====================================================\n");
   2352         cli_out("START Flex Iteration SECTION=%s FLEX_ID=%0d\n", 
   2353                 flexport_p->tpl_section,
   2354                 flexport_p->flex_id_start_param + flexport_p->flex_iter);
   2355     /* BEFORE FLEXPORT */
   2356         flexport_get_flex_info(unit, flex_iter);
   2357         flexport_check_rate(unit, flexport_p->port_down_pbmp);
   2358         flexport_stop_traffic(unit, flexport_p->port_down_pbmp);
   2359         flexport_post_traffic_checks(unit, flexport_p->port_down_pbmp);
   2360         delete = 1;
   2361         flexport_setup_switch(unit, flexport_p->port_down_pbmp, delete);
   2362         flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2363 
   2364     /* ACTUAL FLEXPORT */
   2365         flexport_do_flexport(unit);
   2366 
   2367     /* AFTER FLEXPORT */
   2368         flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2369         flexport_set_port_arrays(unit, flexport_p->port_up_pbmp);
   2370         delete = 0;
   2371         flexport_setup_switch(unit, flexport_p->port_up_pbmp, delete);
   2372         flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2373         flexport_start_traffic(unit, flexport_p->port_up_pbmp);
   2374         flexport_start_rate_measurement(unit, flexport_p->port_up_pbmp);
   2375         cli_out("FINISH Flex Iteration SECTION=%s FLEX_ID=%0d\n", 
   2376                 flexport_p->tpl_section,
   2377                 flexport_p->flex_id_start_param + flexport_p->flex_iter);
   2378         cli_out("====================================================\n");
   2379         flexport_p->flex_iter++;
   2380     }
   2381 
   2382     /*===  AFTER flex LOOP  ===*/
   2383     flexport_check_rate(unit, PBMP_PORT_ALL(unit));
   2384     flexport_stop_traffic(unit, PBMP_PORT_ALL(unit));
   2385     flexport_post_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2386     flexport_pre_traffic_checks(unit, PBMP_PORT_ALL(unit));
   2387 
   2388     if (flexport_p->bad_input == 1) {
   2389         flexport_p->test_fail = 1;
   2390     }
   2391     if (flexport_p->test_fail == 1) {
   2392         rv = BCM_E_FAIL;
   2393     }
   2394 
   2395 done:
   2396     return rv;
   2397 }
   2398 
   2399 
   2400 /*
   2401  * Function:
   2402  *      flexport_test_cleanup
   2403  * Purpose:
   2404  *      Do test end checks and free all allocated memory.
   2405  * Parameters:
   2406  *      unit - StrataSwitch Unit #.
   2407  *      a - Pointer to arguments
   2408  *
   2409  * Returns:
   2410  *     SOC_E_XXXX
   2411  */
   2412 
   2413 int
   2414 flexport_th3_test_cleanup(int unit, void *pa)
   2415 {
   2416     flexport_t *flexport_p;
   2417     rate_calc_t *rate_calc_p;
   2418     int rv = BCM_E_NONE;
   2419     int num_flex_iterations, i;
   2420 
   2421     cli_out("\nCalling flexport_test_cleanup");
   2422 
   2423     flexport_p = flexport_parray[unit];
   2424 
   2425     if (flexport_p->linkscan_enable) {
   2426         cli_out("\nEnabling linkscan");
   2427         BCM_IF_ERROR_RETURN(bcm_linkscan_mode_set_pbm(unit, PBMP_PORT_ALL(unit),
   2428                                                       BCM_LINKSCAN_MODE_SW));
   2429         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 1));
   2430     }
   2431     if (flexport_p->counter_interval > 0) {
   2432         cli_out("\nEnabling counter collection with interval %0d", flexport_p->counter_interval);
   2433         BCM_IF_ERROR_RETURN(soc_counter_start(unit, flexport_p->counter_flags,
   2434                                                  flexport_p->counter_interval,
   2435                                                  PBMP_PORT_ALL(unit)));
   2436     }
   2437 
   2438     num_flex_iterations = flexport_p->flex_id_end_param
   2439                           - flexport_p->flex_id_start_param + 1;
   2440     for (i = 0; i < num_flex_iterations; i++) {
   2441         if (flexport_p->test_fail_iter[i] == 1) {
   2442             cli_out("**  FLEX_ID=%0d   FAILED **\n",
   2443                     flexport_p->flex_id_start_param + i);
   2444         }/* else {
   2445             cli_out("\n**  Flexport iteration %0d   PASSED **");
   2446         }*/
   2447     }
   2448 
   2449     if (flexport_p->test_fail == 1) {
   2450         rv = BCM_E_FAIL;
   2451         cli_out("\n**  Flexport test   FAILED SECTION=%s START_FLEX_ID=%0d**\n",
   2452                 flexport_p->tpl_section, flexport_p->flex_id_start_param);
   2453     } else {
   2454         cli_out("\n**  Flexport test  PASSED ** SECTION=%s START_FLEX_ID=%0d\n\n",
   2455                 flexport_p->tpl_section, flexport_p->flex_id_start_param);
   2456     }
   2457 
   2458     rate_calc_p = rate_calc_parray[unit];
   2459 
   2460     sal_free(flexport_p);
   2461     sal_free(rate_calc_p);
   2462     bcm_vlan_init(unit);
   2463 
   2464     cli_out("\n");
   2465 
   2466     return rv;
   2467 }
   2468 
   2469 #endif /*(BCM_ESW_SUPPORT) && \
   2470            (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \
   2471            !defined(NO_SAL_APPL) && (!defined(__KERNEL__)) */
   2472 #endif /* BCM_TOMAHAWK3_SUPPORT */