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.c (86907B)


      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  * config.bcm 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 performance 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  * Configuration parameters passed from CLI:
     30  * PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all
     31  *          ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes
     32  * FloodCnt: Number of packets in each swirl. Setting this to 0 will let the
     33  *           test calculate the number of packets that can be sent to achieve
     34  *           a lossless swirl at full rate. Set to 0 by default.
     35  * RateCalcInt: Interval in seconds over which rate is to be calculated
     36  * TolLr: Rate tolerance percentage for line rate ports (1% by default).
     37  * TolOv: Rate tolerance percentage for oversubscribed ports (3% by default).
     38  * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable
     39                 (default).
     40  * MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set
     41  *              to 0 for random.
     42  * LoopbackMode: Loopback mode. Set to 1 for MAC loopback, 2 for PHY loopback.
     43  *               (default is MAC loopback).
     44  * ConfigFile: Config files for each succession flexport operation.
     45  *             (default is none)
     46  * Tsc<num>: TSC to be flexed and port mode to flex to, e.g. Tsc5=4x10G.
     47  */
     48 
     49 #include <appl/diag/system.h>
     50 #include <shared/alloc.h>
     51 #include <shared/bsl.h>
     52 
     53 #include <soc/cm.h>
     54 #include <soc/dma.h>
     55 #include <soc/drv.h>
     56 #include <soc/dcb.h>
     57 #include <soc/cmicm.h>
     58 #include <soc/cmic.h>
     59 
     60 #include <sal/types.h>
     61 #include <appl/diag/parse.h>
     62 #include <bcm/port.h>
     63 #include <bcm/vlan.h>
     64 #include <bcm/link.h>
     65 
     66 #include "testlist.h"
     67 #include "gen_pkt.h"
     68 #include "streaming_lib.h"
     69 
     70 #define PKT_SIZE_PARAM_DEFAULT 0
     71 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0
     72 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10
     73 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 1
     74 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 3
     75 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1
     76 #define EMULATION_PARAM_DEFAULT 0
     77 #define MAX_NUM_CELLS_PARAM_DEFAULT 4
     78 #define NO_SPEED_CHANGE_PARAM_DEFAULT 1
     79 
     80 #define TCP_CMD_BUF_LEN 512
     81 
     82 #define MAC_DA {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}
     83 #define MAC_SA {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54}
     84 #define TPID 0x8100
     85 #define VLAN 0x0a00
     86 
     87 
     88 #if defined(BCM_ESW_SUPPORT) && \
     89            (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \
     90            !defined(NO_SAL_APPL) && (!defined(__KERNEL__))
     91 
     92 #include <unistd.h>
     93 #include <sys/socket.h>
     94 #include <netinet/in.h>
     95 #include <netdb.h>
     96 
     97 #define MAX_TSC_NUM 65
     98 
     99 /* TSC Info */
    100 #define TDMV_NUM_TSC(unit)       (SOC_IS_TOMAHAWK2(unit) ? 64 : 32)
    101 #define NUM_PORT_MODULES(unit)   (TDMV_NUM_TSC(unit) + 1)
    102 #define TDMV_NUM_TSC_LANES 4
    103 
    104 /* Encap types */
    105 #define PM_ENCAP__HIGIG2 999
    106 #define PM_ENCAP__ETHRNT 998
    107 
    108 enum port_state_e {
    109     PORT_STATE__DISABLED    = 0x0,
    110     PORT_STATE__LINERATE    = 0x1,
    111     PORT_STATE__OVERSUB     = 0x2,
    112     PORT_STATE__COMBINE     = 0x3,
    113     PORT_STATE__LINERATE_HG = 0x5,
    114     PORT_STATE__OVERSUB_HG  = 0x6,
    115     PORT_STATE__COMBINE_HG  = 0x7,
    116     PORT_STATE__MANAGEMENT  = 0x9,
    117     PORT_STATE__MUTABLE     = 0x11,
    118     PORT_STATE__CARDINAL    = 0x19
    119 };
    120 
    121 /* Speed set (Gbps) */
    122 typedef enum {
    123     SPEED_UI_0        = 0,
    124     SPEED_UI_1G       = 1,
    125     SPEED_UI_2p5G     = 2,
    126     SPEED_UI_10G      = 10,
    127     SPEED_UI_20G      = 20,
    128     SPEED_UI_21G_DUAL = 21,
    129     SPEED_UI_25G      = 25,
    130     SPEED_UI_40G      = 40,
    131     SPEED_UI_41G_DUAL = 41,
    132     SPEED_UI_42G      = 42,
    133     SPEED_UI_50G      = 50,
    134     SPEED_UI_100G     = 100,
    135     SPEED_UI_120G     = 120
    136 } port_speed_t;
    137 
    138 typedef struct flexport_s {
    139     pbmp_t vlan_pbmp;
    140     pbmp_t port_down_pbmp;
    141     pbmp_t port_up_pbmp;
    142     pbmp_t speed_change_pbmp;
    143     uint32 pkt_size_param;
    144     uint32 flood_pkt_cnt_param;
    145     uint32 rate_calc_interval_param;
    146     uint32 rate_tolerance_lr_param;
    147     uint32 rate_tolerance_ov_param;
    148     uint32 check_packet_integrity_param;
    149     uint32 emulation_param;
    150     char *server_name_param;
    151     uint32 socket_num_param;
    152     uint32 max_num_cells_param;
    153     uint32 loopback_mode_param;
    154     uint32 no_speed_change_param;
    155     uint32 init_tsc_shim;
    156     uint32 flex_by_command_line;
    157     char *config_file_name;
    158     char *tsc_param[MAX_TSC_NUM];
    159     uint32 num_del;
    160     uint32 num_add;
    161     bcm_port_resource_t del_resource[SOC_MAX_NUM_PORTS];
    162     bcm_port_resource_t add_resource[SOC_MAX_NUM_PORTS];
    163     int last_assigned_port[SOC_MAX_NUM_PIPES];
    164     int flex_tsc_map[MAX_TSC_NUM];
    165     int linkscan_enable;
    166     uint32 counter_flags;
    167     int counter_interval;
    168     pbmp_t counter_pbm;
    169     uint32 bad_input;
    170     uint32 test_fail;
    171     uint32 pkt_seed;
    172     int sockfd;
    173     char tsc_cfg_buffer[12][TCP_CMD_BUF_LEN];
    174     int tsc_cfg_cmds;
    175     int tsc_cfg_ptr;
    176     int clear_new_port_counts;
    177 } flexport_t;
    178 
    179 typedef struct rate_calc_s {
    180     uint32 ovs_ratio_x1000[SOC_MAX_NUM_PIPES];
    181     uint32 rand_pkt_sizes[SOC_MAX_NUM_PORTS][TARGET_CELL_COUNT];
    182     uint64 stime[SOC_MAX_NUM_PORTS];
    183     uint64 exp_rate[SOC_MAX_NUM_PORTS];
    184     uint64 tpkt_start[SOC_MAX_NUM_PORTS];
    185     uint64 tbyt_start[SOC_MAX_NUM_PORTS];
    186 } rate_calc_t;
    187 
    188 static flexport_t *flexport_parray[SOC_MAX_NUM_DEVICES];
    189 static rate_calc_t *rate_calc_parray[SOC_MAX_NUM_DEVICES];
    190 
    191 static const char flexport_test_usage[] =
    192 #ifdef COMPILER_STRING_CONST_LIMIT
    193     "\nDocumentation too long to be displayed with -pedantic compiler\n";
    194 #else
    195     "\nFlexPort test usage:\n"
    196     " \n"
    197     "PktSize:      Packet size in bytes. Set to 1 for random packet sizes.\n"
    198     "              Set to 0 (default) for worst case packet sizes on all ports\n"
    199     "              (145B for ENET, 76B for HG2).\n"
    200     "FloodCnt:     Number of packets in each swirl between.\n"
    201     "              Set to 0 (default) for a lossless swirl at full rate.\n"
    202     "RateCalcInt:  Interval in seconds over which rate is to be calculated.\n"
    203     "TolLr:        Rate tolerance percentage for line rate ports.\n"
    204     "              (1% by default)\n"
    205     "TolOv:        Rate tolerance percentage for oversubscribed ports.\n"
    206     "              (3% by default).\n"
    207     "ChkPktInteg:  Set to 0 to disable packet integrity checks.\n"
    208     "              Set to 1 to enable (default).\n"
    209     "Emulation:    Set to 1 to send TSC clock commands for emulation.\n"
    210     "              Set to 0 to disable (default).\n"
    211     "ServerName:   Name (Linux) or IP address (VxWorks) of the TSC clock server.\n"
    212     "              Required for emulation\n."
    213     "SocketNum:    Socket number of the TSC clock server.\n"
    214     "              Required for emulation\n."
    215     "MaxNumCells:  Maximum number of cells for random packet sizes.\n"
    216     "              Set to 0 for random cell sizes. (default is 4)\n"
    217     "LoopbackMode: Loopback mode. Set to 1 for MAC loopback, 2 for PHY loopback.\n"
    218     "              (default is MAC loopback)\n"
    219     "ConfigFile:   Config files for each succession flexport operation.\n"
    220     "              (default is none)\n"
    221     "Tsc<num>:     TSC to be flexed and port mode to flex to, e.g. Tsc5=4x10G\n"
    222     "              The supported mode/speed in Ethernet encapsulation are:\n"
    223     "NoSpeedChg:   Do not call the bcm_port_speed change. (default)\n"
    224     ;
    225 #endif
    226 
    227 static const char td2p_supported_mode[] =
    228     "              1x100G, 1x120G, 10x10G, 12x10G,\n"
    229     "              1x40G, 1x20G, 1x10G, 2x20G, 2x10G,\n"
    230     "              20G+2x10G, 2x10G+20G,\n"
    231     "              4x10G, 4x2.5G, and 4x1G\n"
    232     "              The supported mode/speed in HiGig2 encapsulation are:\n"
    233     "              1x106G, 1x127G, 10x11G, 12x11G,\n"
    234     "              1x42G, 1x21G, 1x11G, 2x21G, and 4x11G\n"
    235     ;
    236 
    237 static const char th2_supported_mode[] =
    238     "              1x100G, 1x40G\n"
    239     "              2x50G, 2x40G, 2x20G,\n"
    240     "              20G+2x10G, 2x10G+20G,\n"
    241     "              50G+2x25G, 2x25G+50G,\n"
    242     "              4x25G, and 4x10G\n"
    243     "              The supported mode/speed in HiGig2 encapsulation are:\n"
    244     "              1x106G, 1x42G,\n"
    245     "              2x53G, 2x42G, 2x21G,\n"
    246     "              4x27G, and 4x11G\n"
    247     ;
    248 
    249 static const char td3_supported_mode[] =
    250     "              1x100G, 1x40G\n"
    251     "              2x50G, 2x40G, 2x20G,\n"
    252     "              20G+2x10G, 2x10G+20G,\n"
    253     "              50G+2x25G, 2x25G+50G,\n"
    254     "              4x25G, 4x10G and 4x1G\n"
    255     "              The supported mode/speed in HiGig2 encapsulation are:\n"
    256     "              1x106G, 1x42G,\n"
    257     "              2x53G, 2x42G, 2x21G,\n"
    258     "              4x27G, and 4x11G\n"
    259     ;
    260 
    261 /*
    262  * Function:
    263  *      flexport_parse_test_params
    264  * Purpose:
    265  *      Parse CLI parameters, create test structure and flag bad inputs.
    266  * Parameters:
    267  *      unit - StrataSwitch Unit #.
    268  *      a - Pointer to arguments
    269  *
    270  * Returns:
    271  *     Nothing
    272  * Notes:
    273  *      flexport_p->bad_input set from here - tells test to crash out in case
    274  *      CLI input combination is invalid.
    275  */
    276 
    277 static void
    278 flexport_parse_test_params(int unit, args_t *a)
    279 {
    280     int i;
    281     parse_table_t parse_table;
    282     flexport_t *flexport_p = flexport_parray[unit];
    283 
    284     flexport_p->bad_input = 0;
    285 
    286     flexport_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT;
    287     flexport_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT;
    288     flexport_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT;
    289     flexport_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT;
    290     flexport_p->rate_tolerance_ov_param = RATE_TOLERANCE_OV_PARAM_DEFAULT;
    291     flexport_p->check_packet_integrity_param
    292                             = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT;
    293     flexport_p->emulation_param = EMULATION_PARAM_DEFAULT;
    294     flexport_p->socket_num_param = 0;
    295     flexport_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT;
    296     flexport_p->loopback_mode_param = BCM_PORT_LOOPBACK_MAC;
    297     flexport_p->no_speed_change_param = NO_SPEED_CHANGE_PARAM_DEFAULT;
    298     flexport_p->init_tsc_shim = 0;
    299     flexport_p->flex_by_command_line = 0;
    300     flexport_p->clear_new_port_counts = 0;
    301 
    302     /*Parse CLI opts */
    303 
    304     parse_table_init(unit, &parse_table);
    305     parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0,
    306                     &flexport_p->pkt_size_param, NULL);
    307     parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0,
    308                     &flexport_p->flood_pkt_cnt_param, NULL);
    309     parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0,
    310                     &flexport_p->rate_calc_interval_param, NULL);
    311     parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0,
    312                     &flexport_p->rate_tolerance_lr_param, NULL);
    313     parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0,
    314                     &flexport_p->rate_tolerance_ov_param, NULL);
    315     parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0,
    316                     &flexport_p->check_packet_integrity_param, NULL);
    317     parse_table_add(&parse_table, "Emulation", PQ_INT|PQ_DFL, 0,
    318                     &flexport_p->emulation_param, NULL);
    319     parse_table_add(&parse_table, "ServerName", PQ_STRING|PQ_DFL, 0,
    320                     &flexport_p->server_name_param, NULL);
    321     parse_table_add(&parse_table, "SocketNum", PQ_INT|PQ_DFL, 0,
    322                     &flexport_p->socket_num_param, NULL);
    323     parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0,
    324                     &flexport_p->max_num_cells_param, NULL);
    325     parse_table_add(&parse_table, "LoopbackMode", PQ_INT|PQ_DFL, 0,
    326                     &flexport_p->loopback_mode_param, NULL);
    327     parse_table_add(&parse_table, "ConfigFile", PQ_STRING|PQ_DFL, 0,
    328                     &flexport_p->config_file_name, NULL);
    329     parse_table_add(&parse_table, "Tsc0", PQ_STRING|PQ_DFL, 0,
    330                     &flexport_p->tsc_param[0], NULL);
    331     parse_table_add(&parse_table, "Tsc1", PQ_STRING|PQ_DFL, 0,
    332                     &flexport_p->tsc_param[1], NULL);
    333     parse_table_add(&parse_table, "Tsc2", PQ_STRING|PQ_DFL, 0,
    334                     &flexport_p->tsc_param[2], NULL);
    335     parse_table_add(&parse_table, "Tsc3", PQ_STRING|PQ_DFL, 0,
    336                     &flexport_p->tsc_param[3], NULL);
    337     parse_table_add(&parse_table, "Tsc4", PQ_STRING|PQ_DFL, 0,
    338                     &flexport_p->tsc_param[4], NULL);
    339     parse_table_add(&parse_table, "Tsc5", PQ_STRING|PQ_DFL, 0,
    340                     &flexport_p->tsc_param[5], NULL);
    341     parse_table_add(&parse_table, "Tsc6", PQ_STRING|PQ_DFL, 0,
    342                     &flexport_p->tsc_param[6], NULL);
    343     parse_table_add(&parse_table, "Tsc7", PQ_STRING|PQ_DFL, 0,
    344                     &flexport_p->tsc_param[7], NULL);
    345     parse_table_add(&parse_table, "Tsc8", PQ_STRING|PQ_DFL, 0,
    346                     &flexport_p->tsc_param[8], NULL);
    347     parse_table_add(&parse_table, "Tsc9", PQ_STRING|PQ_DFL, 0,
    348                     &flexport_p->tsc_param[9], NULL);
    349     parse_table_add(&parse_table, "Tsc10", PQ_STRING|PQ_DFL, 0,
    350                     &flexport_p->tsc_param[10], NULL);
    351     parse_table_add(&parse_table, "Tsc11", PQ_STRING|PQ_DFL, 0,
    352                     &flexport_p->tsc_param[11], NULL);
    353     parse_table_add(&parse_table, "Tsc12", PQ_STRING|PQ_DFL, 0,
    354                     &flexport_p->tsc_param[12], NULL);
    355     parse_table_add(&parse_table, "Tsc13", PQ_STRING|PQ_DFL, 0,
    356                     &flexport_p->tsc_param[13], NULL);
    357     parse_table_add(&parse_table, "Tsc14", PQ_STRING|PQ_DFL, 0,
    358                     &flexport_p->tsc_param[14], NULL);
    359     parse_table_add(&parse_table, "Tsc15", PQ_STRING|PQ_DFL, 0,
    360                     &flexport_p->tsc_param[15], NULL);
    361     parse_table_add(&parse_table, "Tsc16", PQ_STRING|PQ_DFL, 0,
    362                     &flexport_p->tsc_param[16], NULL);
    363     parse_table_add(&parse_table, "Tsc17", PQ_STRING|PQ_DFL, 0,
    364                     &flexport_p->tsc_param[17], NULL);
    365     parse_table_add(&parse_table, "Tsc18", PQ_STRING|PQ_DFL, 0,
    366                     &flexport_p->tsc_param[18], NULL);
    367     parse_table_add(&parse_table, "Tsc19", PQ_STRING|PQ_DFL, 0,
    368                     &flexport_p->tsc_param[19], NULL);
    369     parse_table_add(&parse_table, "Tsc20", PQ_STRING|PQ_DFL, 0,
    370                     &flexport_p->tsc_param[20], NULL);
    371     parse_table_add(&parse_table, "Tsc21", PQ_STRING|PQ_DFL, 0,
    372                     &flexport_p->tsc_param[21], NULL);
    373     parse_table_add(&parse_table, "Tsc22", PQ_STRING|PQ_DFL, 0,
    374                     &flexport_p->tsc_param[22], NULL);
    375     parse_table_add(&parse_table, "Tsc23", PQ_STRING|PQ_DFL, 0,
    376                     &flexport_p->tsc_param[23], NULL);
    377     parse_table_add(&parse_table, "Tsc24", PQ_STRING|PQ_DFL, 0,
    378                     &flexport_p->tsc_param[24], NULL);
    379     parse_table_add(&parse_table, "Tsc25", PQ_STRING|PQ_DFL, 0,
    380                     &flexport_p->tsc_param[25], NULL);
    381     parse_table_add(&parse_table, "Tsc26", PQ_STRING|PQ_DFL, 0,
    382                     &flexport_p->tsc_param[26], NULL);
    383     parse_table_add(&parse_table, "Tsc27", PQ_STRING|PQ_DFL, 0,
    384                     &flexport_p->tsc_param[27], NULL);
    385     parse_table_add(&parse_table, "Tsc28", PQ_STRING|PQ_DFL, 0,
    386                     &flexport_p->tsc_param[28], NULL);
    387     parse_table_add(&parse_table, "Tsc29", PQ_STRING|PQ_DFL, 0,
    388                     &flexport_p->tsc_param[29], NULL);
    389     parse_table_add(&parse_table, "Tsc30", PQ_STRING|PQ_DFL, 0,
    390                     &flexport_p->tsc_param[30], NULL);
    391     parse_table_add(&parse_table, "Tsc31", PQ_STRING|PQ_DFL, 0,
    392                     &flexport_p->tsc_param[31], NULL);
    393     parse_table_add(&parse_table, "Tsc32", PQ_STRING|PQ_DFL, 0,
    394                     &flexport_p->tsc_param[32], NULL);
    395     parse_table_add(&parse_table, "Tsc33", PQ_STRING|PQ_DFL, 0,
    396                     &flexport_p->tsc_param[33], NULL);
    397     parse_table_add(&parse_table, "Tsc34", PQ_STRING|PQ_DFL, 0,
    398                     &flexport_p->tsc_param[34], NULL);
    399     parse_table_add(&parse_table, "Tsc35", PQ_STRING|PQ_DFL, 0,
    400                     &flexport_p->tsc_param[35], NULL);
    401     parse_table_add(&parse_table, "Tsc36", PQ_STRING|PQ_DFL, 0,
    402                     &flexport_p->tsc_param[36], NULL);
    403     parse_table_add(&parse_table, "Tsc37", PQ_STRING|PQ_DFL, 0,
    404                     &flexport_p->tsc_param[37], NULL);
    405     parse_table_add(&parse_table, "Tsc38", PQ_STRING|PQ_DFL, 0,
    406                     &flexport_p->tsc_param[38], NULL);
    407     parse_table_add(&parse_table, "Tsc39", PQ_STRING|PQ_DFL, 0,
    408                     &flexport_p->tsc_param[39], NULL);
    409     parse_table_add(&parse_table, "Tsc40", PQ_STRING|PQ_DFL, 0,
    410                     &flexport_p->tsc_param[40], NULL);
    411     parse_table_add(&parse_table, "Tsc41", PQ_STRING|PQ_DFL, 0,
    412                     &flexport_p->tsc_param[41], NULL);
    413     parse_table_add(&parse_table, "Tsc42", PQ_STRING|PQ_DFL, 0,
    414                     &flexport_p->tsc_param[42], NULL);
    415     parse_table_add(&parse_table, "Tsc43", PQ_STRING|PQ_DFL, 0,
    416                     &flexport_p->tsc_param[43], NULL);
    417     parse_table_add(&parse_table, "Tsc44", PQ_STRING|PQ_DFL, 0,
    418                     &flexport_p->tsc_param[44], NULL);
    419     parse_table_add(&parse_table, "Tsc45", PQ_STRING|PQ_DFL, 0,
    420                     &flexport_p->tsc_param[45], NULL);
    421     parse_table_add(&parse_table, "Tsc46", PQ_STRING|PQ_DFL, 0,
    422                     &flexport_p->tsc_param[46], NULL);
    423     parse_table_add(&parse_table, "Tsc47", PQ_STRING|PQ_DFL, 0,
    424                     &flexport_p->tsc_param[47], NULL);
    425     parse_table_add(&parse_table, "Tsc48", PQ_STRING|PQ_DFL, 0,
    426                     &flexport_p->tsc_param[48], NULL);
    427     parse_table_add(&parse_table, "Tsc49", PQ_STRING|PQ_DFL, 0,
    428                     &flexport_p->tsc_param[49], NULL);
    429     parse_table_add(&parse_table, "Tsc50", PQ_STRING|PQ_DFL, 0,
    430                     &flexport_p->tsc_param[50], NULL);
    431     parse_table_add(&parse_table, "Tsc51", PQ_STRING|PQ_DFL, 0,
    432                     &flexport_p->tsc_param[51], NULL);
    433     parse_table_add(&parse_table, "Tsc52", PQ_STRING|PQ_DFL, 0,
    434                     &flexport_p->tsc_param[52], NULL);
    435     parse_table_add(&parse_table, "Tsc53", PQ_STRING|PQ_DFL, 0,
    436                     &flexport_p->tsc_param[53], NULL);
    437     parse_table_add(&parse_table, "Tsc54", PQ_STRING|PQ_DFL, 0,
    438                     &flexport_p->tsc_param[54], NULL);
    439     parse_table_add(&parse_table, "Tsc55", PQ_STRING|PQ_DFL, 0,
    440                     &flexport_p->tsc_param[55], NULL);
    441     parse_table_add(&parse_table, "Tsc56", PQ_STRING|PQ_DFL, 0,
    442                     &flexport_p->tsc_param[56], NULL);
    443     parse_table_add(&parse_table, "Tsc57", PQ_STRING|PQ_DFL, 0,
    444                     &flexport_p->tsc_param[57], NULL);
    445     parse_table_add(&parse_table, "Tsc58", PQ_STRING|PQ_DFL, 0,
    446                     &flexport_p->tsc_param[58], NULL);
    447     parse_table_add(&parse_table, "Tsc59", PQ_STRING|PQ_DFL, 0,
    448                     &flexport_p->tsc_param[59], NULL);
    449     parse_table_add(&parse_table, "Tsc60", PQ_STRING|PQ_DFL, 0,
    450                     &flexport_p->tsc_param[60], NULL);
    451     parse_table_add(&parse_table, "Tsc61", PQ_STRING|PQ_DFL, 0,
    452                     &flexport_p->tsc_param[61], NULL);
    453     parse_table_add(&parse_table, "Tsc62", PQ_STRING|PQ_DFL, 0,
    454                     &flexport_p->tsc_param[62], NULL);
    455     parse_table_add(&parse_table, "Tsc63", PQ_STRING|PQ_DFL, 0,
    456                     &flexport_p->tsc_param[63], NULL);
    457     parse_table_add(&parse_table, "NoSpeedChg", PQ_INT|PQ_DFL, 0,
    458                     &flexport_p->no_speed_change_param, NULL);
    459     parse_table_add(&parse_table, "InitTscShim", PQ_INT|PQ_DFL, 0,
    460                     &flexport_p->init_tsc_shim, NULL);
    461     parse_table_add(&parse_table, "ClrNewPortCounts", PQ_INT|PQ_DFL, 0,
    462                     &flexport_p->clear_new_port_counts, NULL);
    463 
    464     if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) {
    465         if (SOC_IS_TRIDENT2X(unit)) {
    466             cli_out("%s%s", flexport_test_usage, td2p_supported_mode);
    467         }
    468         if (SOC_IS_TOMAHAWK2(unit)) {
    469             cli_out("%s%s", flexport_test_usage, th2_supported_mode);
    470         }
    471         if (SOC_IS_TRIDENT3X(unit)) {
    472             cli_out("%s%s", flexport_test_usage, td3_supported_mode);
    473         }
    474         test_error(unit, "\n*ERROR PARSING ARGS\n");
    475     }
    476 
    477     cli_out("\n ------------- PRINTING TEST PARAMS ------------------");
    478     cli_out("\nPktSize      = %0d", flexport_p->pkt_size_param);
    479     cli_out("\nRateCalcInt  = %0d", flexport_p->rate_calc_interval_param);
    480     cli_out("\nFloodCnt     = %0d", flexport_p->flood_pkt_cnt_param);
    481     cli_out("\nTolLr        = %0d", flexport_p->rate_tolerance_lr_param);
    482     cli_out("\nTolOv        = %0d", flexport_p->rate_tolerance_ov_param);
    483     cli_out("\nChkPktInteg  = %0d", flexport_p->check_packet_integrity_param);
    484     cli_out("\nEmulation    = %0d", flexport_p->emulation_param);
    485     cli_out("\nMaxNumCells  = %0d", flexport_p->max_num_cells_param);
    486     cli_out("\nLoopbackMode = %0d", flexport_p->loopback_mode_param);
    487     cli_out("\nConfigFile   = %s",  flexport_p->config_file_name);
    488     cli_out("\nClrNewPortCounts   = %0d",  flexport_p->clear_new_port_counts);
    489     for (i = 0; i < MAX_TSC_NUM; i++) {
    490        if (flexport_p->tsc_param[i] != NULL) {
    491            cli_out("\nTsc%2d       = %s", i, flexport_p->tsc_param[i]);
    492            if(i >= TDMV_NUM_TSC(unit)) {
    493                flexport_p->bad_input = 1;
    494            }
    495            flexport_p->flex_by_command_line = 1;
    496        }
    497     }
    498     if (flexport_p->flex_by_command_line == 0) {
    499         cli_out("\nTsc<num>    = (null)");
    500     }
    501     cli_out("\nNoSpeeedChg   = %0d", flexport_p->no_speed_change_param);
    502     cli_out("\nInitTscShim   = %0d", flexport_p->init_tsc_shim);
    503     cli_out("\n -----------------------------------------------------");
    504 
    505     if (flexport_p->max_num_cells_param == 0) {
    506         /* coverity[dont_call : FALSE] */
    507         flexport_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1;
    508     }
    509 
    510     if (flexport_p->pkt_size_param == 0) {
    511       if(SOC_IS_TRIDENT3X(unit))
    512         cli_out
    513             ("\nUsing worst case packet sizes - 64B for Ethernet and HG2");
    514       else
    515         cli_out
    516             ("\nUsing worst case packet sizes - 145B for Ethernet and "
    517              "76B for HG2");
    518     } else if (flexport_p->pkt_size_param == 1) {
    519         cli_out("\nUsing random packet sizes");
    520     } else if (flexport_p->pkt_size_param < MIN_PKT_SIZE) {
    521         test_error(unit,"*ERROR: Packet size cannot be lower than %0dB\n",
    522                 MIN_PKT_SIZE);
    523         flexport_p->bad_input = 1;
    524     } else if (flexport_p->pkt_size_param > MTU) {
    525         test_error(unit,"*ERROR: Packet size higher than %0dB (Device MTU)\n",
    526                 MTU);
    527         flexport_p->bad_input = 1;
    528     }
    529 
    530     if (flexport_p->flood_pkt_cnt_param == 0) {
    531         cli_out("\nFloodCnt=0, automatically calculate number of packets to "
    532                 "flood each port");
    533     }
    534 
    535     if ((flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_MAC) &&
    536         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY) &&
    537         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY_REMOTE) &&
    538         (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_NONE)) {
    539         /*
    540          *   0 - no loopback; only to be used with chip external loopbacks.
    541          *   1 - MAC outer loopback.
    542          *   2 - PCS local loopback, close to PMD boundary.
    543          *   3 - PMD local loopback, close to AFE.
    544          */
    545         test_error(unit,"*ERROR: Loopback mode must be either 0, 1, 2 or 3\n");
    546         flexport_p->bad_input = 1;
    547     }
    548 
    549     if ((flexport_p->config_file_name != NULL &&
    550          flexport_p->flex_by_command_line != 0) ||
    551         (flexport_p->config_file_name == NULL &&
    552          flexport_p->flex_by_command_line == 0)) {
    553         test_error(unit,"*ERROR: Please specify ConfigFile or Tsc\n");
    554         flexport_p->bad_input = 1;
    555     }
    556 
    557     if (flexport_p->emulation_param &&
    558         (flexport_p->server_name_param == NULL ||
    559          flexport_p->socket_num_param == 0)) {
    560         test_error(unit,"*ERROR: ServerName and SocketNum must be specified\n");
    561         flexport_p->bad_input = 1;
    562     }
    563 
    564 }
    565 
    566 
    567 static int
    568 connectToSocket(int portno, char* serverName)
    569 {
    570     int sockfd;
    571     struct sockaddr_in serv_addr;
    572     struct hostent *server = NULL;
    573 
    574     sockfd = socket(AF_INET, SOCK_STREAM, 0);
    575     if (sockfd < 0) {
    576         cli_out("\nconnectToSocket : ERROR opening socket\n");
    577         return -1;
    578     }
    579     sal_memset((char *) &serv_addr, 0, sizeof(serv_addr));
    580 
    581     server = gethostbyname(serverName);
    582     if (server == NULL) {
    583         cli_out("\nconnectToSocket : ERROR no such host '%s'\n", serverName);
    584         close(sockfd);
    585         return -1;
    586     }
    587     sal_memcpy((char *) &serv_addr.sin_addr.s_addr, server->h_addr_list[0],
    588             server->h_length);
    589     serv_addr.sin_family = AF_INET;
    590     serv_addr.sin_port = htons(portno);
    591     if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
    592         cli_out("\nconnectToSocket : ERROR connecting\n");
    593         close(sockfd);
    594         return -1;
    595     } else {
    596         cli_out("\nconnectToSocket : Connected to '%s' %0d\n", serverName, portno);
    597     }
    598     return sockfd;
    599 }
    600 
    601 
    602 static bcm_error_t
    603 sendDataToSocket(int sockfd, char* msg)
    604 {
    605     int rv;
    606     rv = write(sockfd, msg, strlen(msg));
    607     if (rv < 0) {
    608          cli_out("\nsendDataToSocket : ERROR writing to socket\n");
    609          return -1;
    610     }
    611     cli_out("\nsendDataToSocket : %s \n", msg);
    612     return BCM_E_NONE;
    613 }
    614 
    615 
    616 /*
    617  * Function:
    618  *      tdm_chomp
    619  * Purpose:
    620  *      Removes newline from portmap strings
    621  * Parameters:
    622  *      str: Pointer to a string
    623  *
    624  * Returns:
    625  *     Nothing
    626  */
    627 
    628 static
    629 void tdm_chomp(char *str)
    630 {
    631     while (*str && *str != '\n' && *str != '\r') {
    632         str++;
    633     }
    634     *str = 0;
    635 }
    636 
    637 
    638 /*
    639  * Function:
    640  *      convert_hex2bin
    641  * Purpose:
    642  *      Converts hex string to 4-bit binary map
    643  * Parameters:
    644  *      str: single hex digit string
    645  *      bmp: 4 bit bitmap
    646  *
    647  * Returns:
    648  *     Nothing
    649  */
    650 
    651 static
    652 void convert_hex2bin(char str, unsigned char bmp[4]){
    653     char str_tmp[2];
    654     long num;
    655     str_tmp[0]=str; str_tmp[1]='\0';
    656     num = strtol(str_tmp, NULL, 16);
    657 
    658     switch(num){
    659         case 0:
    660                 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=0;
    661                 break;
    662         case 1:
    663                 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=1;
    664                 break;
    665         case 2:
    666                 bmp[3]=0; bmp[2]=0; bmp[1]=1; bmp[0]=0;
    667                 break;
    668         case 3:
    669                 bmp[3]=0; bmp[2]=0; bmp[1]=1; bmp[0]=1;
    670                 break;
    671         case 4:
    672                 bmp[3]=0; bmp[2]=1; bmp[1]=0; bmp[0]=0;
    673                 break;
    674         case 5:
    675                 bmp[3]=0; bmp[2]=1; bmp[1]=0; bmp[0]=1;
    676                 break;
    677         case 6:
    678                 bmp[3]=0; bmp[2]=1; bmp[1]=1; bmp[0]=0;
    679                 break;
    680         case 7:
    681                 bmp[3]=0; bmp[2]=1; bmp[1]=1; bmp[0]=1;
    682                 break;
    683         case 8:
    684                 bmp[3]=1; bmp[2]=0; bmp[1]=0; bmp[0]=0;
    685                 break;
    686         case 9:
    687                 bmp[3]=1; bmp[2]=0; bmp[1]=0; bmp[0]=1;
    688                 break;
    689         case 0xa:
    690                 bmp[3]=1; bmp[2]=0; bmp[1]=1; bmp[0]=0;
    691                 break;
    692         case 0xb:
    693                 bmp[3]=1; bmp[2]=0; bmp[1]=1; bmp[0]=1;
    694                 break;
    695         case 0xc:
    696                 bmp[3]=1; bmp[2]=1; bmp[1]=0; bmp[0]=0;
    697                 break;
    698         case 0xd:
    699                 bmp[3]=1; bmp[2]=1; bmp[1]=0; bmp[0]=1;
    700                 break;
    701         case 0xe:
    702                 bmp[3]=1; bmp[2]=1; bmp[1]=1; bmp[0]=0;
    703                 break;
    704         case 0xf:
    705                 bmp[3]=1; bmp[2]=1; bmp[1]=1; bmp[0]=1;
    706                 break;
    707         default:
    708                 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=0;
    709                 break;
    710     }
    711 }
    712 
    713 
    714 /*
    715  * Function:
    716  *      get_lanes
    717  * Purpose:
    718  *      Converts hex string to 4-bit binary map
    719  * Parameters:
    720  *      unit - StrataSwitch Unit #.
    721  *      num_subport: number of subports
    722  *      speed: pointer to a port speed array
    723  *      lanes: pointer to a lane array
    724  *
    725  * Returns:
    726  *     Nothing
    727  */
    728 
    729 static void
    730 get_lanes(int unit, int num_subport, int *speed, int *lanes)
    731 {
    732     int i;
    733 
    734     for (i = 0; i < num_subport; i++) {
    735         switch(speed[i]) {
    736             case   1000 : lanes[i] = 1; break;
    737             case  10000 : lanes[i] = 1; break;
    738             case  20000 : lanes[i] = 2; break;
    739             case  25000 : lanes[i] = 1; break;
    740             case  40000 : lanes[i] = ((i==0) && (speed[2] == 0))? 4 : 2; break;
    741             case  50000 : lanes[i] = 2; break;
    742             case 100000 : lanes[i] = ((i==0) && (SOC_IS_TRIDENT2X(unit))) ?
    743                                                       10 : 4; break;
    744             default     : lanes[i] = 0; break;
    745         }
    746     }
    747 }
    748 
    749 
    750 static void
    751 get_per_pipe_log_port_range(int unit, int pport,
    752               int *log_start, int *log_end, int *pipe) {
    753 
    754     if(SOC_IS_TOMAHAWK2(unit)) {
    755         *pipe = (pport - 1) / 64;
    756         *log_start = (*pipe) * 34;
    757         *log_end = (*pipe) * 34 + 34 - 1;
    758     } else {
    759         *pipe = 0;
    760         *log_start = 0;
    761         *log_end = SOC_MAX_NUM_PORTS;
    762     }
    763 }
    764 
    765 /*
    766  * Function:
    767  *      get_logical_port_no
    768  * Purpose:
    769  *      assign logical port number for physical port
    770  * Parameters:
    771  *      unit - StrataSwitch Unit #.
    772  *      pport: physical port number
    773  *
    774  * Returns:
    775  *      logical port number
    776  */
    777 static int
    778 get_logical_port_no(int unit, int pport){
    779     soc_info_t *si;
    780     int l, lport;
    781     int lstart, lend, pipe;
    782     flexport_t *flexport_p = flexport_parray[unit];
    783 
    784     si = &SOC_INFO(unit);
    785     lport = -1;
    786     get_per_pipe_log_port_range(unit, pport, &lstart, &lend, &pipe);
    787 
    788   if(SOC_IS_TRIDENT3X(unit)) {
    789     lport = (pport > 64) ? (2 + pport) : (pport);
    790   } else {
    791     if(flexport_p->last_assigned_port[pipe] == -1) {
    792 	    flexport_p->last_assigned_port[pipe] = lstart;
    793     }
    794 
    795     for (l = (flexport_p->last_assigned_port[pipe] + 1);
    796          l <= lend && l < SOC_MAX_NUM_PORTS; l++) {
    797         if(si->port_l2p_mapping[l] == -1) {
    798             flexport_p->last_assigned_port[pipe] = l;
    799             lport = l;
    800             LOG_INFO(BSL_LS_APPL_TESTS,
    801                      (BSL_META_U(unit, "\nAssigned logical port")));
    802             LOG_INFO(BSL_LS_APPL_TESTS,
    803                      (BSL_META_U(unit, " %0d to physical port %0d"),
    804                                  l, pport));
    805             break;
    806         }
    807     }
    808   }
    809   return lport;
    810 }
    811 
    812 static int
    813 config_tsc_shim(int unit, int tsc_num, int num_subport, int *speed, int encap)
    814 {
    815   int i, lane_speed = 0, vco_sel = 0, higig = 0, tsc_lane_mode = 0;
    816   int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    817   int update_tscf = 0;
    818   char buffer[TCP_CMD_BUF_LEN];
    819   flexport_t *flexport_p = flexport_parray[unit];
    820 
    821   get_lanes(unit, num_subport, speed, lanes);
    822   for(i = 0; i < num_subport; i++) {
    823     if(speed[i] > 0) {
    824       update_tscf = 1;
    825       switch (speed[i]) {
    826         case 100000:
    827             lane_speed = 12; vco_sel = 1; tsc_lane_mode =  1;
    828             update_tscf = 1;
    829             break;
    830         case  50000:
    831             lane_speed = 12; vco_sel = 1; tsc_lane_mode =  5;
    832             update_tscf = 1;
    833             break;
    834         case  40000:
    835             lane_speed = (lanes[i] == 4) ? 5 : 10;
    836             vco_sel = 0;
    837             tsc_lane_mode =  (lanes[i] == 4) ? 1 : 5;
    838             update_tscf = 1;
    839             break;
    840         case  25000:
    841             lane_speed = 12; vco_sel = 1; tsc_lane_mode = 15;
    842             update_tscf = 1;
    843              break;
    844         case  20000:
    845             lane_speed =  5; vco_sel = 0; tsc_lane_mode =  5;
    846             update_tscf = 1;
    847             break;
    848         case  10000:
    849             lane_speed =  5; vco_sel = 0; tsc_lane_mode = 15;
    850             update_tscf = 1;
    851             break;
    852         default:
    853             test_error(unit, "*ERROR: Speed %0dG is not supported\n",
    854                        speed[i] / 1000);
    855             break;
    856       }
    857       sal_memset(buffer, 0, TCP_CMD_BUF_LEN);
    858       sprintf(buffer, "config_tscf_lane TscNum %0d LaneNum %0d LaneSpeed %0d\n",
    859              tsc_num, i, lane_speed);
    860       sal_strcpy(flexport_p->tsc_cfg_buffer[flexport_p->tsc_cfg_ptr++], buffer);
    861       flexport_p->tsc_cfg_cmds = 1;
    862     }
    863   }
    864 
    865   higig = (encap == BCM_PORT_ENCAP_HIGIG2) ? 1 : 0;
    866   /* Now, correct the TSC lane mode if the port macro is configured */
    867   /* as a tri-port. */
    868   if ((speed[0] > 0) && (speed[0] == speed[1]) && (speed[0] != speed[2])) {
    869           tsc_lane_mode = 7;
    870   }
    871   if ((speed[2] > 0) && (speed[2] == speed[3]) && (speed[0] != speed[2])) {
    872           tsc_lane_mode = 13;
    873   }
    874 
    875   if (update_tscf) {
    876       sal_memset(buffer, 0, TCP_CMD_BUF_LEN);
    877       sprintf(buffer, "config_tscf TscNum %0d VcoSel %0d Higig %0d TscLaneMode %0d HddcNum %0d\n",
    878               tsc_num, vco_sel, higig, tsc_lane_mode, tsc_num);
    879       sal_strcpy(flexport_p->tsc_cfg_buffer[flexport_p->tsc_cfg_ptr++], buffer);
    880       flexport_p->tsc_cfg_cmds = 1;
    881   }
    882 
    883   for (i = 0; i < 12; i++) {
    884       if (flexport_p->tsc_cfg_buffer[i][0] != '\0') {
    885           if (BCM_E_NONE != sendDataToSocket(flexport_p->sockfd,
    886                                 flexport_p->tsc_cfg_buffer[i])) {
    887               return BCM_E_INTERNAL;
    888           }
    889           sal_memset(flexport_p->tsc_cfg_buffer[i], 0, TCP_CMD_BUF_LEN);
    890       }
    891   }
    892   flexport_p->tsc_cfg_cmds = 0;
    893   flexport_p->tsc_cfg_ptr = 0;
    894 
    895   return BCM_E_NONE;
    896 }
    897 
    898 /*
    899  * Function:
    900  *      flex_tsc
    901  * Purpose:
    902  *      Prepare speed_change_pbmp, port_down_pbmp, port_up_pbmp for one TSC
    903  * Parameters:
    904  *      unit - StrataSwitch Unit #.
    905  *      num_subport: number of subports
    906  *      first_phy_port: first physical port number of the TSC
    907  *      encap: Ethernet or HiGig2
    908  *
    909  * Returns:
    910  *     SOC_E_XXXX
    911  */
    912 
    913 static bcm_error_t
    914 flex_tsc(int unit, int num_subport, int first_phy_port, int *speed, int encap)
    915 {
    916     soc_info_t *si;
    917     flexport_t *flexport_p = flexport_parray[unit];
    918     int i;
    919     int cur_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    920     int cur_lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    921     int cur_encap = BCM_PORT_ENCAP_IEEE;
    922     int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    923     int lanes_changed = 0;
    924     int exact_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    925     bcm_port_t lport, pport;
    926     int rv;
    927 
    928     si = &SOC_INFO(unit);
    929 
    930     LOG_INFO(BSL_LS_APPL_TESTS,
    931              (BSL_META_U(unit, "\nFlexing port %0d..%0d to"),
    932              first_phy_port, first_phy_port + num_subport - 1));
    933     for (i = 0; i < num_subport; i++) {
    934         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " %0dG"), speed[i] / 1000));
    935     }
    936     if (encap == BCM_PORT_ENCAP_IEEE) {
    937         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " Ethernet")));
    938     } else if (encap == BCM_PORT_ENCAP_HIGIG2) {
    939         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " Higig2")));
    940     }
    941 
    942     lport = si->port_p2l_mapping[first_phy_port];
    943     if (lport != -1 && IS_HG2_ENABLED_PORT(unit, lport)) {
    944         cur_encap = BCM_PORT_ENCAP_HIGIG2;
    945     }
    946 
    947     for (i = 0; i < num_subport; i++) {
    948         pport = first_phy_port + i;
    949         lport = si->port_p2l_mapping[pport];
    950         if (lport != -1) {
    951             rv = bcm_port_speed_get(unit, lport, &cur_speed[i]);
    952             if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
    953                 cli_out("\nbcm_port_speed_get %0d %0d: %s",
    954                         lport, rv, bcm_errmsg(rv));
    955                 return rv;
    956             }
    957         }
    958     }
    959 
    960     get_lanes(unit, num_subport, cur_speed, cur_lanes);
    961     get_lanes(unit, num_subport, speed, lanes);
    962     for (i = 0; i < num_subport; i++) {
    963         if (lanes[i] != cur_lanes[i]) {
    964             lanes_changed = 1;
    965             break;
    966         }
    967     }
    968 
    969     if (lanes_changed == 0 && encap == cur_encap &&
    970         flexport_p->no_speed_change_param == 0) {
    971         for (i = 0; i < num_subport; i++) {
    972             exact_speed[i] = stream_get_exact_speed(speed[i], encap);
    973             if (exact_speed[i] != cur_speed[i]) {
    974                 pport = first_phy_port + i;
    975                 lport = si->port_p2l_mapping[pport];
    976                 LOG_INFO(BSL_LS_APPL_TESTS,
    977                          (BSL_META_U(unit, "\nChanging port %0d from %0d G to %0d G"),
    978                                             pport, cur_speed[i] / 1000,
    979                                             exact_speed[i] / 1000));
    980                 rv = bcm_port_speed_set(unit, lport, exact_speed[i]);
    981                 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
    982                     cli_out("\nbcm_port_speed_set %0d %0d: %s",
    983                             lport, exact_speed[i], bcm_errmsg(rv));
    984                     return rv;
    985                 }
    986                 SOC_PBMP_PORT_ADD(flexport_p->speed_change_pbmp, lport);
    987             }
    988         }
    989         return BCM_E_NONE;
    990     }
    991 
    992     for (i = 0; i < num_subport; i++) {
    993         pport = first_phy_port + i;
    994         lport = si->port_p2l_mapping[pport];
    995         if (lport != -1) {
    996             exact_speed[i] = stream_get_exact_speed(speed[i], encap);
    997             if (cur_speed[i] > 0 &&
    998                 (exact_speed[i] != cur_speed[i] || encap != cur_encap ||
    999                  lanes[i] != cur_lanes[i])) {
   1000                 LOG_INFO(BSL_LS_APPL_TESTS,
   1001                          (BSL_META_U(unit, "\nRemoving %0d G port %0d"),
   1002                                      cur_speed[i] / 1000, pport));
   1003                 bcm_port_resource_t_init(
   1004                     &flexport_p->del_resource[flexport_p->num_del]);
   1005                 flexport_p->del_resource[flexport_p->num_del].physical_port = -1;
   1006                 flexport_p->del_resource[flexport_p->num_del].port = lport;
   1007                 flexport_p->num_del++;
   1008                 SOC_PBMP_PORT_ADD(flexport_p->port_down_pbmp, lport);
   1009             }
   1010         }
   1011     }
   1012 
   1013     for (i = 0; i < num_subport; i++) {
   1014         exact_speed[i] = stream_get_exact_speed(speed[i], encap);
   1015         if (speed[i] > 0 &&
   1016             (exact_speed[i] != cur_speed[i] || encap != cur_encap ||
   1017              lanes[i] != cur_lanes[i])) {
   1018             pport = first_phy_port + i;
   1019             lport = get_logical_port_no(unit, pport);
   1020             if(lport == -1) {
   1021                 cli_out("\nERROR : Unable to find valid logical port for"
   1022                                               " physical port %0d", pport);
   1023                 return BCM_E_INTERNAL;
   1024             }
   1025             bcm_port_resource_t_init(
   1026                 &flexport_p->add_resource[flexport_p->num_add]);
   1027             LOG_INFO(BSL_LS_APPL_TESTS,
   1028                      (BSL_META_U(unit, "\nAdding %0d G port %0d lane %0d"),
   1029                                  exact_speed[i] / 1000, pport, lanes[i]));
   1030             flexport_p->add_resource[flexport_p->num_add].physical_port = pport;
   1031             flexport_p->add_resource[flexport_p->num_add].port  = lport;
   1032             flexport_p->add_resource[flexport_p->num_add].speed = exact_speed[i];
   1033             flexport_p->add_resource[flexport_p->num_add].lanes = lanes[i];
   1034             flexport_p->add_resource[flexport_p->num_add].encap = encap;
   1035             flexport_p->num_add++;
   1036             SOC_PBMP_PORT_ADD(flexport_p->port_up_pbmp, lport);
   1037         }
   1038     }
   1039     flexport_p->flex_tsc_map[(first_phy_port - 1) / num_subport] = 1;
   1040 
   1041     return BCM_E_NONE;
   1042 }
   1043 
   1044 
   1045 /*
   1046  * Function:
   1047  *      flexport_call_bcm_api
   1048  * Purpose:
   1049  *      Call the bcm_port_resource_multi_set API
   1050  * Parameters:
   1051  *      unit - StrataSwitch Unit #.
   1052  *
   1053  * Returns:
   1054  *     SOC_E_XXXX
   1055  */
   1056 
   1057 static bcm_error_t
   1058 flexport_call_bcm_api(int unit)
   1059 {
   1060     flexport_t *flexport_p = flexport_parray[unit];
   1061     int i;
   1062     bcm_port_t lport;
   1063     uint32 nports;
   1064     bcm_port_resource_t *resource;
   1065     bcm_error_t rv;
   1066 
   1067     nports = flexport_p->num_del + flexport_p->num_add;
   1068     resource = (bcm_port_resource_t *) sal_alloc(nports *
   1069                                                  sizeof(bcm_port_resource_t),
   1070                                                  "flexport_resource_array");
   1071     sal_memset(resource, 0, sizeof(bcm_port_resource_t));
   1072 
   1073     for (i = 0; i < flexport_p->num_del; i ++) {
   1074         resource[i] = flexport_p->del_resource[i];
   1075     }
   1076     for (i = 0; i < flexport_p->num_add; i ++) {
   1077         resource[flexport_p->num_del + i] = flexport_p->add_resource[i];
   1078     }
   1079 
   1080     PBMP_ITER(flexport_p->port_down_pbmp, lport) {
   1081         if (lport < SOC_MAX_NUM_PORTS) {
   1082             rv = bcm_port_enable_set(unit, lport, 0);
   1083             if (BCM_FAILURE(rv)) {
   1084                 cli_out("\nbcm_port_disable_set %0d: %s", lport, bcm_errmsg(rv));
   1085                 sal_free(resource);
   1086                 return rv;
   1087             }
   1088         }
   1089     }
   1090 
   1091     LOG_INFO(BSL_LS_APPL_TESTS,
   1092              (BSL_META_U(unit, "\nCalling bcm_port_resource_multi:")));
   1093     for (i = 0; i < nports; i ++) {
   1094         LOG_INFO(BSL_LS_APPL_TESTS,
   1095                  (BSL_META_U(unit, "\nresource[%0d]: physical_port = %0d"),
   1096                              i, resource[i].physical_port));
   1097         LOG_INFO(BSL_LS_APPL_TESTS,
   1098                  (BSL_META_U(unit, "\nresource[%0d]: port  = %0d"),
   1099                              i, resource[i].port));
   1100         LOG_INFO(BSL_LS_APPL_TESTS,
   1101                  (BSL_META_U(unit, "\nresource[%0d]: speed = %0d"),
   1102                              i, resource[i].speed));
   1103         LOG_INFO(BSL_LS_APPL_TESTS,
   1104                  (BSL_META_U(unit, "\nresource[%0d]: lanes = %0d"),
   1105                              i, resource[i].lanes));
   1106         LOG_INFO(BSL_LS_APPL_TESTS,
   1107                  (BSL_META_U(unit, "\nresource[%0d]: encap = %0d"),
   1108                              i, resource[i].encap));
   1109     }
   1110     rv = bcm_port_resource_multi_set(unit, nports, resource);
   1111     if (BCM_FAILURE(rv)) {
   1112         cli_out("\nbcm_port_resource_multi_set: %s", bcm_errmsg(rv));
   1113         sal_free(resource);
   1114         return rv;
   1115     }
   1116 
   1117     cli_out("\nWait 20s for TSC configuration changes to take effect\n");
   1118     sal_sleep(20);
   1119 
   1120     PBMP_ITER(flexport_p->port_up_pbmp, lport) {
   1121         if (lport < SOC_MAX_NUM_PORTS) {
   1122             rv = bcm_port_enable_set(unit, lport, 1);
   1123             if (BCM_FAILURE(rv)) {
   1124                 cli_out("\nbcm_port_enable_set %0d: %s", lport, bcm_errmsg(rv));
   1125                 sal_free(resource);
   1126                 return rv;
   1127             }
   1128         }
   1129     }
   1130 
   1131     sal_free(resource);
   1132 
   1133     return BCM_E_NONE;
   1134 }
   1135 
   1136 /*
   1137  * Function:
   1138  *      flexport_by_config_file
   1139  * Purpose:
   1140  *      Load a BCM config file and flex accordingly
   1141  * Parameters:
   1142  *      unit: StrataSwitch Unit #.
   1143  *      fname: filename of the bcm config file
   1144  *
   1145  * Returns:
   1146  *     BCM_E_XXXX
   1147  */
   1148 
   1149 static bcm_error_t
   1150 flexport_by_config_file(int unit, char *fname)
   1151 {
   1152     int port_speed;
   1153     int *port_speeds;
   1154     int *port_states;
   1155     int traffic[MAX_TSC_NUM];
   1156     char line[256], line_cpy1[256], line_cpy2[32], line_cpy3[32];
   1157     char *port_str[32], *port_data[32], *l2p_str[16];
   1158     char *split1 = NULL, *split2 = NULL, *split3 = NULL;
   1159     const char *dic_portmap, *dic_pbmp_xe, *dic_pbmp_os, *dic_dev_bw;
   1160     const char *dic_higig;
   1161     int i, j, port_idx, l2p_idx, port_lgcID, port_data_idx, tmp_port, tmp_speed;
   1162     int port_phyID, highest_lgcID = 0, clk_freq, lgc_2_phy_portmap[SOC_MAX_NUM_PORTS];
   1163     int port_lanenum = 0;
   1164     unsigned char os_bmp[SOC_MAX_NUM_PORTS], xe_bmp[SOC_MAX_NUM_PORTS],
   1165                   bmp_4bit[4];
   1166     long int hg_bmp=0;
   1167     FILE *fp;
   1168     soc_info_t *si;
   1169     int p;
   1170     char eth_hig_str[3], line_ovsb_str[4];
   1171     int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1172     int encap;
   1173     int num_subport;
   1174     int rv = BCM_E_NONE;
   1175 
   1176     port_speeds = (int *) sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS,
   1177                                     "port_speeds");
   1178     port_states = (int *) sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS,
   1179                                     "port_states");
   1180     sal_memset(port_speeds, 0, sizeof(int) * SOC_MAX_NUM_PORTS);
   1181     sal_memset(port_states, 0, sizeof(int) * SOC_MAX_NUM_PORTS);
   1182 
   1183     si = &SOC_INFO(unit);
   1184     cli_out("\nCurrent bcm config:");
   1185     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
   1186         if (p < SOC_MAX_NUM_PORTS) {
   1187             bcm_port_speed_get(unit, p, &port_speed);
   1188             if (SOC_PBMP_MEMBER(PBMP_E_ALL(unit), p)) {
   1189                 sal_sprintf(eth_hig_str, "ETH");
   1190             } else {
   1191                 sal_sprintf(eth_hig_str, "HG2");
   1192             }
   1193             if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), p)) {
   1194                 sal_sprintf(line_ovsb_str, "OVSB");
   1195             } else {
   1196                 sal_sprintf(line_ovsb_str, "LINE");
   1197             }
   1198             cli_out("\nDev Port %3d, Phy Port %3d, %3d G %s %s",
   1199                     p, si->port_l2p_mapping[p], port_speed / 1000,
   1200                     eth_hig_str, line_ovsb_str);
   1201         }
   1202     }
   1203 
   1204     /* Open bcm config file */
   1205     fp = sal_fopen(fname, "r");
   1206     if (fp == NULL) {
   1207         test_error(unit, "*ERROR: Cannot open bcm config file: '%s'\n", fname);
   1208         rv = BCM_E_FAIL;
   1209         goto done;
   1210     } else {
   1211         cli_out("\nLoading bcm config file: '%s'", fname);
   1212     }
   1213 
   1214     /* Dictionary */
   1215     dic_portmap = "portmap_";
   1216     dic_pbmp_xe = "pbmp_xport_xe";
   1217     dic_pbmp_os = "pbmp_oversubscribe";
   1218     dic_dev_bw  = "device_bandwidth";
   1219     dic_higig   = "bmp_higig";
   1220 
   1221     /* Initialize parameters */
   1222     for (i=0; i < SOC_MAX_NUM_PORTS; i++) { port_states[i] = 0; }
   1223     for (i=1; i < SOC_MAX_NUM_PORTS; i++) { port_speeds[i] = SPEED_UI_0; }
   1224     port_speeds[0] = SPEED_UI_10G; port_speeds[129] = SPEED_UI_1G;
   1225     for (i=0; i < MAX_TSC_NUM; i++) { traffic[i] = PM_ENCAP__ETHRNT; }
   1226     for (i=0; i < SOC_MAX_NUM_PORTS; i++) { lgc_2_phy_portmap[i] = 9999; }
   1227     for (i=0; i < SOC_MAX_NUM_PORTS; i++) { os_bmp[i] = 0; xe_bmp[i] = 0; }
   1228 
   1229     while (sal_fgets(line, sizeof(line), fp)) {
   1230         if (sal_strstr(line, "#") != line) {
   1231             if (sal_strlen(line) > 256) {
   1232                 sal_fclose(fp);
   1233                 rv = BCM_E_FAIL;
   1234                 goto done;
   1235             }
   1236             sal_strcpy(line_cpy1, line);
   1237             split1 = sal_strtok(line_cpy1,"=");
   1238             port_idx = 0;
   1239             while (split1) {
   1240                 port_str[port_idx++] = split1;
   1241                 split1 = sal_strtok(NULL,"=");
   1242             }
   1243             tdm_chomp(port_str[1]);
   1244             if (sal_strstr(line, dic_portmap)) {
   1245                 if (sal_strlen(port_str[1]) > 32) {
   1246                     sal_fclose(fp);
   1247                     rv = BCM_E_FAIL;
   1248                     goto done;
   1249                 }
   1250                 sal_strcpy(line_cpy2, port_str[1]);
   1251                 split2 = sal_strtok(line_cpy2,":");
   1252                 port_data_idx = 0;
   1253                 while (split2) {
   1254                     port_data[port_data_idx++] = split2;
   1255                     split2 = sal_strtok(NULL,":");
   1256                 }
   1257                 tmp_port = sal_atoi(port_data[0]);
   1258                 tmp_speed = sal_atoi(port_data[1]);
   1259                 if (tmp_port<129 && tmp_port>0) {
   1260                     port_speeds[tmp_port] = tmp_speed;
   1261                     port_states[tmp_port-1] = 9;
   1262                 }
   1263                 if (sal_strlen(port_str[0]) > 32) {
   1264                     sal_fclose(fp);
   1265                     rv = BCM_E_FAIL;
   1266                     goto done;
   1267                 }
   1268                 sal_strcpy(line_cpy3, port_str[0]);
   1269                 split3 = sal_strtok(line_cpy3,"_");
   1270                 l2p_idx = 0;
   1271                 while (split3) {
   1272                     l2p_str[l2p_idx++] = split3;
   1273                     split3 = sal_strtok(NULL,"_");
   1274                 }
   1275                 port_lgcID = sal_atoi(l2p_str[1]);
   1276                 if (port_lgcID > 0 && port_lgcID < SOC_MAX_NUM_PORTS) {
   1277                     lgc_2_phy_portmap[port_lgcID] = tmp_port;
   1278                     highest_lgcID = (port_lgcID>highest_lgcID) ?
   1279                                     (port_lgcID) : (highest_lgcID);
   1280                 }
   1281             }
   1282             if (sal_strstr(line, dic_dev_bw)) {
   1283                 clk_freq = sal_atoi(port_str[1]);
   1284                 clk_freq /= 1000;
   1285                 /* Check clock frequency */
   1286                 if (clk_freq != si->frequency) {
   1287                     test_error(unit, "*ERROR: Cannot change freq from %0d to %0d\n",
   1288                                       si->frequency, clk_freq);
   1289                 }
   1290             }
   1291             if (sal_strstr(line, dic_pbmp_xe)) {
   1292                 if (sal_strlen(port_str[1]) > 32) {
   1293                     sal_fclose(fp);
   1294                     rv = BCM_E_FAIL;
   1295                     goto done;
   1296                 }
   1297                 sal_strcpy(line_cpy2, port_str[1]);
   1298                 split2 = sal_strtok(line_cpy2,"x");
   1299                 port_data_idx=0;
   1300                 while (split2) {
   1301                     port_data[port_data_idx++] = split2;
   1302                     split2 = sal_strtok(NULL,"x");
   1303                 }
   1304                 /* Potentially 128 bit, so cannot just strtol entire string */
   1305                 j = 0;
   1306                 for (i = (strlen(port_data[1])-1); i >= 0; i--) {
   1307                     if ((j * 4 + 3) < SOC_MAX_NUM_PORTS) {
   1308                         convert_hex2bin(port_data[1][i], bmp_4bit);
   1309                         xe_bmp[j * 4    ] = bmp_4bit[0];
   1310                         xe_bmp[j * 4 + 1] = bmp_4bit[1];
   1311                         xe_bmp[j * 4 + 2] = bmp_4bit[2];
   1312                         xe_bmp[j * 4 + 3] = bmp_4bit[3];
   1313                         j++;
   1314                     }
   1315                 }
   1316             }
   1317             if (sal_strstr(line, dic_pbmp_os)) {
   1318                 if (sal_strlen(port_str[1]) > 32) {
   1319                     sal_fclose(fp);
   1320                     rv = BCM_E_FAIL;
   1321                     goto done;
   1322                 }
   1323                 sal_strcpy(line_cpy2, port_str[1]);
   1324                 split2 = sal_strtok(line_cpy2, "x");
   1325                 port_data_idx = 0;
   1326                 while (split2) {
   1327                     port_data[port_data_idx++] = split2;
   1328                     split2 = sal_strtok(NULL, "x");
   1329                 }
   1330                 /* Potentially 128 bit, so cannot just strtol entire string */
   1331                 j = 0;
   1332                 for (i = (strlen(port_data[1]) - 1); i >= 0; i--) {
   1333                     if ((j * 4 + 3) < 128) {
   1334                         convert_hex2bin(port_data[1][i], bmp_4bit);
   1335                         os_bmp[j * 4    ] = bmp_4bit[0];
   1336                         os_bmp[j * 4 + 1] = bmp_4bit[1];
   1337                         os_bmp[j * 4 + 2] = bmp_4bit[2];
   1338                         os_bmp[j * 4 + 3] = bmp_4bit[3];
   1339                         j++;
   1340                     }
   1341                 }
   1342             }
   1343             if (sal_strstr(line, dic_higig)) {
   1344                 if (sal_strlen(port_str[1]) > 32) {
   1345                     sal_fclose(fp);
   1346                     rv = BCM_E_FAIL;
   1347                     goto done;
   1348                 }
   1349                 sal_strcpy(line_cpy2, port_str[1]);
   1350                 split2 = sal_strtok(line_cpy2, "x");
   1351                 port_data_idx = 0;
   1352                 while (split2) {
   1353                     port_data[port_data_idx++] = split2;
   1354                     split2 = sal_strtok(NULL, "x");
   1355                 }
   1356                 hg_bmp = strtol(port_data[1], NULL, 16);
   1357             }
   1358         }
   1359     }
   1360 
   1361     /* Set port state: oversub, linerate, combined */
   1362     for (i = 1; i < (SOC_MAX_NUM_PORTS - 1); i++) {
   1363         port_phyID = lgc_2_phy_portmap[i];
   1364         if (port_phyID > 0 && port_phyID < (SOC_MAX_NUM_PORTS - 1)) {
   1365             if (port_states[port_phyID - 1] == 9 && xe_bmp[i] == 1) {
   1366                 /* linerate/oversub */
   1367                 port_states[port_phyID - 1] = (os_bmp[i] == 1) ?
   1368                     (PORT_STATE__OVERSUB) : (PORT_STATE__LINERATE);
   1369 
   1370                 /* Combined */
   1371                 if (SOC_IS_TRIDENT2X(unit)) {
   1372                     switch (port_speeds[port_phyID]) {
   1373                         case SPEED_UI_120G     : port_lanenum = 12; break;
   1374                         case SPEED_UI_100G     : port_lanenum = 10; break;
   1375                         case SPEED_UI_42G      :
   1376                         case SPEED_UI_40G      : port_lanenum =  4; break;
   1377                         case SPEED_UI_21G_DUAL :
   1378                         case SPEED_UI_20G      : port_lanenum =  2; break;
   1379                         case SPEED_UI_10G      :
   1380                         case SPEED_UI_2p5G     :
   1381                         case SPEED_UI_1G       : port_lanenum =  1; break;
   1382                         default                : port_lanenum =  0; break;
   1383                     }
   1384                 }
   1385                 if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) {
   1386                     switch (port_speeds[port_phyID]) {
   1387                         case SPEED_UI_100G     :
   1388                         case SPEED_UI_40G      : port_lanenum =  4; break;
   1389                         case SPEED_UI_50G      :
   1390                         case SPEED_UI_41G_DUAL :
   1391                         case SPEED_UI_20G      : port_lanenum =  2; break;
   1392                         case SPEED_UI_25G      :
   1393                         case SPEED_UI_10G      : port_lanenum =  1; break;
   1394                         default                : port_lanenum =  0; break;
   1395                     }
   1396                 }
   1397                 for (j = 1; j < port_lanenum; j++){
   1398                     port_states[port_phyID + j - 1] = PORT_STATE__COMBINE;
   1399                 }
   1400             }
   1401         }
   1402     }
   1403 
   1404     /* Set tsc type: higig, ethernet */
   1405     if (hg_bmp > 0) {
   1406         for (i = 0; i < TDMV_NUM_TSC(unit); i++) {
   1407             if ((((hg_bmp >> i) & 0x1) == 0x1)) {
   1408                 traffic[i] = PM_ENCAP__HIGIG2;
   1409             }
   1410         }
   1411     }
   1412 
   1413     /* Transfer port state to TDM-5 specification */
   1414     for (i = 1; i < (SOC_MAX_NUM_PORTS - 7); i++) {
   1415         j = (i - 1) / TDMV_NUM_TSC_LANES;
   1416         if (j < TDMV_NUM_TSC(unit)) {
   1417             if (traffic[j] == PM_ENCAP__HIGIG2) {
   1418                 switch (port_states[i - 1]) {
   1419                 case PORT_STATE__LINERATE:
   1420                     port_states[i-1] = PORT_STATE__LINERATE_HG;
   1421                     break;
   1422                 case PORT_STATE__OVERSUB:
   1423                     port_states[i-1] = PORT_STATE__OVERSUB_HG;
   1424                     break;
   1425                 default:
   1426                     break;
   1427                 }
   1428             }
   1429         }
   1430     }
   1431 
   1432     sal_fclose(fp);
   1433 
   1434     for (i = 1; i < (SOC_MAX_NUM_PORTS - 1); i++) {
   1435         port_phyID = lgc_2_phy_portmap[i];
   1436         if (port_phyID > 0 && port_phyID < (SOC_MAX_NUM_PORTS - 1)) {
   1437             if ((port_states[port_phyID-1] == PORT_STATE__LINERATE_HG) ||
   1438                 (port_states[port_phyID-1] == PORT_STATE__OVERSUB_HG)) {
   1439                 switch (port_speeds[port_phyID]) {
   1440                     case 120: port_speeds[port_phyID] = 127; break;
   1441                     case 100: port_speeds[port_phyID] = 106; break;
   1442                     case 50:  port_speeds[port_phyID] = 53;  break;
   1443                     case 40:  port_speeds[port_phyID] = 42;  break;
   1444                     case 25:  port_speeds[port_phyID] = 27;  break;
   1445                     case 20:  port_speeds[port_phyID] = 21;  break;
   1446                     case 10:  port_speeds[port_phyID] = 11;  break;
   1447                     default: break;
   1448                 }
   1449             }
   1450             if ((port_states[port_phyID-1] == PORT_STATE__LINERATE) ||
   1451                 (port_states[port_phyID-1] == PORT_STATE__OVERSUB)) {
   1452                 sal_sprintf(eth_hig_str, "ETH");
   1453             } else {
   1454                 sal_sprintf(eth_hig_str, "HG2");
   1455             }
   1456             if ((port_states[port_phyID-1] == PORT_STATE__OVERSUB_HG) ||
   1457                 (port_states[port_phyID-1] == PORT_STATE__OVERSUB)) {
   1458                 sal_sprintf(line_ovsb_str, "OVSB");
   1459             } else {
   1460                 sal_sprintf(line_ovsb_str, "LINE");
   1461             }
   1462             cli_out("\nDev Port %3d, Phy Port %3d, %3d G %s %s",
   1463                     i, port_phyID, port_speeds[port_phyID],
   1464                     eth_hig_str, line_ovsb_str);
   1465         }
   1466     }
   1467 
   1468     for (i = 0; i < TDMV_NUM_TSC(unit); i++) {
   1469         port_idx = i * TDMV_NUM_TSC_LANES + 1;
   1470         num_subport = 4;
   1471         if (SOC_IS_TRIDENT2X(unit) && port_speeds[port_idx] >= 100) {
   1472             num_subport = 12;
   1473             i += 2;
   1474         }
   1475         for (j = 0; j < num_subport; j++) {
   1476             speed[j] = port_speeds[port_idx + j] * 1000;
   1477         }
   1478         if (traffic[i] == PM_ENCAP__HIGIG2) {
   1479             encap = BCM_PORT_ENCAP_HIGIG2;
   1480         } else {
   1481             encap = BCM_PORT_ENCAP_IEEE;
   1482         }
   1483 
   1484         rv = flex_tsc(unit, num_subport, port_idx, speed, encap);
   1485         if (BCM_FAILURE(rv)) {
   1486             cli_out("\nflex_tsc %0d: %s", port_idx, bcm_errmsg(rv));
   1487             break;
   1488         }
   1489     }
   1490 
   1491 done:
   1492     sal_free(port_speeds);
   1493     sal_free(port_states);
   1494     return rv;
   1495 }
   1496 
   1497 /*
   1498  * Function:
   1499  *      flexport_by_tsc
   1500  * Purpose:
   1501  *      Flex one TSC according to the command line inputs
   1502  * Parameters:
   1503  *      unit: StrataSwitch Unit #.
   1504  *      tsc: TSC #
   1505  *      mode: target port speed/mode
   1506  *
   1507  * Returns:
   1508  *     BCM_E_XXXX
   1509  */
   1510 
   1511 static bcm_error_t
   1512 flexport_by_tsc(int unit, uint32 tsc, char *mode)
   1513 {
   1514     int rv = BCM_E_NONE;
   1515     int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1516     int num_subport = 4;
   1517     int encap_enum = BCM_PORT_ENCAP_IEEE;
   1518 
   1519     cli_out("\nFlexing TSC %d to %s", tsc, mode);
   1520 
   1521     if (sal_strstr(mode, "4x0G") || sal_strstr(mode, "12x0G")) {
   1522         cli_out("\nShutting down TSC %d", tsc);
   1523     } else if (sal_strstr(mode, "1x100G") || sal_strstr(mode, "1x106G")) {
   1524         speed[0] = 100000;
   1525         if (SOC_IS_TRIDENT2X(unit)) {
   1526             num_subport = 12;
   1527         }
   1528     } else if (SOC_IS_TRIDENT2X(unit) &&
   1529                (sal_strstr(mode, "1x120G") || sal_strstr(mode, "1x126G"))) {
   1530         speed[0] = 120000;
   1531         num_subport = 12;
   1532     } else if (SOC_IS_TRIDENT2X(unit) &&
   1533                (sal_strstr(mode, "10x10G") || sal_strstr(mode, "10x11G"))) {
   1534         speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000;
   1535         speed[4] = 10000; speed[5] = 10000; speed[6] = 10000; speed[7] = 10000;
   1536         speed[8] = 10000; speed[9] = 10000;
   1537         num_subport = 12;
   1538     } else if (SOC_IS_TRIDENT2X(unit) &&
   1539                (sal_strstr(mode, "12x10G") || sal_strstr(mode, "12x11G"))) {
   1540         speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000;
   1541         speed[4] = 10000; speed[5] = 10000; speed[6] = 10000; speed[7] = 10000;
   1542         speed[8] = 10000; speed[9] = 10000; speed[10] = 10000; speed[11] = 10000;
   1543         num_subport = 12;
   1544     } else if (sal_strstr(mode, "50G+2x25G")) {
   1545         speed[0] = 50000; speed[2] = 25000; speed[3] = 25000;
   1546     } else if (sal_strstr(mode, "2x25G+50G")) {
   1547         speed[0] = 25000; speed[1] = 25000; speed[2] = 50000;
   1548     } else if (sal_strstr(mode, "20G+2x10G")) {
   1549         speed[0] = 20000; speed[2] = 10000; speed[3] = 10000;
   1550     } else if (sal_strstr(mode, "2x10G+20G")) {
   1551         speed[0] = 10000; speed[1] = 10000; speed[2] = 20000;
   1552     } else if (sal_strstr(mode, "40G+2x10G")) {
   1553         speed[0] = 40000; speed[2] = 10000; speed[3] = 10000;
   1554     } else if (sal_strstr(mode, "2x10G+40G")) {
   1555         speed[0] = 10000; speed[1] = 10000; speed[2] = 40000;
   1556     } else if (sal_strstr(mode, "1x50G") || sal_strstr(mode, "1x53G")) {
   1557         speed[0] = 50000;
   1558     } else if (sal_strstr(mode, "1x40G") || sal_strstr(mode, "1x42G")) {
   1559         speed[0] = 40000;
   1560     } else if (sal_strstr(mode, "1x25G") || sal_strstr(mode, "1x27G")) {
   1561         speed[0] = 25000;
   1562     } else if (sal_strstr(mode, "1x20G") || sal_strstr(mode, "1x21G")) {
   1563         speed[0] = 20000;
   1564     } else if ((sal_strstr(mode, "1x10G") || sal_strstr(mode, "1x11G"))) {
   1565         speed[0] = 10000;
   1566     } else if (sal_strstr(mode, "2x50G") || sal_strstr(mode, "2x53G")) {
   1567         speed[0] = 50000; speed[2] = 50000;
   1568     } else if (sal_strstr(mode, "2x40G") || sal_strstr(mode, "2x42G")) {
   1569         speed[0] = 40000; speed[2] = 40000;
   1570     } else if (sal_strstr(mode, "2x25G") || sal_strstr(mode, "2x27G")) {
   1571         speed[0] = 25000; speed[2] = 25000;
   1572     } else if (sal_strstr(mode, "2x20G") || sal_strstr(mode, "2x21G")) {
   1573         speed[0] = 20000; speed[2] = 20000;
   1574     } else if (sal_strstr(mode, "2x10G") || sal_strstr(mode, "2x11G")) {
   1575         speed[0] = 10000; speed[2] = 10000;
   1576     } else if (sal_strstr(mode, "40G+20G")) {
   1577         speed[0] = 40000; speed[2] = 20000;
   1578     } else if (sal_strstr(mode, "20G+40G")) {
   1579         speed[0] = 20000; speed[2] = 40000;
   1580     } else if (sal_strstr(mode, "4x25G") || sal_strstr(mode, "4x27G")) {
   1581         speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000;
   1582     } else if (sal_strstr(mode, "4x10G") || sal_strstr(mode, "4x11G")) {
   1583         speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000;
   1584     } else if (SOC_IS_TRIDENT2X(unit) &&
   1585                (sal_strstr(mode, "4x2.5G"))) {
   1586         speed[0] = 2500; speed[1] = 2500; speed[2] = 2500; speed[3] = 2500;
   1587     } else if (sal_strstr(mode, "4x1G")) {
   1588         speed[0] = 1000; speed[1] = 1000; speed[2] = 1000; speed[3] = 1000;
   1589     } else {
   1590         test_error(unit, "*ERROR: Mode %s is not supported\n", mode);
   1591     }
   1592 
   1593     if (sal_strstr(mode, "11G") || sal_strstr(mode, "21G") ||
   1594         sal_strstr(mode, "27G") || sal_strstr(mode, "53G") ||
   1595         sal_strstr(mode, "42G") || sal_strstr(mode, "106G") ||
   1596         sal_strstr(mode, "127G")) {
   1597         encap_enum = BCM_PORT_ENCAP_HIGIG2;
   1598     } else {
   1599         encap_enum = BCM_PORT_ENCAP_IEEE;
   1600     }
   1601 
   1602     rv = flex_tsc(unit, num_subport, tsc * TDMV_NUM_TSC_LANES + 1, speed,
   1603                   encap_enum);
   1604     if (BCM_FAILURE(rv)) {
   1605         cli_out("\nflex_tsc %0d: %s",
   1606                 tsc * TDMV_NUM_TSC_LANES + 1, bcm_errmsg(rv));
   1607     }
   1608 
   1609     return rv;
   1610 }
   1611 
   1612 
   1613 /*
   1614  * Function:
   1615  *     lossless_flood_cnt
   1616  * Purpose:
   1617  *     Calculates no of packets to be set for the given port
   1618  * Parameters:
   1619  *      unit: StrataSwitch Unit #.
   1620  *      port - Device port number
   1621  *
   1622  * Returns:
   1623  *     flood packet count for the given port.
   1624  */
   1625 static uint32
   1626 lossless_flood_cnt(int unit, int port)
   1627 {
   1628     uint32 pkt_size, flood_cnt = 0;
   1629     int param_flood_cnt, param_pkt_size;
   1630     flexport_t *flexport_p = flexport_parray[unit];
   1631 
   1632     param_flood_cnt = flexport_p->flood_pkt_cnt_param;
   1633     param_pkt_size = flexport_p->pkt_size_param;
   1634 
   1635     if (param_flood_cnt == 0) {
   1636         if (param_pkt_size == 0) {
   1637             pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port));
   1638         } else {
   1639             pkt_size = param_pkt_size;
   1640         }
   1641         flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, NULL);
   1642     } else {
   1643         flood_cnt = param_flood_cnt;
   1644     }
   1645 
   1646     return (flood_cnt);
   1647 }
   1648 
   1649 static int
   1650 get_packet_size(int unit, int port)
   1651 {
   1652     int pkt_size, flood_cnt, i;
   1653     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1654     flexport_t *flexport_p = flexport_parray[unit];
   1655 
   1656     pkt_size = flexport_p->pkt_size_param;
   1657     if(pkt_size == 0) {
   1658             if (IS_HG_PORT(unit, port)) {
   1659                 pkt_size = HG2_WC_PKT_SIZE;
   1660             } else {
   1661                 pkt_size = ENET_WC_PKT_SIZE;
   1662             }
   1663     }
   1664 
   1665     if (pkt_size == 1) {
   1666         if (flexport_p->flood_pkt_cnt_param == 0) {
   1667             flood_cnt = lossless_flood_cnt(unit, port);
   1668         } else {
   1669             flood_cnt = flexport_p->flood_pkt_cnt_param;
   1670         }
   1671         for(i = 0; i< flood_cnt; i++) {
   1672             pkt_size += rate_calc_p->rand_pkt_sizes[port][i];
   1673         }
   1674         pkt_size = pkt_size / flood_cnt;
   1675     }
   1676     return pkt_size;
   1677 }
   1678 
   1679 /*
   1680  * Function:
   1681  *      set_port_property_arrays
   1682  * Purpose:
   1683  *      Set rand_pkt_sizes, port_oversub, and exp_rates arrays.
   1684  * Parameters:
   1685  *      unit: StrataSwitch Unit #.
   1686  *      pbmp - Device port bitmap
   1687  *      pkt_size_param - Packet size in bytes
   1688  *      max_num_cells_param - Maximum number of cells
   1689  *
   1690  * Returns:
   1691  *     BCM_E_XXXX
   1692  */
   1693 
   1694 static bcm_error_t
   1695 set_port_property_arrays(int unit, pbmp_t pbmp, int pkt_size_param,
   1696                          int max_num_cells_param)
   1697 {
   1698   int p, j, pkt_size;
   1699   stream_rate_t *stream_rate_calc_p;
   1700   rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1701   flexport_t *flexport_p = flexport_parray[unit];
   1702 
   1703   stream_rate_calc_p = sal_alloc(sizeof(stream_rate_t), "streaming_rate");
   1704   sal_memset(stream_rate_calc_p, 0, sizeof(stream_rate_t));
   1705 
   1706   stream_rate_calc_p->mode              = 0;
   1707   stream_rate_calc_p->emulation_param   = flexport_p->emulation_param;
   1708   stream_rate_calc_p->tolerance_lr      = flexport_p->rate_tolerance_lr_param;
   1709   stream_rate_calc_p->tolerance_os      = flexport_p->rate_tolerance_ov_param;
   1710   SOC_PBMP_CLEAR(stream_rate_calc_p->pbmp);
   1711   PBMP_ITER(PBMP_E_ALL(unit), p) {
   1712       if (p < SOC_MAX_NUM_PORTS) {
   1713           stream_rate_calc_p->pkt_size          = get_packet_size(unit, p);
   1714           SOC_PBMP_PORT_ADD(stream_rate_calc_p->pbmp, p);
   1715       }
   1716   }
   1717 
   1718   if (SOC_FAILURE(stream_calc_exp_rate_by_rx(unit, rate_calc_p->exp_rate, stream_rate_calc_p))) {
   1719       cli_out("\n*ERROR, stream_calc_exp_rate_by_rx failed.\n");
   1720       sal_free(stream_rate_calc_p);
   1721       return BCM_E_FAIL;
   1722   }
   1723   sal_free(stream_rate_calc_p);
   1724 
   1725   PBMP_ITER(pbmp, p) {
   1726       if (p < SOC_MAX_NUM_PORTS) {
   1727           for (j = 0; j < TARGET_CELL_COUNT; j++) {
   1728               do {
   1729                   /* coverity[dont_call : FALSE] */
   1730                   pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) +
   1731                              MIN_PKT_SIZE;
   1732               } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) > max_num_cells_param);
   1733               rate_calc_p->rand_pkt_sizes[p][j] = pkt_size;
   1734           }
   1735       }
   1736   }
   1737 
   1738   return BCM_E_NONE;
   1739 }
   1740 
   1741 /*
   1742  * Function:
   1743  *      set_up_ports
   1744  * Purpose:
   1745  *      Enable port bridging and HiGig lookup for HG2 ports
   1746  * Parameters:
   1747  *      unit - StrataSwitch Unit #.
   1748  *      pbmp - Device port bitmap
   1749  *
   1750  * Returns:
   1751  *     Nothing
   1752  */
   1753 
   1754 static void
   1755 set_up_ports(int unit, pbmp_t pbmp)
   1756 {
   1757     int i, p;
   1758     lport_tab_entry_t lport_tab_entry;
   1759     port_tab_entry_t port_tab_entry;
   1760     soc_field_t ihg_lookup_fields[] =
   1761         { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf,
   1762         REMOVE_MH_SRC_PORTf
   1763     };
   1764     uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 };
   1765 
   1766     cli_out("\nEnabling HG_LOOKUP on HG ports");
   1767 
   1768     PBMP_ITER(pbmp, p) {
   1769         if (p < SOC_MAX_NUM_PORTS && IS_HG_PORT(unit, p)) {
   1770             soc_reg_fields32_modify(unit, IHG_LOOKUPr, p, 5,
   1771                                     ihg_lookup_fields, ihg_lookup_values);
   1772         }
   1773     }
   1774 
   1775     cli_out("\nEnabling Port bridging");
   1776 
   1777     for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) {
   1778         (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i,
   1779                      lport_tab_entry.entry_data);
   1780         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   1781                             ALLOW_SRC_MODf, 0x1);
   1782         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   1783                             PORT_BRIDGEf, 0x1);
   1784         (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i,
   1785                       lport_tab_entry.entry_data);
   1786     }
   1787 
   1788     for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) {
   1789         (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i,
   1790                      port_tab_entry.entry_data);
   1791         soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data,
   1792                             PORT_BRIDGEf, 0x1);
   1793         (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i,
   1794                           port_tab_entry.entry_data);
   1795     }
   1796 }
   1797 
   1798 /*
   1799  * Function:
   1800  *      set_up_streams
   1801  * Purpose:
   1802  *      VLAN programming. Each port is put on an unique VLAN.
   1803  * Parameters:
   1804  *      unit: StrataSwitch Unit #.
   1805  *      pbmp - Device port bitmap
   1806  *      vlan_bmp - bitmap of device ports that have vlan set up
   1807  *
   1808  * Returns:
   1809  *     vlan_pbmp - bitmap of device ports that have vlan set up.
   1810  */
   1811 
   1812 static pbmp_t
   1813 set_up_streams(int unit, pbmp_t pbmp, pbmp_t vlan_pbmp)
   1814 {
   1815     int p;
   1816     pbmp_t pbm, ubm;
   1817     bcm_vlan_t vlan;
   1818 
   1819     BCM_PBMP_CLEAR(ubm);
   1820 
   1821     PBMP_ITER(pbmp, p) {
   1822         if (p < SOC_MAX_NUM_PORTS) {
   1823             vlan = VLAN + p;
   1824             if (SOC_PBMP_MEMBER(vlan_pbmp, p)) {
   1825                 stream_set_vlan(unit, vlan, 1);
   1826             } else {
   1827                 vlan = VLAN + p;
   1828                 BCM_PBMP_CLEAR(pbm);
   1829                 bcm_vlan_create(unit, vlan);
   1830                 BCM_PBMP_PORT_ADD(pbm, p);
   1831                 bcm_vlan_port_add(unit, vlan, pbm, ubm);
   1832             }
   1833         }
   1834     }
   1835 
   1836     SOC_PBMP_OR(vlan_pbmp, pbmp);
   1837 
   1838     return vlan_pbmp;
   1839 }
   1840 
   1841 
   1842 /*
   1843  * Function:
   1844  *     send_pkts
   1845  * Purpose:
   1846  *     Sends packet for all the ports in the port bitmap
   1847  * Parameters:
   1848  *      unit: StrataSwitch Unit #.
   1849  *      pbmp - port bitmap
   1850  *      pkt_size_param -
   1851  *      pkt_seed -
   1852  *
   1853  * Returns:
   1854  *     flood packet count for the given port.
   1855  */
   1856 static void
   1857 send_pkts(int unit, pbmp_t pbmp, uint32 pkt_size_param, uint32 pkt_seed)
   1858 {
   1859 	int port;
   1860     uint8 mac_da[] = MAC_DA;
   1861     uint8 mac_sa[] = MAC_SA;
   1862 	uint32 pkt_size;
   1863     stream_pkt_t *tx_pkt;
   1864 	flexport_t *flexport_p = flexport_parray[unit];
   1865 	rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1866 
   1867     tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt");
   1868     sal_memset(tx_pkt, 0, sizeof(stream_pkt_t));
   1869 
   1870     cli_out("\n==================================================\n");
   1871     cli_out("\nSending packets ...\n\n");
   1872     PBMP_ITER(pbmp, port) {
   1873         if (port < SOC_MAX_NUM_PORTS) {
   1874             if (flexport_p->pkt_size_param == 0) {
   1875                 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port));
   1876             } else {
   1877                 pkt_size = flexport_p->pkt_size_param;
   1878             }
   1879 
   1880             tx_pkt->port = port;
   1881             tx_pkt->num_pkt = lossless_flood_cnt(unit, port);
   1882             tx_pkt->pkt_seed = pkt_seed;
   1883             tx_pkt->pkt_size = pkt_size;
   1884     		cli_out("\nSending packets on port %0d size %0d num %0d.", port, pkt_size, tx_pkt->num_pkt);
   1885 			if(pkt_size_param == 1) {
   1886               tx_pkt->rand_pkt_size_en = 1;
   1887               tx_pkt->rand_pkt_size = rate_calc_p->rand_pkt_sizes[port];
   1888             } else {
   1889               tx_pkt->rand_pkt_size_en = 0;
   1890               tx_pkt->rand_pkt_size = NULL;
   1891             }
   1892             tx_pkt->tx_vlan = VLAN + port;
   1893             sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR);
   1894             sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR);
   1895             stream_tx_pkt(unit, tx_pkt);
   1896         }
   1897     }
   1898 	sal_free(tx_pkt);
   1899 }
   1900 
   1901 /*
   1902  * Function:
   1903  *      start_rate_measurement
   1904  * Purpose:
   1905  *      Get current time, packet count & byte count needed to calculate port
   1906  *      rate
   1907  * Parameters:
   1908  *      unit - StrataSwitch Unit #.
   1909  *      pbmp - Device port bitmap to be used
   1910  *      emulation_param - 1: test run in emulator platform
   1911  *                        0: test run is actual hardware(chip)
   1912  *
   1913  * Returns:
   1914  *     SOC_E_XXXX
   1915  */
   1916 static bcm_error_t
   1917 start_rate_measurement(int unit, pbmp_t pbmp, uint32 emulation_param)
   1918 {
   1919     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1920 
   1921     return record_rate_information(unit, emulation_param, pbmp, rate_calc_p->stime,
   1922                                  rate_calc_p->tpkt_start, rate_calc_p->tbyt_start);
   1923 
   1924 }
   1925 
   1926 /*
   1927  * Function:
   1928  *      check_rates
   1929  * Purpose:
   1930  *      Check rates against expected rates.
   1931  * Parameters:
   1932  *      unit - StrataSwitch Unit #.
   1933  *      pbmp - Device port bitmap to be checked
   1934  *      tolerance_lr - Percentage of rate tolerance for line rate ports
   1935  *      tolerance_os - Percentage of rate tolerance for oversub ports
   1936  *
   1937  * Returns:
   1938  *     SOC_E_XXXX
   1939  */
   1940 
   1941 static bcm_error_t
   1942 check_rates(int unit, pbmp_t pbmp, uint32 tolerance_lr,
   1943              uint32 tolerance_os, uint32 emulation_param)
   1944 {
   1945     uint64 *etime;
   1946     uint64 *tpkt_end;
   1947     uint64 *tbyt_end;
   1948     uint64 *rate;
   1949     rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   1950     bcm_error_t rv = BCM_E_NONE;
   1951 
   1952     etime = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1953                                       "etime");
   1954     tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1955                                     "tpkt_end");
   1956     tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1957                                     "tbyt_end");
   1958     rate = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1959                                 "rate");
   1960 
   1961     sal_memset(etime,    0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1962     sal_memset(tpkt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1963     sal_memset(tbyt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1964     sal_memset(rate,     0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   1965 
   1966     rv = record_rate_information(unit, emulation_param, pbmp, etime,
   1967                                      tpkt_end, tbyt_end);
   1968 
   1969     calc_act_port_rate(unit, pbmp, rate_calc_p->stime, etime,
   1970                        rate_calc_p->tpkt_start, tpkt_end,
   1971                        rate_calc_p->tbyt_start, tbyt_end, rate);
   1972 
   1973     rv = compare_rates(unit, pbmp, tolerance_lr, tolerance_os,
   1974                   rate_calc_p->exp_rate, rate);
   1975 
   1976     if (rv != BCM_E_NONE) {
   1977         test_error(unit, "********** RATE CHECK FAILED ***********\n");
   1978     } else {
   1979         cli_out("\n********** RATE CHECK PASSED ***********");
   1980     }
   1981 
   1982     sal_free(etime);
   1983     sal_free(tpkt_end);
   1984     sal_free(tbyt_end);
   1985     sal_free(rate);
   1986     return rv;
   1987 }
   1988 
   1989 /*
   1990  * Function:
   1991  *      flexport_test_init
   1992  * Purpose:
   1993  *      Test init function. Parse CLI params and do necessary init.
   1994  * Parameters:
   1995  *      unit - StrataSwitch Unit #.
   1996  *      a - Pointer to arguments
   1997  *
   1998  * Returns:
   1999  *     SOC_E_XXXX
   2000  */
   2001 
   2002 int
   2003 flexport_test_init(int unit, args_t *a, void **pa)
   2004 {
   2005     flexport_t *flexport_p;
   2006     rate_calc_t *rate_calc_p;
   2007     int i, tsc, sub_port, pport, lport;
   2008     int encap;
   2009     int num_subport = 4;
   2010     int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   2011 
   2012     flexport_p = flexport_parray[unit];
   2013     flexport_p = sal_alloc(sizeof(flexport_t), "flexport_test");
   2014     sal_memset(flexport_p, 0, sizeof(flexport_t));
   2015     flexport_parray[unit] = flexport_p;
   2016 
   2017     rate_calc_p = rate_calc_parray[unit];
   2018     rate_calc_p = sal_alloc(sizeof(rate_calc_t), "streaming_library");
   2019     sal_memset(rate_calc_p, 0, sizeof(rate_calc_t));
   2020     rate_calc_parray[unit] = rate_calc_p;
   2021 
   2022     cli_out("\nCalling flexport_test_init");
   2023     flexport_parse_test_params(unit, a);
   2024 
   2025     flexport_p->test_fail = 0;
   2026 
   2027     if(flexport_p->emulation_param) {
   2028         start_cmic_timesync(unit);
   2029     }
   2030 
   2031     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flexport_p->counter_flags,
   2032                                                  &flexport_p->counter_interval,
   2033                                                  &flexport_p->counter_pbm));
   2034     if (flexport_p->counter_interval > 0) {
   2035         cli_out("\nDisabling counter collection");
   2036         soc_counter_stop(unit);
   2037     }
   2038     BCM_IF_ERROR_RETURN(bcm_linkscan_enable_get(unit,
   2039                                                 &flexport_p->linkscan_enable));
   2040     if (flexport_p->linkscan_enable) {
   2041         cli_out("\nDisabling linkscan");
   2042         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
   2043     }
   2044 
   2045     if (flexport_p->emulation_param) {
   2046         /* The server address and port number changes in each session.   */
   2047         /* So, the image must be recompiled after changing the following */
   2048         /* code before every session.                                    */
   2049         flexport_p->sockfd = connectToSocket(flexport_p->socket_num_param,
   2050                                              flexport_p->server_name_param);
   2051 
   2052         /* Initialize tsc_cfg_buffer*/
   2053         for (i = 0; i < 12; i++) {
   2054             sal_memset(flexport_p->tsc_cfg_buffer[i], 0, TCP_CMD_BUF_LEN);
   2055         }
   2056         flexport_p->tsc_cfg_cmds = 0;
   2057         flexport_p->tsc_cfg_ptr = 0;
   2058 
   2059         /* Perform TSC config based on SOC_INFO*/
   2060         if(flexport_p->init_tsc_shim) {
   2061             for(tsc = 0; tsc < TDMV_NUM_TSC(unit); tsc++) {
   2062                 encap = BCM_PORT_ENCAP_IEEE;
   2063 	            for(sub_port = 0; sub_port < num_subport; sub_port++) {
   2064 	                pport = 1 + (tsc * 4) + sub_port;
   2065 	                lport = SOC_INFO(unit).port_p2l_mapping[pport];
   2066 
   2067                     speed[sub_port] = 0;
   2068 	                if(lport == -1) continue;
   2069 
   2070                     if(IS_HG_PORT(unit, lport)) {
   2071                         encap = BCM_PORT_ENCAP_HIGIG2;
   2072                     }
   2073 
   2074 	                BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit, lport, &speed[sub_port]));
   2075                 }
   2076                 config_tsc_shim(unit, tsc, num_subport, speed, encap);
   2077             }
   2078         }
   2079     }
   2080 
   2081     return BCM_E_NONE;
   2082 }
   2083 
   2084 
   2085 /*
   2086  * Function:
   2087  *      flexport_test
   2088  * Purpose:
   2089  *      Set up ports/streams and send packets.
   2090  * Parameters:
   2091  *      unit - StrataSwitch Unit #.
   2092  *      a - Pointer to arguments
   2093  *
   2094  * Returns:
   2095  *     SOC_E_XXXX
   2096  */
   2097 
   2098 int
   2099 flexport_test(int unit, args_t *a, void *pa)
   2100 {
   2101     int i, tsc, sub_port, pport, lport, port;
   2102     pbmp_t stop_traffic_pbmp;
   2103     pbmp_t start_traffic_pbmp;
   2104     uint8 mac_da[] = MAC_DA;
   2105     uint8 mac_sa[] = MAC_SA;
   2106     flexport_t *flexport_p;
   2107     stream_integrity_t *pkt_intg;
   2108     uint64 val64;
   2109     int encap;
   2110     int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   2111     int rv = BCM_E_NONE;
   2112 
   2113     flexport_p = flexport_parray[unit];
   2114 
   2115     if (flexport_p->bad_input) {
   2116         goto done;
   2117     }
   2118 
   2119     cli_out("\nCalling flexport_test");
   2120 
   2121     flexport_p->pkt_seed = sal_rand();
   2122     stream_set_lpbk(unit, PBMP_PORT_ALL(unit), flexport_p->loopback_mode_param);
   2123     stream_turn_off_cmic_mmu_bkp(unit);
   2124     stream_turn_off_fc(unit, PBMP_PORT_ALL(unit));
   2125     set_port_property_arrays(unit, PBMP_PORT_ALL(unit),
   2126                              flexport_p->pkt_size_param,
   2127                              flexport_p->max_num_cells_param);
   2128     set_up_ports(unit, PBMP_PORT_ALL(unit));
   2129     flexport_p->vlan_pbmp = set_up_streams(unit, PBMP_PORT_ALL(unit),
   2130                                            flexport_p->vlan_pbmp);
   2131     send_pkts(unit, PBMP_PORT_ALL(unit), flexport_p->pkt_size_param,
   2132               flexport_p->pkt_seed);
   2133 
   2134     cli_out("\nWait 2s for traffic to stabilize");
   2135     sal_sleep(2);
   2136     start_rate_measurement(unit, PBMP_PORT_ALL(unit), flexport_p->emulation_param);
   2137     cli_out("\nMeasuring Rate over a period of %0ds",
   2138             flexport_p->rate_calc_interval_param);
   2139     sal_sleep(flexport_p->rate_calc_interval_param);
   2140 
   2141     flexport_p->num_del = 0;
   2142     flexport_p->num_add = 0;
   2143     for(i = 0; i < SOC_MAX_NUM_PIPES; i++) {
   2144         flexport_p->last_assigned_port[i] = -1;
   2145     }
   2146     SOC_PBMP_CLEAR(stop_traffic_pbmp);
   2147     SOC_PBMP_CLEAR(start_traffic_pbmp);
   2148     SOC_PBMP_CLEAR(flexport_p->port_down_pbmp);
   2149     SOC_PBMP_CLEAR(flexport_p->port_up_pbmp);
   2150     SOC_PBMP_CLEAR(flexport_p->speed_change_pbmp);
   2151     if (flexport_p->flex_by_command_line) {
   2152         for (i = 0; i < TDMV_NUM_TSC(unit); i++) {
   2153             if (flexport_p->tsc_param[i] != NULL) {
   2154                 BCM_IF_ERROR_RETURN(flexport_by_tsc(unit, i,
   2155                                                     flexport_p->tsc_param[i]));
   2156             }
   2157         }
   2158     } else if (flexport_p->config_file_name != NULL){
   2159         BCM_IF_ERROR_RETURN(flexport_by_config_file(unit,
   2160                                                     flexport_p->config_file_name));
   2161     }
   2162 
   2163     stop_traffic_pbmp = flexport_p->port_down_pbmp;
   2164     BCM_PBMP_OR(stop_traffic_pbmp, flexport_p->speed_change_pbmp);
   2165     if (BCM_PBMP_NOT_NULL(stop_traffic_pbmp)) {
   2166         if (stream_chk_mib_counters(unit, stop_traffic_pbmp, 0) != BCM_E_NONE) {
   2167             flexport_p->test_fail = 1;
   2168         }
   2169 
   2170         if (check_rates(unit, stop_traffic_pbmp,
   2171                        flexport_p->rate_tolerance_lr_param,
   2172                        flexport_p->rate_tolerance_ov_param,
   2173                        flexport_p->emulation_param) != BCM_E_NONE) {
   2174             flexport_p->test_fail = 1;
   2175         }
   2176 
   2177         if (flexport_p->check_packet_integrity_param != 0) {
   2178             pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity");
   2179             sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
   2180 
   2181             pkt_intg->rx_pbmp = stop_traffic_pbmp;
   2182             PBMP_ITER(stop_traffic_pbmp, port) {
   2183                 if (port < SOC_MAX_NUM_PORTS) {
   2184                     pkt_intg->port_pkt_seed[port] = flexport_p->pkt_seed;
   2185                     pkt_intg->port_flood_cnt[port] = lossless_flood_cnt(unit, port);
   2186                     pkt_intg->rx_vlan[port] = VLAN + port;
   2187                     pkt_intg->tx_vlan[port] = VLAN + port;
   2188                     sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR);
   2189                     sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR);
   2190                 }
   2191             }
   2192             rv = stream_chk_pkt_integrity(unit, pkt_intg);
   2193             if (rv != BCM_E_NONE) {
   2194                 flexport_p->test_fail = 1;
   2195             }
   2196             sal_free(pkt_intg);
   2197         }
   2198     }
   2199 
   2200     if (flexport_p->num_del + flexport_p->num_add > 0) {
   2201         stream_set_lpbk(unit, flexport_p->port_down_pbmp, BCM_PORT_LOOPBACK_NONE);
   2202         flexport_call_bcm_api(unit);
   2203         stream_set_lpbk(unit, flexport_p->port_up_pbmp, flexport_p->loopback_mode_param);
   2204     }
   2205 
   2206     if (flexport_p->emulation_param) {
   2207         for(tsc = 0; tsc < TDMV_NUM_TSC(unit); tsc++) {
   2208             if(flexport_p->flex_tsc_map[tsc] == 1) {
   2209                 encap = BCM_PORT_ENCAP_IEEE;
   2210                 for(sub_port = 0; sub_port < TDMV_NUM_TSC_LANES; sub_port++) {
   2211                     pport = 1 + (tsc * 4) + sub_port;
   2212                     lport = SOC_INFO(unit).port_p2l_mapping[pport];
   2213 
   2214                     speed[sub_port] = 0;
   2215                     if(lport == -1) continue;
   2216 
   2217                     if(IS_HG_PORT(unit, lport)) {
   2218                         encap = BCM_PORT_ENCAP_HIGIG2;
   2219                     }
   2220 
   2221                     BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit, lport, &speed[sub_port]));
   2222                 }
   2223                 config_tsc_shim(unit, tsc, TDMV_NUM_TSC_LANES, speed, encap);
   2224             }
   2225         }
   2226     }
   2227 
   2228     start_traffic_pbmp = flexport_p->port_up_pbmp;
   2229     BCM_PBMP_OR(start_traffic_pbmp, flexport_p->speed_change_pbmp);
   2230 
   2231     if (flexport_p->clear_new_port_counts) {
   2232         COMPILER_64_ZERO(val64);
   2233         BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit, start_traffic_pbmp, val64));
   2234     }
   2235 
   2236     stream_turn_off_fc(unit, flexport_p->port_up_pbmp);
   2237     set_port_property_arrays(unit, start_traffic_pbmp,
   2238                              flexport_p->pkt_size_param,
   2239                              flexport_p->max_num_cells_param);
   2240     set_up_ports(unit, flexport_p->port_up_pbmp);
   2241     flexport_p->vlan_pbmp = set_up_streams(unit, start_traffic_pbmp,
   2242                                            flexport_p->vlan_pbmp);
   2243     send_pkts(unit, start_traffic_pbmp, flexport_p->pkt_size_param,
   2244               flexport_p->pkt_seed);
   2245 
   2246 
   2247     cli_out("\nWait 2s for traffic to stabilize");
   2248     sal_sleep(2);
   2249 
   2250     start_rate_measurement(unit, start_traffic_pbmp, flexport_p->emulation_param);
   2251 
   2252     cli_out("\nMeasuring Rate over a period of %0ds",
   2253             flexport_p->rate_calc_interval_param);
   2254     sal_sleep(flexport_p->rate_calc_interval_param);
   2255 
   2256     if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) {
   2257         flexport_p->test_fail = 1;
   2258     }
   2259     if (check_rates(unit, PBMP_PORT_ALL(unit),
   2260                    flexport_p->rate_tolerance_lr_param,
   2261                    flexport_p->rate_tolerance_ov_param,
   2262                    flexport_p->emulation_param) != BCM_E_NONE) {
   2263         flexport_p->test_fail = 1;
   2264     }
   2265     if (flexport_p->check_packet_integrity_param != 0) {
   2266         pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity");
   2267         sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
   2268 
   2269         pkt_intg->rx_pbmp = PBMP_PORT_ALL(unit);
   2270         PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   2271             if (port < SOC_MAX_NUM_PORTS) {
   2272                 pkt_intg->port_pkt_seed[port] = flexport_p->pkt_seed;
   2273                 pkt_intg->port_flood_cnt[port] = lossless_flood_cnt(unit, port);
   2274                 pkt_intg->rx_vlan[port] = VLAN + port;
   2275                 pkt_intg->tx_vlan[port] = VLAN + port;
   2276                 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR);
   2277                 sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR);
   2278             }
   2279 		}
   2280         rv = stream_chk_pkt_integrity(unit, pkt_intg);
   2281         if (rv != BCM_E_NONE) {
   2282             flexport_p->test_fail = 1;
   2283         }
   2284         sal_free(pkt_intg);
   2285     }
   2286 
   2287 done:
   2288     return rv;
   2289 }
   2290 
   2291 
   2292 /*
   2293  * Function:
   2294  *      flexport_test_cleanup
   2295  * Purpose:
   2296  *      Do test end checks and free all allocated memory.
   2297  * Parameters:
   2298  *      unit - StrataSwitch Unit #.
   2299  *      a - Pointer to arguments
   2300  *
   2301  * Returns:
   2302  *     SOC_E_XXXX
   2303  */
   2304 
   2305 int
   2306 flexport_test_cleanup(int unit, void *pa)
   2307 {
   2308     flexport_t *flexport_p;
   2309     rate_calc_t *rate_calc_p;
   2310     int rv = BCM_E_NONE;
   2311 
   2312     cli_out("\nCalling flexport_test_cleanup");
   2313 
   2314     flexport_p = flexport_parray[unit];
   2315 
   2316     if (flexport_p->emulation_param) {
   2317         close(flexport_p->sockfd);
   2318     }
   2319 
   2320     if (flexport_p->linkscan_enable) {
   2321         cli_out("\nEnabling linkscan");
   2322         BCM_IF_ERROR_RETURN(bcm_linkscan_mode_set_pbm(unit, PBMP_PORT_ALL(unit),
   2323                                                       BCM_LINKSCAN_MODE_SW));
   2324         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 1));
   2325     }
   2326     if (flexport_p->counter_interval > 0) {
   2327         cli_out("\nEnabling counter collection with interval %0d", flexport_p->counter_interval);
   2328         BCM_IF_ERROR_RETURN(soc_counter_start(unit, flexport_p->counter_flags,
   2329                                                  flexport_p->counter_interval,
   2330                                                  PBMP_PORT_ALL(unit)));
   2331     }
   2332 
   2333     if (flexport_p->bad_input == 1) {
   2334         flexport_p->test_fail = 1;
   2335     }
   2336 
   2337     if (flexport_p->test_fail == 1) {
   2338         rv = BCM_E_FAIL;
   2339     }
   2340 
   2341     rate_calc_p = rate_calc_parray[unit];
   2342 
   2343     sal_free(flexport_p);
   2344     sal_free(rate_calc_p);
   2345     bcm_vlan_init(unit);
   2346 
   2347     cli_out("\n");
   2348 
   2349     return rv;
   2350 }
   2351 
   2352 #endif /*(BCM_ESW_SUPPORT) && \
   2353            (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \
   2354            !defined(NO_SAL_APPL) && (!defined(__KERNEL__)) */