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


      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  * Flexport test is to check the correctness of flexport operation under
      8  * ipmc and l3uc traffic background. Ports are divided into two groups:
      9  * ports receiving IPMC packets and ports receiving L3UC packets.
     10  * Each port in IPMC group can receive L2 or L3 copies. While each port
     11  * in L3UC receiving L3UC packets. Test calculates expected rates based
     12  * on port config and oversub ratio and checks against it.
     13  * Configuration parameters passed from CLI:\n"
     14  *
     15  * Checks:
     16  * 1. Packet counts on each port.
     17  * 2. Packet integrity per port per replication.
     18  * 3. Port rate.
     19  *
     20  * Test Limitations
     21  * 1. FloodCnt automatically computed in the test supports packet sizes upto
     22  *    1518B and NumCopy=2. Any deviations may result in packet drops for LR
     23  *    configs or false rate errors being reported. For custom configs the user is
     24  *    encouraged to tweak the FloodCnt value as per their needs.
     25  *
     26  * Configuration parameters passed from CLI:
     27  * PktSize : Packet size in bytes not including HG2 header. Set to 0 for worst
     28  *           case packet sizes (145B for Ethernet and 76B for HG2). Set to 1 for
     29  *           random packet sizes.
     30  * FloodCnt: Number of packets sent from CPU to flood each stream (packet swill).
     31  *           Set to 0 for test to automatically calculate.
     32  * IpmcNumL2Ports: Number of ports receiving L2 copies in each stream (2 by default).
     33  * IpmcNumL3Ports:  Number of ports receiving L3 copies in each stream (2 by default).
     34  * IpmcNumRep: Number of same-port replications on ports receiving . Set to 0 for
     35  *         random.
     36  * MaxNumCells: Max number of cells for random packet sizes. Default = 4.
     37  *              Set to 0 for random.
     38  * RateCalcInterval: Interval in seconds over which swill is allowed to
     39  *          run (10s by default).
     40  */
     41 
     42 #include <appl/diag/system.h>
     43 #include <shared/alloc.h>
     44 #include <shared/bsl.h>
     45 
     46 #include <soc/cm.h>
     47 #include <soc/dma.h>
     48 #include <soc/drv.h>
     49 #include <soc/dcb.h>
     50 #include <soc/cmicm.h>
     51 #include <soc/cmic.h>
     52 
     53 #include <sal/types.h>
     54 #include <appl/diag/parse.h>
     55 #include <bcm/port.h>
     56 #include <bcm/vlan.h>
     57 #include <bcm/link.h>
     58 #include <bcm/ipmc.h>
     59 #include <bcm/multicast.h>
     60 
     61 #include "testlist.h"
     62 #include "gen_pkt.h"
     63 #include "streaming_lib.h"
     64 
     65 #define MAC_DA {0x01,0x00,0x5e,0x02,0x03,0x04}
     66 #define MAC_SA {0x00,0x00,0x00,0x00,0x00,0x01}
     67 #define VLAN 0x2
     68 #define DROP_VLAN 0xabc
     69 #define SIP 0x02030405
     70 #define DIP 0xe0020304
     71 #define FIRST_MC_GROUP 0x2000001
     72 #define FIRST_INTF_ID 0x2
     73 #define TTL 5
     74 
     75 #define MAX_NUM_TSC 65
     76 #define NUM_LANES_PER_TSC 4
     77 #define MAX_PKTS_PER_STREAM 200
     78 
     79 #define PKT_SIZE_PARAM_DEFAULT 0
     80 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0
     81 #define NUM_L2_COPY_PARAM_DEFAULT 2
     82 #define NUM_L3_COPY_PARAM_DEFAULT 6
     83 #define NUM_REP_PARAM_DEFAULT 3
     84 #define MAX_NUM_CELLS_PARAM_DEFAULT 4
     85 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10
     86 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 2
     87 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 5
     88 #define CHECK_INTEGRITY_PARAM_DEFAULT 1
     89 #define CHECK_RATE_PARAM_DEFAULT 1
     90 #define CHECK_MIB_PARAM_DEFAULT 0
     91 #define MAX_L3_VLANS_PER_TEST 1000
     92 #define MAX_NUM_IPMC_STREAMS 10
     93 #define MAX_NUM_REP_PER_PORT 10
     94 #define NO_SPEED_CHANGE_PARAM_DEFAULT 1
     95 #define EMULATION_PARAM_DEFAULT 0
     96 #define CLEAR_NEW_PORT_CNT_PARAM_DEFAULT 0
     97 #define TEST_COVERITY_PBMP_WID 256
     98 
     99 #if defined(BCM_ESW_SUPPORT) && defined(INCLUDE_L3) && \
    100            (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \
    101            !defined(NO_SAL_APPL) && (!defined(__KERNEL__))
    102 
    103 typedef struct flexport_mc_s {
    104     pbmp_t ipmc_pbmp;
    105     uint32 ipmc_num_streams;
    106     uint32 ipmc_port_list[SOC_MAX_NUM_PORTS];
    107     uint32 ipmc_port_list_size;
    108     int    ipmc_stream[MAX_NUM_IPMC_STREAMS][SOC_MAX_NUM_PORTS];
    109     uint32 ipmc_num_rep[SOC_MAX_NUM_PORTS];
    110     uint32 ipmc_port_l3_copy_en[SOC_MAX_NUM_PORTS];
    111     uint32 ipmc_tx_vlan[MAX_NUM_IPMC_STREAMS];
    112     uint32 ipmc_exp_vlan[MAX_NUM_IPMC_STREAMS];
    113     uint8  ipmc_exp_mac_addr[MAX_NUM_IPMC_STREAMS][NUM_BYTES_MAC_ADDR];
    114     uint32 ipmc_drop_vlan[MAX_NUM_IPMC_STREAMS];
    115     uint64 *ipmc_exp_rate;
    116     uint64 *ipmc_tpkt_start;
    117     uint64 *ipmc_tpkt_end;
    118     uint32 ipmc_rand_pkt_sizes[TARGET_CELL_COUNT];
    119 
    120     uint32 pkt_size_param;
    121     uint32 flood_pkt_cnt_param;
    122     uint32 ipmc_num_l2_ports_param;
    123     uint32 ipmc_num_l3_ports_param;
    124     uint32 check_integrity_param;
    125     uint32 check_rate_param;
    126     uint32 check_mib_param;
    127     uint32 ipmc_num_rep_param;
    128     uint32 max_num_cells_param;
    129     uint32 rate_calc_interval_param;
    130     uint32 rate_tolerance_lr_param;
    131     uint32 rate_tolerance_os_param;
    132     uint32 flex_no_spd_ch_param;
    133     uint32 emulation_param;
    134     uint32 loopback_mode_param;
    135     uint32 clear_new_port_cnt_param;
    136     uint32 num_ports_per_stream;
    137 
    138     uint32 bad_input;
    139     int test_fail;
    140     uint32 pkt_seed;
    141 
    142     uint32 debug_param;
    143     uint32 ipmc_port_rep_vlan[SOC_MAX_NUM_PORTS][MAX_NUM_REP_PER_PORT];
    144     uint32 ipmc_port_vlan_cnt[SOC_MAX_NUM_PORTS];
    145     uint32 ipmc_cpu_rx_vlan_cnt[MAX_L3_VLANS_PER_TEST];
    146     uint32 ipmc_next_vlan;
    147     uint32 ipmc_next_drop_vlan;
    148     uint32 ipmc_next_intf_id;
    149     uint32 ipmc_stream_mc_group[MAX_NUM_IPMC_STREAMS];
    150 
    151     int    env_linkscan_enable;
    152     uint32 env_counter_flags;
    153     int    env_counter_interval;
    154     pbmp_t env_counter_pbm;
    155 
    156     pbmp_t flex_lport_dn_pbmp;  /* pbmp for down-ports */
    157     pbmp_t flex_lport_up_pbmp;  /* pbmp for up-ports */
    158     pbmp_t flex_lport_ch_pbmp;  /* pbmp for speed_change_lane_unchange-ports */
    159     char   *flex_tsc_mode[MAX_NUM_TSC];
    160     uint32 flex_num_del;
    161     uint32 flex_num_add;
    162     bcm_port_resource_t flex_resource_del[SOC_MAX_NUM_PORTS];
    163     bcm_port_resource_t flex_resource_add[SOC_MAX_NUM_PORTS];
    164 
    165     pbmp_t l3uc_pbmp;
    166     pbmp_t l3uc_vlan_pbmp;
    167 
    168     /* chip dependent test parameters. */
    169     int    test_lport_lo_ipmc, test_lport_hi_ipmc;
    170     int    test_lport_lo_l3uc, test_lport_hi_l3uc;
    171 } flexport_mc_t;
    172 
    173 
    174 typedef struct flexport_l3uc_rate_calc_t {
    175     uint32 ovs_ratio_x1000[SOC_MAX_NUM_PIPES];
    176     uint32 rand_pkt_sizes[SOC_MAX_NUM_PORTS][TARGET_CELL_COUNT];
    177     uint64 stime[SOC_MAX_NUM_PORTS];
    178     uint64 exp_rate[SOC_MAX_NUM_PORTS];
    179     uint64 tpkt_start[SOC_MAX_NUM_PORTS];
    180     uint64 tbyt_start[SOC_MAX_NUM_PORTS];
    181 } flexport_l3uc_rate_calc_t;
    182 
    183 
    184 static flexport_mc_t *flexport_parray[SOC_MAX_NUM_DEVICES];
    185 static flexport_l3uc_rate_calc_t *rate_calc_parray[SOC_MAX_NUM_DEVICES];
    186 
    187 
    188 const char flexport_mc_test_usage[] =
    189 #ifdef COMPILER_STRING_CONST_LIMIT
    190     "\nDocumentation too long to be displayed with -pedantic compiler\n";
    191 #else
    192     "Flexport test is to check the correctness of flexport operation under\n"
    193     "ipmc and l3uc traffic background. Ports are divided into two groups:\n"
    194     "ports receiving IPMC packets and ports receiving L3UC packets. \n"
    195     "Each port in IPMC group can receive L2 or L3 copies. While each port\n"
    196     "in L3UC receiving L3UC packets. Test calculates expected rates based\n"
    197     "on port config and oversub ratio and checks against it.\n"
    198     "Configuration parameters passed from CLI:\n"
    199     "PktSize: Packet size in bytes. Set it to 0 for worst case packet sizes.\n"
    200     "         Set it to 1 for random packet sizes.\n"
    201     "FloodCnt: Number of packets in each swill. Set it to 0 will let the\n"
    202     "          test calculate the number of packets that can be sent to\n"
    203     "          achieve a lossless swirl at full rate. Set to 0 by default.\n"
    204     " IpmcNumL2Ports: Number of ports receiving L2 copies (2 by default).\n"
    205     " IpmcNumL3Ports: Number of ports receiving L3 copies (2 by default).\n"
    206     " IpmcNumRep: Number of replications per port. Set to 0 for random.\n"
    207     " MaxNumCells: Max number of cells for random packet sizes. Default = 4.\n"
    208     "              Set to 0 for random.\n"
    209     " RateCalcInterval: Interval in seconds over which swill is allowed to\n"
    210     "                   run (10s by default).\n";
    211 #endif
    212 
    213 const char flexport_mc_td3_supported_mode[] =
    214     "              1x100G, 1x40G\n"
    215     "              2x50G, 2x40G, 2x20G,\n"
    216     "              20G+2x10G, 2x10G+20G,\n"
    217     "              50G+2x25G, 2x25G+50G,\n"
    218     "              4x25G, 4x10G and 4x1G\n"
    219     "              The supported mode/speed in HiGig2 encapsulation are:\n"
    220     "              1x106G, 1x42G,\n"
    221     "              2x53G, 2x42G, 2x21G,\n"
    222     "              4x27G, and 4x11G\n"
    223     ;
    224 
    225 
    226 
    227 /*
    228  * Function:
    229  *      flexport_print_ports
    230  * Purpose:
    231  *      Print ports in port bmp.
    232  * Parameters:
    233  *      unit: StrataSwitch Unit #.
    234  *      pbmp: port bitmap.
    235  *      str : string ptr for print title.
    236  *
    237  * Returns:
    238  *     Nothing.
    239  */
    240 static void
    241 flexport_print_ports(int unit, pbmp_t pbmp, char *str)
    242 {
    243     int p, cnt = 0;
    244     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n%s"), str));
    245     PBMP_ITER(pbmp, p) {
    246         if (cnt++ % 10 == 0) {
    247             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
    248         }
    249         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%3d "), p));
    250     }
    251     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
    252 }
    253 
    254 /*
    255  * Function:
    256  *      flexport_set_chip_dependent_params
    257  * Purpose:
    258  *      Set chip dependent parameters.
    259  * Parameters:
    260  *
    261  * Returns:
    262  *     Nothing
    263  */
    264 static void
    265 flexport_set_chip_dependent_params(int unit)
    266 {
    267     flexport_mc_t *flex_p = flexport_parray[unit];
    268 
    269     /* MAVERICK2 */
    270     if (SOC_IS_MAVERICK2(unit)) {
    271         flex_p->test_lport_lo_ipmc = 1;
    272         flex_p->test_lport_hi_ipmc = 32;
    273         flex_p->test_lport_lo_l3uc = 41;
    274         flex_p->test_lport_hi_l3uc = 64;
    275     }
    276     /* TRIDENT3 */
    277     else if (SOC_IS_TRIDENT3(unit)) {
    278         flex_p->test_lport_lo_ipmc = 1;
    279         flex_p->test_lport_hi_ipmc = 32;
    280         flex_p->test_lport_lo_l3uc = 64;
    281         flex_p->test_lport_hi_l3uc = 128;
    282     }
    283     else {
    284         flex_p->test_lport_lo_ipmc = 1;
    285         flex_p->test_lport_hi_ipmc = 32;
    286         flex_p->test_lport_lo_l3uc = 64;
    287         flex_p->test_lport_hi_l3uc = 128;
    288     }
    289 }
    290 
    291 /*
    292  * Function:
    293  *      flexport_is_ipmc_port
    294  * Purpose:
    295  *      Check if physial port is belonging to ipmc group.
    296  * Parameters:
    297  *      unit: StrataSwitch Unit #.
    298  *      phy_port:  physical port number.
    299  *
    300  * Returns:
    301  *     Return true if port is belonging to impc port_range,
    302  *     otherwise return false.
    303  */
    304 static int
    305 flexport_is_ipmc_port(int unit, int phy_port)
    306 {
    307     flexport_mc_t *flex_p = flexport_parray[unit];
    308     return (phy_port >= flex_p->test_lport_lo_ipmc &&
    309             phy_port <= flex_p->test_lport_hi_ipmc);
    310 }
    311 
    312 /*
    313  * Function:
    314  *      flexport_is_l3uc_port
    315  * Purpose:
    316  *      Check if physial port is belonging to l3uc group.
    317  * Parameters:
    318  *      unit: StrataSwitch Unit #.
    319  *      phy_port:  physical port number.
    320  *
    321  * Returns:
    322  *     Return true if port is belonging to l3uc port_range,
    323  *     otherwise return false.
    324  */
    325 static int
    326 flexport_is_l3uc_port(int unit, int phy_port)
    327 {
    328     flexport_mc_t *flex_p = flexport_parray[unit];
    329     return (phy_port >= flex_p->test_lport_lo_l3uc &&
    330             phy_port <= flex_p->test_lport_hi_l3uc);
    331 }
    332 
    333 
    334 /*
    335  * Function:
    336  *      flexport_parse_test_params
    337  * Purpose:
    338  *      Parse CLI parameters, create test structure and flag bad inputs.
    339  * Parameters:
    340  *      unit - StrataSwitch Unit #.
    341  *      a - Pointer to arguments
    342  *
    343  * Returns:
    344  *     Nothing
    345  * Notes:
    346  *      flex_p->bad_input set from here - tells test to crash out in case
    347  *      CLI input combination is invalid.
    348  */
    349 static void
    350 flexport_parse_test_params(int unit, args_t *a)
    351 {
    352     parse_table_t parse_table;
    353     flexport_mc_t *flex_p = flexport_parray[unit];
    354 
    355     flex_p->bad_input = 0;
    356 
    357     flex_p->pkt_size_param          = PKT_SIZE_PARAM_DEFAULT;
    358     flex_p->flood_pkt_cnt_param     = FLOOD_PKT_CNT_PARAM_DEFAULT;
    359     flex_p->max_num_cells_param     = MAX_NUM_CELLS_PARAM_DEFAULT;
    360     flex_p->ipmc_num_l2_ports_param = NUM_L2_COPY_PARAM_DEFAULT;
    361     flex_p->ipmc_num_l3_ports_param = NUM_L3_COPY_PARAM_DEFAULT;
    362     flex_p->ipmc_num_rep_param      = NUM_REP_PARAM_DEFAULT;
    363     flex_p->rate_calc_interval_param= RATE_CALC_INTERVAL_PARAM_DEFAULT;
    364     flex_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT;
    365     flex_p->rate_tolerance_os_param = RATE_TOLERANCE_OV_PARAM_DEFAULT;
    366     flex_p->check_integrity_param   = CHECK_INTEGRITY_PARAM_DEFAULT;
    367     flex_p->check_rate_param        = CHECK_RATE_PARAM_DEFAULT;
    368     flex_p->check_mib_param         = CHECK_MIB_PARAM_DEFAULT;
    369     flex_p->flex_no_spd_ch_param    = NO_SPEED_CHANGE_PARAM_DEFAULT;
    370     flex_p->emulation_param         = EMULATION_PARAM_DEFAULT;
    371     flex_p->loopback_mode_param     = BCM_PORT_LOOPBACK_MAC;
    372     flex_p->clear_new_port_cnt_param= CLEAR_NEW_PORT_CNT_PARAM_DEFAULT;
    373     flex_p->debug_param             = 0;
    374 
    375     /*Parse CLI opts */
    376 
    377     parse_table_init(unit, &parse_table);
    378     parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0,
    379                     &(flex_p->pkt_size_param), NULL);
    380     parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0,
    381                     &(flex_p->flood_pkt_cnt_param), NULL);
    382     parse_table_add(&parse_table, "IpmcNumL2Ports", PQ_INT|PQ_DFL, 0,
    383                     &(flex_p->ipmc_num_l2_ports_param), NULL);
    384     parse_table_add(&parse_table, "IpmcNumL3Ports", PQ_INT|PQ_DFL, 0,
    385                     &(flex_p->ipmc_num_l3_ports_param), NULL);
    386     parse_table_add(&parse_table, "IpmcNumRep", PQ_INT|PQ_DFL, 0,
    387                     &(flex_p->ipmc_num_rep_param), NULL);
    388     parse_table_add(&parse_table, "RateToleranceLR", PQ_INT|PQ_DFL, 0,
    389                     &(flex_p->rate_tolerance_lr_param), NULL);
    390     parse_table_add(&parse_table, "RateToleranceOS", PQ_INT|PQ_DFL, 0,
    391                     &(flex_p->rate_tolerance_os_param), NULL);
    392     parse_table_add(&parse_table, "RateCalcInterval", PQ_INT|PQ_DFL, 0,
    393                     &(flex_p->rate_calc_interval_param), NULL);
    394     parse_table_add(&parse_table, "CheckIntegrity", PQ_INT|PQ_DFL, 0,
    395                     &(flex_p->check_integrity_param), NULL);
    396     parse_table_add(&parse_table, "CheckRate", PQ_INT|PQ_DFL, 0,
    397                     &(flex_p->check_rate_param), NULL);
    398     parse_table_add(&parse_table, "CheckMib", PQ_INT|PQ_DFL, 0,
    399                     &(flex_p->check_mib_param), NULL);
    400     parse_table_add(&parse_table, "ClrNewPortCnt", PQ_INT|PQ_DFL, 0,
    401                     &(flex_p->clear_new_port_cnt_param), NULL);
    402     parse_table_add(&parse_table, "DebugParam", PQ_INT|PQ_DFL, 0,
    403                     &(flex_p->debug_param), NULL);
    404 
    405     if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) {
    406         test_msg("%s", flexport_mc_test_usage);
    407         cli_out("\n%s\n", flexport_mc_td3_supported_mode);
    408         test_error(unit, "%s: Invalid option: %s\n",
    409                    ARG_CMD(a),
    410                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    411         flex_p->bad_input = 1;
    412         parse_arg_eq_done(&parse_table);
    413     } else {
    414         cli_out("\n");
    415         cli_out("------------- PRINTING TEST PARAMS ------------------\n");
    416         cli_out("PktSize          = %0d\n", flex_p->pkt_size_param);
    417         cli_out("FloodCnt         = %0d\n", flex_p->flood_pkt_cnt_param);
    418         cli_out("IpmcNumL3Ports   = %0d\n", flex_p->ipmc_num_l3_ports_param);
    419         cli_out("IpmcNumRep       = %0d\n", flex_p->ipmc_num_rep_param);
    420         cli_out("MaxNumCells      = %0d\n", flex_p->max_num_cells_param);
    421         cli_out("RateToleranceLR  = %0d\n", flex_p->rate_tolerance_lr_param);
    422         cli_out("RateToleranceOS  = %0d\n", flex_p->rate_tolerance_os_param);
    423         cli_out("RateCalcInterval = %0d\n", flex_p->rate_calc_interval_param);
    424         cli_out("CheckIntegrity   = %0d\n", flex_p->check_integrity_param);
    425         cli_out("CheckRate        = %0d\n", flex_p->check_rate_param);
    426         cli_out("FlexNoSpeedChange= %0d\n", flex_p->flex_no_spd_ch_param);
    427         cli_out("ClrNewPortCnt    = %0d\n", flex_p->clear_new_port_cnt_param);
    428         cli_out("DebugParam       = %0d\n", flex_p->debug_param);
    429         cli_out("-----------------------------------------------------\n");
    430     }
    431 
    432     /* loopback_mode */
    433     if ((flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_MAC) &&
    434         (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY) &&
    435         (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY_REMOTE) &&
    436         (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_NONE)) {
    437         /*
    438          *   0 - no loopback; only to be used with chip external loopbacks.
    439          *   1 - MAC outer loopback.
    440          *   2 - PCS local loopback, close to PMD boundary.
    441          *   3 - PMD local loopback, close to AFE.
    442          */
    443         test_error(unit,"*ERROR: Loopback mode must be either 0, 1, 2 or 3\n");
    444         flex_p->bad_input = 1;
    445     }
    446 
    447     if (flex_p->max_num_cells_param == 0) {
    448         /* coverity[dont_call : FALSE] */
    449         flex_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1;
    450     }
    451 
    452     if (flex_p->pkt_size_param == 0) {
    453         flex_p->pkt_size_param = 256;
    454         cli_out("Using default packet sizes - %0dB", flex_p->pkt_size_param);
    455     } else if (flex_p->pkt_size_param == 1) {
    456         cli_out("Using random packet sizes\n");
    457     } else if (flex_p->pkt_size_param < MIN_PKT_SIZE) {
    458         test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n",
    459                    MIN_PKT_SIZE);
    460         flex_p->bad_input = 1;
    461     } else if (flex_p->pkt_size_param > MTU) {
    462         test_error(unit, "\n%s higher than %0dB (Device MTU)\n",
    463                    "*ERROR: Packet size cannot be ", MTU);
    464         flex_p->bad_input = 1;
    465     }
    466 
    467     if (flex_p->flood_pkt_cnt_param == 0) {
    468         cli_out("FloodCnt=0, test will automatically calculate number of"
    469                 " packets to flood each port\n");
    470     }
    471 
    472     if (flex_p->ipmc_num_rep_param > MAX_NUM_REP_PER_PORT) {
    473         flex_p->ipmc_num_rep_param = MAX_NUM_REP_PER_PORT;
    474         cli_out("Max replications supported by this test = %0d,"
    475                 "forcing number of replications to %0d\n",
    476                 MAX_NUM_REP_PER_PORT, MAX_NUM_REP_PER_PORT);
    477     }
    478 
    479     /* total number of ports in each ipmc group */
    480     flex_p->num_ports_per_stream = flex_p->ipmc_num_l2_ports_param +
    481                                    flex_p->ipmc_num_l3_ports_param;
    482     cli_out("initial NumPortsIpmc = %0d,\n", flex_p->num_ports_per_stream);
    483 }
    484 
    485 /*
    486  * Function:
    487  *      flexport_ipmc_set_port_property
    488  * Purpose:
    489  *      Set port_list, stream, port_l3_copy_en, rand_pkt_size.
    490  *      Also call set_exp_rates.
    491  * Parameters:
    492  *      unit: StrataSwitch Unit #.
    493  *
    494  * Returns:
    495  *     Nothing.
    496  */
    497 static void
    498 flexport_ipmc_set_port_property(int unit)
    499 {
    500     int i, j, p, port_idx, pkt_size;
    501     flexport_mc_t *flex_p = flexport_parray[unit];
    502 
    503     cli_out("\n[ipmc] set_port_property()\n");
    504 
    505     flex_p->ipmc_num_streams = 0;
    506     /* coverity[dont_call : FALSE] */
    507     flex_p->pkt_seed = sal_rand();
    508 
    509     flex_p->ipmc_port_list_size = 0;
    510     PBMP_ITER(flex_p->ipmc_pbmp, p) {
    511         flex_p->ipmc_port_list[flex_p->ipmc_port_list_size++] = p;
    512     }
    513 
    514     /* assign ports for stream 0 by picking up the first n ports */
    515     i = 0;
    516     for (j = 0; j < flex_p->num_ports_per_stream; j++) {
    517         port_idx = j; /* index of port in ipmc_port_list */
    518         flex_p->ipmc_stream[i][j] = port_idx;
    519     }
    520     flex_p->ipmc_num_streams = 1;
    521 
    522     /* port_l3_copy_en[]: all ports except P0 and P1 receive L3 copies.
    523      * P0 and P1 are used for generating traffic.
    524      */
    525     for (i = 0; i < flex_p->ipmc_port_list_size; i++) {
    526         p = flex_p->ipmc_port_list[i];
    527         flex_p->ipmc_port_l3_copy_en[p] = i < 2 ? 0 : 1;
    528     }
    529 
    530     /* num_rep[]: number of L3 replications of each port */
    531     for (i = 0; i < flex_p->ipmc_port_list_size; i++) {
    532         p = flex_p->ipmc_port_list[i];
    533         flex_p->ipmc_num_rep[p] = 0;
    534         if (flex_p->ipmc_port_l3_copy_en[p] == 1) {
    535             if (flex_p->ipmc_num_rep_param == 0) {
    536                 /* coverity[dont_call : FALSE] */
    537                 flex_p->ipmc_num_rep[p] = sal_rand() % (MAX_NUM_REP_PER_PORT + 1);
    538             } else {
    539                 flex_p->ipmc_num_rep[p] = flex_p->ipmc_num_rep_param;
    540             }
    541         }
    542     }
    543 
    544     /* rand_pkt_sizes[][] */
    545     p = flex_p->ipmc_port_list[0];
    546     for (j = 0; j < TARGET_CELL_COUNT; j++) {
    547         do {
    548             /* coverity[dont_call : FALSE] */
    549             pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE;
    550         } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) >
    551                                          flex_p->max_num_cells_param);
    552         flex_p->ipmc_rand_pkt_sizes[j] = pkt_size;
    553     }
    554 
    555     {
    556         /* print */
    557         int port_idx;
    558         cli_out("\n=========== IPMC STREAM INFO ============\n");
    559         cli_out("\t[%s]%4s %s/%s\n", "idx", "port", "type", "num_cpy");
    560 
    561         for (i = 0; i < flex_p->ipmc_num_streams; i++) {
    562             cli_out("%4d ", i);
    563             for (j = 0; j < flex_p->num_ports_per_stream; j++) {
    564                 port_idx = flex_p->ipmc_stream[i][j];
    565                 p = flex_p->ipmc_port_list[port_idx];
    566                 cli_out("\t[%d]%4d ", j, p);
    567                 if (flex_p->ipmc_port_l3_copy_en[p] == 0) {
    568                     cli_out("%s/%d", "L2", 0);
    569                 } else {
    570                     cli_out("%s/%d", "L3", (flex_p->ipmc_num_rep[p] + 1));
    571                 }
    572             }
    573             cli_out("\n");
    574         }
    575         cli_out("\nipmc_num_ports/ipmc_num_avail_ports = %0d / %0d\n",
    576                 flex_p->num_ports_per_stream, flex_p->ipmc_port_list_size);
    577     }
    578 }
    579 
    580 /*
    581  * Function:
    582  *      flexport_ipmc_add_l3_intf
    583  * Purpose:
    584  *      This function actually sets up the IPMC packet flow. Please refer to
    585  *      items 4-6 of the "Test Setup" section of the test description at the
    586  *      beginning of this file.
    587  * Parameters:
    588  *      unit: StrataSwitch Unit #.
    589  *      port: physical port.
    590  *      mc_group: multicast group id.
    591  *      dst_vlan: used for vlan translation.
    592  *
    593  * Returns:
    594  *     Nothing.
    595  */
    596 static void
    597 flexport_ipmc_add_l3_intf(int unit, int port, bcm_multicast_t mc_group,
    598                  bcm_vlan_t dst_vlan)
    599 {
    600     pbmp_t pbm, ubm;
    601     bcm_vlan_t vlan;
    602     bcm_l3_intf_t l3_intf;
    603     bcm_if_t intf_id;
    604     bcm_if_t encap_id;
    605     uint32 intf_flags = 0;
    606     uint8  intf_mac[] = {0x00,0x00,0x00,0x00,0x00,0x00};
    607     bcm_gport_t gport;
    608     uint32 port_vlan_cnt;
    609     flexport_mc_t *flex_p = flexport_parray[unit];
    610 
    611     /* init */
    612     intf_flags |= BCM_L3_WITH_ID;
    613     BCM_PBMP_CLEAR(ubm);
    614 
    615     /* create vlan */
    616     vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++;
    617     bcm_vlan_create(unit, vlan);
    618     BCM_PBMP_CLEAR(pbm);
    619     BCM_PBMP_PORT_ADD(pbm, port);
    620     bcm_vlan_port_add(unit, vlan, pbm, ubm);
    621 
    622     /* create vlan_translate */
    623     bcm_vlan_translate_add(unit, port, vlan, dst_vlan, 0);
    624 
    625     /* update test variable */
    626     port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++;
    627     flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan;
    628 
    629     /* create l3_intf */
    630     bcm_l3_intf_t_init(&l3_intf);
    631     intf_id = (bcm_if_t) flex_p->ipmc_next_intf_id++;
    632     intf_mac[NUM_BYTES_MAC_ADDR - 1] = intf_id;
    633     intf_mac[NUM_BYTES_MAC_ADDR - 2] = intf_id >> 8;
    634     sal_memcpy(l3_intf.l3a_mac_addr, intf_mac, 6);
    635     l3_intf.l3a_vid = vlan;
    636     l3_intf.l3a_intf_id = intf_id;
    637     l3_intf.l3a_flags = intf_flags;
    638     bcm_l3_intf_create(unit, &l3_intf);
    639 
    640     /* add l3_intf into mc_group */
    641     bcm_multicast_l3_encap_get(unit, mc_group, port, intf_id, &encap_id);
    642     BCM_GPORT_LOCAL_SET(gport, port);
    643     bcm_multicast_egress_add(unit, mc_group, gport, encap_id);
    644 }
    645 
    646 /*
    647  * Function:
    648  *      flexport_ipmc_print_vlan_info
    649  * Purpose:
    650  *      Print IPMC vlan info.
    651  * Parameters:
    652  *      unit: StrataSwitch Unit #.
    653  *
    654  * Returns:
    655  *     Nothing.
    656  */
    657 static void
    658 flexport_ipmc_print_vlan_info(int unit)
    659 {
    660     int i, j, port_idx;
    661     int port, cnt, vlan_cnt;
    662     flexport_mc_t *flex_p = flexport_parray[unit];
    663 
    664     cli_out("\n=========== port vlan info ============\n");
    665     cli_out("%4s %4s %4s %4s %4s %4s \t%4s\n",
    666             "strm", "idx", "tsc", "port", "type", "vlan_cnt", "vlan_id");
    667 
    668     for (i = 0; i < flex_p->ipmc_num_streams; i++) {
    669         for (j = 0; j < flex_p->num_ports_per_stream; j++) {
    670             port_idx = flex_p->ipmc_stream[i][j];
    671             port     = flex_p->ipmc_port_list[port_idx];
    672             if (flex_p->ipmc_port_l3_copy_en[port] == -1) continue;
    673             cli_out("%4d ", i);
    674             cli_out("%4d %4d %4d ", j, (port-1)/4, port);
    675             if (flex_p->ipmc_port_l3_copy_en[port] == 0) {
    676                 cli_out("%4s ", "L2");
    677             } else {
    678                 cli_out("%4s ", "L3");
    679             }
    680             vlan_cnt = flex_p->ipmc_port_vlan_cnt[port];
    681             cli_out("%4d \t", vlan_cnt);
    682             for (cnt = 0; cnt < vlan_cnt; cnt++) {
    683                 cli_out("%4d  ", flex_p->ipmc_port_rep_vlan[port][cnt]);
    684             }
    685             cli_out("\n");
    686         }
    687         cli_out("\n");
    688     }
    689 }
    690 
    691 /*
    692  * Function:
    693  *      flexport_ipmc_set_up_streams
    694  * Purpose:
    695  *      This function actually sets up the IPMC packet flow. Please refer to
    696  *      items 4-6 of the "Test Setup" section of the test description at the
    697  *      beginning of this file.
    698  * Parameters:
    699  *      unit: StrataSwitch Unit #.
    700  *
    701  * Returns:
    702  *     Nothing.
    703  */
    704 static void
    705 flexport_ipmc_set_up_streams(int unit)
    706 {
    707     int i, j, k;
    708     pbmp_t pbm, ubm;
    709     bcm_vlan_t vlan, vlan_0 = 0, vlan_1 = 0, dst_vlan, drop_vlan;
    710     /* uint32 vlan, vlan_0 = 0, vlan_1 = 0; */
    711     bcm_multicast_t mc_group;
    712     uint32 mc_flags = 0;
    713     bcm_if_t intf_id;
    714     bcm_ipmc_addr_t ipmc_addr;
    715     uint32 ipmc_flags = 0;
    716     uint8 mac_sa[] = MAC_SA;
    717     int port;
    718     bcm_gport_t gport;
    719     uint32 port_vlan_cnt;
    720     flexport_mc_t *flex_p = flexport_parray[unit];
    721 
    722     /* init vlan setup */
    723     bcm_vlan_destroy_all(unit);
    724     bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE);
    725     BCM_PBMP_CLEAR(ubm);
    726     flex_p->ipmc_next_vlan = VLAN + SOC_MAX_NUM_PORTS + 10;
    727     flex_p->ipmc_next_drop_vlan = DROP_VLAN;
    728 
    729     (void) bcm_switch_control_set(unit, bcmSwitchL3EgressMode, TRUE);
    730     PBMP_ITER(flex_p->ipmc_pbmp, port) {
    731         (void) bcm_port_control_set(unit, port, bcmPortControlIP4, TRUE);
    732         (void) bcm_port_control_set(unit, port, bcmPortControlIP6, TRUE);
    733         (void) bcm_port_control_set(unit, port, bcmSwitchL3McIdxRetType, TRUE);
    734         (void) bcm_port_control_set(unit, port,
    735                                     bcmSwitchIpmcReplicationSharing, TRUE);
    736     }
    737 
    738     bcm_ipmc_enable(unit, TRUE);
    739     mc_group = (bcm_multicast_t)(FIRST_MC_GROUP);
    740     mc_flags = BCM_MULTICAST_TYPE_L3 | BCM_MULTICAST_WITH_ID;
    741     intf_id  = (bcm_if_t)(FIRST_INTF_ID);
    742     flex_p->ipmc_next_intf_id = (uint32) intf_id;
    743     ipmc_flags |= BCM_IPMC_SOURCE_PORT_NOCHECK;
    744 
    745     for (i = 0; i < flex_p->ipmc_num_streams; i++) {
    746         (void) bcm_multicast_create(unit, mc_flags, &mc_group);
    747         flex_p->ipmc_stream_mc_group[i] = mc_group;
    748 
    749         /* create drop_vlan */
    750         drop_vlan = (bcm_vlan_t) flex_p->ipmc_next_drop_vlan++;
    751         bcm_vlan_create(unit, drop_vlan);
    752         flex_p->ipmc_drop_vlan[i] = (uint32) drop_vlan;
    753         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
    754                     "\nstream = %0d, mc_group = 0x%0x, drop_vlan = %0d\n"),
    755                     i, mc_group, (uint32) drop_vlan));
    756 
    757         /* vlan_0 for P0 */
    758         vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++;
    759         bcm_vlan_create(unit, vlan);
    760         BCM_PBMP_CLEAR(pbm);
    761         port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]];
    762         BCM_PBMP_PORT_ADD(pbm, port);
    763         bcm_vlan_port_add(unit, vlan, pbm, ubm);
    764         vlan_0 = vlan;
    765 
    766         port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++;
    767         flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan;
    768 
    769         /* vlan_1 for ports receiving l2 copies, P0,P1,...,Pn */
    770         vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++;
    771         bcm_vlan_create(unit, vlan);
    772         BCM_PBMP_CLEAR(pbm);
    773         for (j = 0; j < flex_p->num_ports_per_stream; j++) {
    774             port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]];
    775             if (flex_p->ipmc_port_l3_copy_en[port] == 0) {
    776                 BCM_PBMP_PORT_ADD(pbm, port);
    777 
    778                 port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++;
    779                 flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan;
    780 
    781                 BCM_GPORT_LOCAL_SET(gport, port);
    782                 bcm_multicast_egress_add(unit, mc_group, gport,(bcm_if_t)(-1));
    783             }
    784         }
    785         bcm_vlan_port_add(unit, vlan, pbm, ubm);
    786         vlan_1 = vlan;
    787 
    788         /* vlan_xlate: P0: vlan_0 -> vlan_1 */
    789         port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]];
    790         bcm_vlan_translate_add(unit, port, vlan_0, vlan_1, 0);
    791 
    792         for (j = 1; j < flex_p->num_ports_per_stream; j++) {
    793             port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]];
    794             if (flex_p->ipmc_port_l3_copy_en[port] == 0) {
    795                 dst_vlan = (j == 1 ) ? vlan_0 : drop_vlan;
    796                 bcm_vlan_translate_add(unit, port, vlan_1, dst_vlan, 0);
    797             }
    798         }
    799 
    800         /* [L3 copy] */
    801         PBMP_ITER(PBMP_PORT_ALL(unit), port) {
    802             if (flexport_is_ipmc_port(unit, port)) {
    803                 if (port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]] ||
    804                     port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][1]])
    805                     continue;
    806                 for (k = 0; k < (flex_p->ipmc_num_rep[port] + 1); k++) {
    807                     flexport_ipmc_add_l3_intf(unit, port, mc_group, drop_vlan);
    808                 }
    809             }
    810         }
    811 
    812         bcm_ipmc_addr_t_init(&ipmc_addr);
    813         ipmc_addr.mc_ip_addr = DIP;
    814         ipmc_addr.s_ip_addr = SIP;
    815         ipmc_addr.vid = vlan_1;
    816         ipmc_addr.group = mc_group;
    817         ipmc_addr.flags = ipmc_flags;
    818         bcm_ipmc_add(unit, &ipmc_addr);
    819         mc_group++;
    820 
    821         flex_p->ipmc_tx_vlan[i]  = (uint32) vlan_0;
    822         flex_p->ipmc_exp_vlan[i] = (uint32) vlan_1;
    823         sal_memcpy(flex_p->ipmc_exp_mac_addr[i], mac_sa, 6);
    824 
    825         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
    826                     "\nstream=%0d, tx_vlan = %0d, rx_vlan = %0d\n"),
    827                     i, flex_p->ipmc_tx_vlan[i], flex_p->ipmc_exp_vlan[i]));
    828     }
    829 
    830     /* print vlan info */
    831     flexport_ipmc_print_vlan_info(unit);
    832 }
    833 
    834 /*
    835  * Function:
    836  *     flexport_get_port_pkt_size
    837  * Purpose:
    838  *     Get the packet size of given port.
    839  * Parameters:
    840  *      unit: StrataSwitch Unit #.
    841  *      port - Device port number
    842  *
    843  * Returns:
    844  *      Port packet size.
    845  */
    846 static uint32
    847 flexport_get_port_pkt_size(int unit, int port)
    848 {
    849     uint32 pkt_size;
    850     flexport_mc_t *flex_p = flexport_parray[unit];
    851 
    852     if (flex_p->pkt_size_param == 0) {
    853         pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port));
    854     } else {
    855         pkt_size = flex_p->pkt_size_param;
    856     }
    857 
    858     return (pkt_size);
    859 }
    860 
    861 /*
    862  * Function:
    863  *     flexport_get_lossless_flood_cnt
    864  * Purpose:
    865  *     Calculates no of packets to be set for the given port
    866  * Parameters:
    867  *      unit: StrataSwitch Unit #.
    868  *      port - Device port number
    869  *
    870  * Returns:
    871  *     flood packet count for the given port.
    872  */
    873 static uint32
    874 flexport_get_lossless_flood_cnt(int unit, int port)
    875 {
    876     uint32 pkt_size, flood_cnt = 0;
    877     flexport_mc_t *flex_p = flexport_parray[unit];
    878 
    879     if (flex_p->flood_pkt_cnt_param == 0) {
    880         pkt_size = flexport_get_port_pkt_size(unit, port);
    881         flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, NULL);
    882     } else {
    883         flood_cnt = flex_p->flood_pkt_cnt_param;
    884     }
    885 
    886     if (flood_cnt > MAX_PKTS_PER_STREAM) {
    887         flood_cnt = MAX_PKTS_PER_STREAM;
    888     }
    889 
    890     return (flood_cnt);
    891 }
    892 
    893 /*
    894  * Function:
    895  *      flexport_ipmc_send_pkts
    896  * Purpose:
    897  *      Send packets from CPU to create a swirl on each stream. Please refer
    898  *      to item 6 of the "Test Setup" portion of the test description at the
    899  *      beginning of this file.
    900  * Parameters:
    901  *      unit - StrataSwitch Unit #.
    902  *
    903  * Returns:
    904  *     Nothing
    905  */
    906 static void
    907 flexport_ipmc_send_pkts(int unit)
    908 {
    909     uint8 mac_da[] = MAC_DA;
    910     uint8 mac_sa[] = MAC_SA;
    911     uint32 pkt_size = 0, pkt_count = 0, flood_cnt = 0;
    912     int i, port;
    913     uint32 use_random_packet_sizes = 0;
    914     flexport_mc_t *flex_p = flexport_parray[unit];
    915     stream_pkt_t *tx_pkt;
    916 
    917     tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt");
    918     sal_memset(tx_pkt, 0, sizeof(stream_pkt_t));
    919 
    920     if (flex_p->pkt_size_param == 1) {
    921         use_random_packet_sizes = 1;
    922     }
    923 
    924     cli_out("\n==================================================\n");
    925     cli_out("\nSending packets ...\n\n");
    926     for (i = 0; i < flex_p->ipmc_num_streams; i++) {
    927         port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]];
    928         flood_cnt = flexport_get_lossless_flood_cnt(unit, port);
    929         pkt_size  = (flex_p->pkt_size_param == 0) ?
    930                     ENET_WC_PKT_SIZE : flex_p->pkt_size_param;
    931 
    932         tx_pkt->l3_en    = 1;
    933         tx_pkt->ipv6_en  = 0;
    934         tx_pkt->ip_da    = DIP;
    935         tx_pkt->ip_sa    = SIP;
    936         tx_pkt->ttl      = TTL;
    937         tx_pkt->port     = port;
    938         tx_pkt->num_pkt  = flood_cnt;
    939         tx_pkt->pkt_seed = flex_p->pkt_seed + i;
    940         tx_pkt->pkt_size = pkt_size;
    941         tx_pkt->tx_vlan  = flex_p->ipmc_tx_vlan[i];
    942         sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR);
    943         sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR);
    944         tx_pkt->rand_pkt_size_en = use_random_packet_sizes;
    945         tx_pkt->rand_pkt_size    = NULL;
    946         if (tx_pkt->rand_pkt_size_en) {
    947             tx_pkt->rand_pkt_size = flex_p->ipmc_rand_pkt_sizes;
    948         }
    949 
    950         stream_tx_pkt(unit, tx_pkt);
    951 
    952         pkt_count += tx_pkt->cnt_pkt;
    953         cli_out("flood_cnt for stream %0d = %0d\n", i, tx_pkt->cnt_pkt);
    954     }
    955 
    956     cli_out("\nTotal packet sent: %0d\n\n", pkt_count);
    957     sal_free(tx_pkt);
    958 }
    959 
    960 /*
    961  * Function:
    962  *      flexport_ipmc_chk_rate
    963  * Purpose:
    964  *      Check actual port rates against expected port rates.
    965  * Parameters:
    966  *      unit - StrataSwitch Unit #.
    967  *
    968  * Returns:
    969  *     SOC_E_XXXX
    970  */
    971 static bcm_error_t
    972 flexport_ipmc_chk_rate(int unit)
    973 {
    974     int i, j, port, port_idx;
    975     bcm_error_t rv = BCM_E_NONE;
    976     stream_rate_t *rate_calc;
    977     flexport_mc_t *flex_p = flexport_parray[unit];
    978 
    979     /* check mib counters */
    980     if (flex_p->check_mib_param == 1) {
    981         if (stream_chk_mib_counters(unit, flex_p->ipmc_pbmp, 0) != BCM_E_NONE) {
    982             flex_p->test_fail = 1;
    983         }
    984     }
    985 
    986     /* check rate */
    987     if(!flex_p->check_rate_param) return rv;
    988     rate_calc = (stream_rate_t *)
    989                  sal_alloc(sizeof(stream_rate_t), "rate_calc");
    990     if (rate_calc == NULL) {
    991         test_error(unit, "Failed to allocate memory for rate_calc\n");
    992         return BCM_E_FAIL;
    993     }
    994     sal_memset(rate_calc, 0, sizeof(stream_rate_t));
    995 
    996     rate_calc->mode         = 1;
    997     rate_calc->pkt_size     = flex_p->pkt_size_param;
    998     rate_calc->interval_len = flex_p->rate_calc_interval_param;
    999     rate_calc->tolerance_lr = flex_p->rate_tolerance_lr_param;
   1000     rate_calc->tolerance_os = flex_p->rate_tolerance_os_param;
   1001 
   1002     SOC_PBMP_CLEAR(rate_calc->pbmp);
   1003     for (i = 0; i < flex_p->ipmc_num_streams; i++) {
   1004         for (j = 0; j < flex_p->num_ports_per_stream; j++) {
   1005             port_idx = flex_p->ipmc_stream[i][j];
   1006             port = flex_p->ipmc_port_list[port_idx];
   1007             if (port < SOC_MAX_NUM_PORTS && port < TEST_COVERITY_PBMP_WID) {
   1008                 if (flex_p->ipmc_port_l3_copy_en[port] == -1) continue;
   1009                 /* pbmp */
   1010                 SOC_PBMP_PORT_ADD((rate_calc->pbmp), port);
   1011                 /* num_l3_rep */
   1012                 if (flex_p->ipmc_port_l3_copy_en[port] == 0) {
   1013                     rate_calc->num_rep[port] = 0;
   1014                 } else {
   1015                     rate_calc->num_rep[port] = flex_p->ipmc_num_rep[port] + 1;
   1016                 }
   1017                 /* src_port */
   1018                 rate_calc->src_port[port] =
   1019                         flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]];
   1020             }
   1021         }
   1022     }
   1023 
   1024     rv = stream_chk_port_rate(unit, flex_p->ipmc_pbmp, rate_calc);
   1025     if (rv != BCM_E_NONE) flex_p->test_fail = 1;
   1026 
   1027     sal_free(rate_calc);
   1028     return rv;
   1029 }
   1030 
   1031 /*
   1032  * Function:
   1033  *      flexport_ipmc_chk_integrity_l3
   1034  * Purpose:
   1035  *      Redirect all packets back to CPU and check packet integrity
   1036  * Parameters:
   1037  *      unit - StrataSwitch Unit #.
   1038  *      pkt_intg - ptr to packet integrity struct, containing all necessary
   1039  *                 parameters needed for integrity check.
   1040  *
   1041  * Returns:
   1042  *     SOC_E_XXXX
   1043  */
   1044 static bcm_error_t
   1045 flexport_ipmc_chk_integrity_l3(int unit, stream_integrity_t *pkt_intg)
   1046 {
   1047     bcm_error_t rv = BCM_E_NONE;
   1048     uint8 *rx_pkt, *ref_pkt;
   1049     int i, j, k, port, port_speed, chk_fail = 0, stream_cnt = 0;
   1050     int rst_vlan;
   1051     dv_t *dv_rx;
   1052     uint32 vlan;
   1053     uint32 pkt_size;
   1054     uint32 port_exp_pkt_cnt, port_act_pkt_cnt, pkt_cnt_sum = 0;
   1055     uint32 header_size = 0;
   1056     uint32 rx_vlan;
   1057     flexport_mc_t *flex_p = flexport_parray[unit];
   1058 
   1059     cli_out("\n==================================================\n");
   1060     cli_out("IPMC Checking Packet Integrity ...\n\n");
   1061     /* initialize */
   1062     soc_dma_header_size_get(unit, &header_size);
   1063 
   1064     dv_rx   = soc_dma_dv_alloc(unit, DV_RX, 3);
   1065     ref_pkt = sal_dma_alloc(MTU * sizeof(uint8), "ref_packet");
   1066     rx_pkt  = sal_dma_alloc(MTU * sizeof(uint8) + header_size, "rx_pkt");
   1067     if (dv_rx == NULL || ref_pkt == NULL || rx_pkt == NULL) {
   1068         soc_dma_dv_free(unit, dv_rx);
   1069         sal_dma_free(ref_pkt);
   1070         sal_dma_free(rx_pkt);
   1071         test_error(unit, "Failed to allocate memory for integrity check\n");
   1072         return BCM_E_FAIL;
   1073     }
   1074 
   1075     /* config all channels as RX */
   1076     soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 1, 0xffffffff);
   1077     soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 2, 0xffffffff);
   1078 
   1079     /* config unmatched VLAN packet to be forwarded to CPU */
   1080     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_0r, 0,
   1081                                                UVLAN_TOCPUf, 0x1));
   1082     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_1r, 0,
   1083                                                L3_MTU_FAIL_TOCPUf, 0x1));
   1084 
   1085     /* check packet integrity for each port */
   1086     LOG_INFO(BSL_LS_APPL_TESTS,
   1087              (BSL_META_U(unit, "%4s %4s %4s %8s %8s\n"),
   1088                          "idx", "port", "spd", "tx_pkt", "rx_pkt"));
   1089     PBMP_ITER(pkt_intg->rx_pbmp, port) {
   1090         if (port < SOC_MAX_NUM_PORTS) {
   1091             /* check integrity of each packet */
   1092             port_exp_pkt_cnt = pkt_intg->port_flood_cnt[port];
   1093             port_act_pkt_cnt = 0;
   1094             vlan = pkt_intg->rx_vlan[port];
   1095 
   1096             for (j = 0; j < port_exp_pkt_cnt; j++) {
   1097                 rst_vlan = 0;
   1098                 if (j == 0) {
   1099                     if (pkt_intg->type == PKT_TYPE_L3UC) {
   1100                         rst_vlan = 2; /* L3 packet*/
   1101                     } else {
   1102                         rst_vlan = 1; /* L2 packet*/
   1103                     }
   1104                 }
   1105                 /* receive one packet from CPU though rx_pkt_dma */
   1106                 if (stream_pktdma_rx(unit, rst_vlan, vlan, dv_rx, rx_pkt,
   1107                                      MTU + header_size) != BCM_E_NONE) {
   1108                     break;
   1109                 }
   1110                 port_act_pkt_cnt ++;
   1111 
   1112                 /* record rx_vlan */
   1113                 rx_vlan = (rx_pkt[14+header_size] << 8) +
   1114                           rx_pkt[15+header_size];
   1115                 flex_p->ipmc_cpu_rx_vlan_cnt[rx_vlan]++;
   1116 
   1117                 /* generate reference packet */
   1118                 if (stream_gen_ref_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt,
   1119                                        &pkt_size) != BCM_E_NONE) {
   1120                     cli_out("*ERROR, failed to generate ref_pkt "
   1121                             "for integrity check, port %d\n",
   1122                             port);
   1123                     chk_fail = 1;
   1124                     break;
   1125                 }
   1126 
   1127                 /* check packet content (payload) */
   1128                 for (k = 0; k < (pkt_size - NUM_BYTES_CRC); k++) {
   1129                     if (rx_pkt[k + header_size] != ref_pkt[k]) {
   1130                         /* mac_sa and vlan are used for rep identification */
   1131                         if (( 6 <= k && k <= 11) || /* mac_sa */
   1132                             (14 <= k && k <= 15))   /* vlan   */
   1133                             continue;
   1134 
   1135                         cli_out("*ERROR: Packet corruption, "
   1136                                 "Stream %d, Port %3d, Packet %d, "
   1137                                 "pkt_size=%0d, header_size=%0d, k=%0d, "
   1138                                 "rx_pkt[%0d]=0x%0x, ref_pkt[%0d]=0x%0x\n",
   1139                                 stream_cnt, port, j,
   1140                                 pkt_size, header_size, k,
   1141                                 k + header_size, rx_pkt[k + header_size],
   1142                                 k, ref_pkt[k]);
   1143 
   1144                         cli_out("-- Expected Packet:");
   1145                         tgp_print_pkt(ref_pkt, pkt_size);
   1146                         cli_out("-- Received Packet:");
   1147                         tgp_print_pkt(rx_pkt, pkt_size+header_size);
   1148 
   1149                         chk_fail = 1;
   1150                         break;
   1151                     }
   1152                 }
   1153             }
   1154 
   1155             /* disable forwarding pkt to cpu for current port */
   1156             if (pkt_intg->type == PKT_TYPE_L3UC) {
   1157                 stream_set_l3mtu_valid(unit, vlan);
   1158             } else {
   1159                 stream_set_vlan_valid(unit, vlan);
   1160             }
   1161 
   1162             /* check packet count */
   1163             bcm_port_speed_get(unit, port, &port_speed);
   1164             LOG_INFO(BSL_LS_APPL_TESTS,
   1165                      (BSL_META_U(unit, "%4d %4d %3dG %8d %8d "),
   1166                                  stream_cnt, port, port_speed/1000,
   1167                                  port_exp_pkt_cnt, port_act_pkt_cnt));
   1168             if (port_act_pkt_cnt == 0) {
   1169                 chk_fail = 1;
   1170                 LOG_INFO(BSL_LS_APPL_TESTS,
   1171                          (BSL_META_U(unit, "*WARNING")));
   1172             } else if (port_act_pkt_cnt < port_exp_pkt_cnt &&
   1173                 !(SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))) {
   1174                 chk_fail = 1;
   1175                 LOG_INFO(BSL_LS_APPL_TESTS,
   1176                          (BSL_META_U(unit, "*WARNING")));
   1177             }
   1178             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
   1179 
   1180             pkt_cnt_sum += port_act_pkt_cnt;
   1181             stream_cnt++;
   1182         }
   1183     }
   1184 
   1185     /* check l3 copy: at least one pkt of each l3 replication is received. */
   1186     {
   1187         int vlan_num, port_idx, pkt_cnt, k;
   1188         LOG_INFO(BSL_LS_APPL_TESTS,
   1189                  (BSL_META_U(unit, "Check Port L3 Replication Reception\n")));
   1190         LOG_INFO(BSL_LS_APPL_TESTS,
   1191                  (BSL_META_U(unit, "%4s %4s %6s %8s\n"),
   1192                              "port", "rep", "vlan", "pkt_cnt"));
   1193 
   1194         for (i = 0; i < flex_p->ipmc_num_streams; i++) {
   1195             for (j = 0; j < flex_p->num_ports_per_stream; j++) {
   1196                 port_idx = flex_p->ipmc_stream[i][j];
   1197                 port     = flex_p->ipmc_port_list[port_idx];
   1198                 if (flex_p->ipmc_port_l3_copy_en[port] != 1) continue;
   1199 
   1200                 for (k = 0; k < flex_p->ipmc_port_vlan_cnt[port]; k++){
   1201                     vlan_num= flex_p->ipmc_port_rep_vlan[port][k];
   1202                     pkt_cnt = flex_p->ipmc_cpu_rx_vlan_cnt[vlan_num];
   1203                     LOG_INFO(BSL_LS_APPL_TESTS,
   1204                              (BSL_META_U(unit, "%4d %4d %4d %4d"),
   1205                                          port, k, vlan_num, pkt_cnt));
   1206                     if (flex_p->ipmc_cpu_rx_vlan_cnt[vlan_num] == 0) {
   1207                         chk_fail = 1;
   1208                         LOG_INFO(BSL_LS_APPL_TESTS,
   1209                                  (BSL_META_U(unit,
   1210                                     "\t*ERROR, no l3 packet received")));
   1211                     }
   1212                     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
   1213                 }
   1214             }
   1215         }
   1216     }
   1217 
   1218     cli_out("Total packets received: %d\n", pkt_cnt_sum);
   1219     if (chk_fail == 0) {
   1220         cli_out("\n**** PACKET INTEGRITY CHECK PASSED *****\n");
   1221     } else {
   1222         cli_out("\n**** PACKET INTEGRITY CHECK FAILED *****\n");
   1223         rv = BCM_E_FAIL;
   1224     }
   1225 
   1226     soc_dma_abort_dv(unit, dv_rx);
   1227     soc_dma_dv_free(unit, dv_rx);
   1228     sal_dma_free(rx_pkt);
   1229     sal_dma_free(ref_pkt);
   1230 
   1231     return rv;
   1232 }
   1233 
   1234 /*
   1235  * Function:
   1236  *      flexport_ipmc_chk_integrity
   1237  * Purpose:
   1238  *      Redirect all packets back to CPU and check packet integrity
   1239  * Parameters:
   1240  *      unit - StrataSwitch Unit #.
   1241  *
   1242  * Returns:
   1243  *     Nothing
   1244  */
   1245 static bcm_error_t
   1246 flexport_ipmc_chk_integrity(int unit)
   1247 {
   1248     int i, port;
   1249     uint32 flood_cnt;
   1250     uint8 mac_da[] = MAC_DA;
   1251     stream_integrity_t *pkt_intg;
   1252     bcm_error_t rv = BCM_E_NONE;
   1253     flexport_mc_t *flex_p = flexport_parray[unit];
   1254 
   1255     if (!flex_p->check_integrity_param) return rv;
   1256 
   1257     pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg");
   1258     if (pkt_intg == NULL) {
   1259         test_error(unit, "Failed to allocate memory for pkt_intg\n");
   1260         return BCM_E_FAIL;
   1261     }
   1262     sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
   1263 
   1264     pkt_intg->type = PKT_TYPE_IPMC;
   1265     pkt_intg->ipv6_en = 0;
   1266     SOC_PBMP_CLEAR(pkt_intg->rx_pbmp);
   1267     for (i = 0; i < flex_p->ipmc_num_streams; i++) {
   1268         port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]];
   1269         if (port < SOC_MAX_NUM_PORTS && port < TEST_COVERITY_PBMP_WID) {
   1270             /* rx_pbmp */
   1271             SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port);
   1272 
   1273             /* rx_vlan: used to forward pkt to CPU */
   1274             pkt_intg->rx_vlan[port] = flex_p->ipmc_drop_vlan[i];
   1275 
   1276             /* tx_vlan: used to re-generate ref_pkt */
   1277             pkt_intg->tx_vlan[port] = flex_p->ipmc_exp_vlan[i];
   1278 
   1279             /* port_flood_cnt */
   1280             /* flood_cnt = flexport_get_lossless_flood_cnt(unit, port); */
   1281             flood_cnt = flex_p->num_ports_per_stream *
   1282                         flex_p->ipmc_num_l3_ports_param * 30;
   1283             pkt_intg->port_flood_cnt[port] = flood_cnt;
   1284 
   1285             /* port_pkt_seed */
   1286             pkt_intg->port_pkt_seed[port] = flex_p->pkt_seed + i;
   1287 
   1288             /* mac_da, mac_sa */
   1289             sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR);
   1290             sal_memcpy(pkt_intg->mac_sa[port], flex_p->ipmc_exp_mac_addr[i],
   1291                        NUM_BYTES_MAC_ADDR);
   1292 
   1293             /* ip_da, ip_sa */
   1294             pkt_intg->ip_da[port] = DIP;
   1295             pkt_intg->ip_sa[port] = SIP;
   1296         }
   1297     }
   1298 
   1299     if (flexport_ipmc_chk_integrity_l3(unit, pkt_intg) != BCM_E_NONE) {
   1300         flex_p->test_fail = 1;
   1301         rv = BCM_E_FAIL;
   1302     }
   1303 
   1304     sal_free(pkt_intg);
   1305     return rv;
   1306 }
   1307 
   1308 /*
   1309  * Function:
   1310  *      flexport_call_bcm_api
   1311  * Purpose:
   1312  *      Call the bcm_port_resource_multi_set API
   1313  * Parameters:
   1314  *      unit - StrataSwitch Unit #.
   1315  *
   1316  * Returns:
   1317  *     SOC_E_XXXX
   1318  */
   1319 static bcm_error_t
   1320 flexport_call_bcm_api(int unit)
   1321 {
   1322     flexport_mc_t *flex_p = flexport_parray[unit];
   1323     int i;
   1324     bcm_port_t lport;
   1325     uint32 nports;
   1326     bcm_port_resource_t *resource;
   1327     bcm_error_t rv;
   1328 
   1329     nports = flex_p->flex_num_del + flex_p->flex_num_add;
   1330     resource = (bcm_port_resource_t *) sal_alloc(nports *
   1331                                                  sizeof(bcm_port_resource_t),
   1332                                                  "flexport_resource_array");
   1333     sal_memset(resource, 0, sizeof(bcm_port_resource_t));
   1334 
   1335     for (i = 0; i < flex_p->flex_num_del; i ++) {
   1336         resource[i] = flex_p->flex_resource_del[i];
   1337     }
   1338     for (i = 0; i < flex_p->flex_num_add; i ++) {
   1339         resource[flex_p->flex_num_del + i] = flex_p->flex_resource_add[i];
   1340     }
   1341 
   1342     PBMP_ITER(flex_p->flex_lport_dn_pbmp, lport) {
   1343         if (lport < SOC_MAX_NUM_PORTS) {
   1344             rv = bcm_port_enable_set(unit, lport, 0);
   1345             if (BCM_FAILURE(rv)) {
   1346                 cli_out("\nbcm_port_disable_set %0d: %s",
   1347                         lport, bcm_errmsg(rv));
   1348                 sal_free(resource);
   1349                 return rv;
   1350             }
   1351         }
   1352     }
   1353 
   1354     LOG_INFO(BSL_LS_APPL_TESTS,
   1355              (BSL_META_U(unit, "\nCalling bcm_port_resource_multi:")));
   1356     for (i = 0; i < nports; i ++) {
   1357         LOG_INFO(BSL_LS_APPL_TESTS,
   1358                  (BSL_META_U(unit, "\nresource[%3d]: pport = %3d, "),
   1359                              i, resource[i].physical_port));
   1360         LOG_INFO(BSL_LS_APPL_TESTS,
   1361                  (BSL_META_U(unit, "lport  = %3d, "),
   1362                              resource[i].port));
   1363         LOG_INFO(BSL_LS_APPL_TESTS,
   1364                  (BSL_META_U(unit, "speed = %3dG, "),
   1365                              resource[i].speed/1000));
   1366         LOG_INFO(BSL_LS_APPL_TESTS,
   1367                  (BSL_META_U(unit, "lanes = %0d, "),
   1368                              resource[i].lanes));
   1369         LOG_INFO(BSL_LS_APPL_TESTS,
   1370                  (BSL_META_U(unit, "encap = %0d"),
   1371                              resource[i].encap));
   1372     }
   1373     rv = bcm_port_resource_multi_set(unit, nports, resource);
   1374     if (BCM_FAILURE(rv)) {
   1375         cli_out("\nbcm_port_resource_multi_set: %s", bcm_errmsg(rv));
   1376         sal_free(resource);
   1377         return rv;
   1378     }
   1379 
   1380     cli_out("\nWait 20s for TSC configuration changes to take effect\n");
   1381     sal_sleep(20);
   1382 
   1383     PBMP_ITER(flex_p->flex_lport_up_pbmp, lport) {
   1384         if (lport < SOC_MAX_NUM_PORTS) {
   1385             rv = bcm_port_enable_set(unit, lport, 1);
   1386             if (BCM_FAILURE(rv)) {
   1387                 cli_out("\nbcm_port_enable_set %0d: %s", lport, bcm_errmsg(rv));
   1388                 sal_free(resource);
   1389                 return rv;
   1390             }
   1391         }
   1392     }
   1393 
   1394     sal_free(resource);
   1395 
   1396     return BCM_E_NONE;
   1397 }
   1398 
   1399 
   1400 /*
   1401  * Function:
   1402  *      flexport_ipmc_update_stream
   1403  * Purpose:
   1404  *      This function actually sets up the IPMC packet flow. Please refer to
   1405  *      items 4-6 of the "Test Setup" section of the test description at the
   1406  *      beginning of this file.
   1407  * Parameters:
   1408  *      unit: StrataSwitch Unit #.
   1409  *
   1410  * Returns:
   1411  *     Nothing.
   1412  */
   1413 static void
   1414 flexport_ipmc_update_stream(int unit)
   1415 {
   1416     int i, j, stream_id, port, port_idx, port_exist;
   1417     flexport_mc_t *flex_p = flexport_parray[unit];
   1418 
   1419     stream_id = 0;
   1420     PBMP_ITER(flex_p->ipmc_pbmp, port) {
   1421         if (SOC_PBMP_MEMBER(flex_p->flex_lport_up_pbmp, port)) {
   1422             /* if port exists in stream, continue */
   1423             port_exist = 0;
   1424             i = stream_id;
   1425             for (j = 0; j < flex_p->num_ports_per_stream; j++) {
   1426                 if (port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]]) {
   1427                     port_exist = 1;
   1428                     break;
   1429                 }
   1430             }
   1431             if (port_exist) continue;
   1432 
   1433             /* add port to stream */
   1434             port_exist = 0;
   1435             for (j = 0; j < flex_p->ipmc_port_list_size; j++) {
   1436                 if (port == flex_p->ipmc_port_list[j]) {
   1437                     port_exist = 1;
   1438                     break;
   1439                 }
   1440             }
   1441             if (port_exist) {
   1442                 port_idx = j;
   1443             } else {
   1444                 port_idx = flex_p->ipmc_port_list_size++;
   1445                 flex_p->ipmc_port_list[port_idx] = port;
   1446             }
   1447             flex_p->ipmc_stream[i][flex_p->num_ports_per_stream++] = port_idx;
   1448             flex_p->ipmc_port_l3_copy_en[port] = 1;
   1449 
   1450             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   1451                         "[IPMC] add lport %3d to mc stream\n"), port));
   1452         }
   1453     }
   1454     PBMP_ITER(flex_p->flex_lport_dn_pbmp, port) {
   1455         if (flexport_is_ipmc_port(unit, port) &&
   1456             !SOC_PBMP_MEMBER(flex_p->flex_lport_up_pbmp, port)) {
   1457             flex_p->ipmc_port_l3_copy_en[port] = -1;
   1458 
   1459             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   1460                         "[IPMC] remove lport %3d from mc stream\n"), port));
   1461         }
   1462     }
   1463 
   1464     /* print */
   1465     flexport_ipmc_print_vlan_info(unit);
   1466 }
   1467 
   1468 /*
   1469  * Function:
   1470  *      flexport_flex_ports
   1471  * Purpose:
   1472  *      flex ports.
   1473  *        -- do flex by calling bcm apis.
   1474  *        -- set test env for up-ports.
   1475  *        -- send traffic
   1476  *        -- measure rate
   1477  *        --
   1478  *        --
   1479  * Parameters:
   1480  *      unit: StrataSwitch Unit #.
   1481  *      port_pbmp: port bitmap for down ports.
   1482  *
   1483  * Returns:
   1484  *     BCM_E_XXXX
   1485  */
   1486 static bcm_error_t
   1487 flexport_flex_ports(int unit)
   1488 {
   1489     pbmp_t start_traffic_pbmp;
   1490     flexport_mc_t *flex_p = flexport_parray[unit];
   1491     uint64 val64;
   1492     int rv = BCM_E_NONE;
   1493 
   1494     /* call bcm apis. */
   1495     if (flex_p->flex_num_del + flex_p->flex_num_add > 0) {
   1496         stream_set_lpbk(unit, flex_p->flex_lport_dn_pbmp,
   1497                         BCM_PORT_LOOPBACK_NONE);
   1498         flexport_call_bcm_api(unit);
   1499         stream_set_lpbk(unit, flex_p->flex_lport_up_pbmp,
   1500                         flex_p->loopback_mode_param);
   1501     }
   1502 
   1503     /* set test env for up-ports */
   1504     SOC_PBMP_CLEAR(start_traffic_pbmp);
   1505     start_traffic_pbmp = flex_p->flex_lport_up_pbmp;
   1506     BCM_PBMP_OR(start_traffic_pbmp, flex_p->flex_lport_ch_pbmp);
   1507 
   1508     /* clear counter */
   1509     if (flex_p->clear_new_port_cnt_param) {
   1510         COMPILER_64_ZERO(val64);
   1511         BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit, start_traffic_pbmp,
   1512                                                     val64));
   1513     }
   1514 
   1515     /* turn off fc for up_ports */
   1516     stream_turn_off_fc(unit, flex_p->flex_lport_up_pbmp);
   1517 
   1518     return rv;
   1519 }
   1520 
   1521 /*
   1522  * Function:
   1523  *      flexport_get_tsc_speed_by_mode
   1524  * Purpose:
   1525  *      Get tsc speed list by converting tsc mode from string to int.
   1526  * Parameters:
   1527  *      unit: StrataSwitch Unit #.
   1528  *      tsc: TSC #
   1529  *      mode: target port speed/mode
   1530  *      speed: prt to tsc speed list
   1531  *
   1532  * Returns:
   1533  *     BCM_E_XXXX
   1534  */
   1535 static bcm_error_t
   1536 flexport_get_tsc_speed_by_mode(int unit, uint32 tsc, char *mode, int* speed)
   1537 {
   1538     int rv = BCM_E_NONE;
   1539     int i;
   1540 
   1541     for (i = 0; i < NUM_LANES_PER_TSC; i++) speed[i] = 0;
   1542 
   1543     if (sal_strstr(mode, "4x0G")) {
   1544         return rv;
   1545     } else if (sal_strstr(mode, "1x100G") || sal_strstr(mode, "1x106G")) {
   1546         speed[0] = 100000;
   1547     } else if (sal_strstr(mode, "50G+2x25G")) {
   1548         speed[0] = 50000; speed[2] = 25000; speed[3] = 25000;
   1549     } else if (sal_strstr(mode, "2x25G+50G")) {
   1550         speed[0] = 25000; speed[1] = 25000; speed[2] = 50000;
   1551     } else if (sal_strstr(mode, "20G+2x10G")) {
   1552         speed[0] = 20000; speed[2] = 10000; speed[3] = 10000;
   1553     } else if (sal_strstr(mode, "2x10G+20G")) {
   1554         speed[0] = 10000; speed[1] = 10000; speed[2] = 20000;
   1555     } else if (sal_strstr(mode, "40G+2x10G")) {
   1556         speed[0] = 40000; speed[2] = 10000; speed[3] = 10000;
   1557     } else if (sal_strstr(mode, "2x10G+40G")) {
   1558         speed[0] = 10000; speed[1] = 10000; speed[2] = 40000;
   1559     } else if (sal_strstr(mode, "1x50G") || sal_strstr(mode, "1x53G")) {
   1560         speed[0] = 50000;
   1561     } else if (sal_strstr(mode, "1x40G") || sal_strstr(mode, "1x42G")) {
   1562         speed[0] = 40000;
   1563     } else if (sal_strstr(mode, "1x25G") || sal_strstr(mode, "1x27G")) {
   1564         speed[0] = 25000;
   1565     } else if (sal_strstr(mode, "1x20G") || sal_strstr(mode, "1x21G")) {
   1566         speed[0] = 20000;
   1567     } else if ((sal_strstr(mode, "1x10G") || sal_strstr(mode, "1x11G"))) {
   1568         speed[0] = 10000;
   1569     } else if (sal_strstr(mode, "2x50G") || sal_strstr(mode, "2x53G")) {
   1570         speed[0] = 50000; speed[2] = 50000;
   1571     } else if (sal_strstr(mode, "2x40G") || sal_strstr(mode, "2x42G")) {
   1572         speed[0] = 40000; speed[2] = 40000;
   1573     } else if (sal_strstr(mode, "2x25G") || sal_strstr(mode, "2x27G")) {
   1574         speed[0] = 25000; speed[2] = 25000;
   1575     } else if (sal_strstr(mode, "2x20G") || sal_strstr(mode, "2x21G")) {
   1576         speed[0] = 20000; speed[2] = 20000;
   1577     } else if (sal_strstr(mode, "2x10G") || sal_strstr(mode, "2x11G")) {
   1578         speed[0] = 10000; speed[2] = 10000;
   1579     } else if (sal_strstr(mode, "40G+20G")) {
   1580         speed[0] = 40000; speed[2] = 20000;
   1581     } else if (sal_strstr(mode, "20G+40G")) {
   1582         speed[0] = 20000; speed[2] = 40000;
   1583     } else if (sal_strstr(mode, "4x25G") || sal_strstr(mode, "4x27G")) {
   1584         speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000;
   1585     } else if (sal_strstr(mode, "4x10G") || sal_strstr(mode, "4x11G")) {
   1586         speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000;
   1587     } else if (sal_strstr(mode, "4x1G")) {
   1588         speed[0] = 1000; speed[1] = 1000; speed[2] = 1000; speed[3] = 1000;
   1589     } else if (sal_strstr(mode, "10G_25G_mix")) {
   1590         int subport_bmp = sal_rand() % 16;
   1591         speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000;
   1592         if (subport_bmp & 1) speed[0] = 10000;
   1593         if (subport_bmp & 2) speed[1] = 10000;
   1594         if (subport_bmp & 4) speed[2] = 10000;
   1595         if (subport_bmp & 8) speed[3] = 10000;
   1596     } else {
   1597         test_error(unit, "*ERROR: Mode %s is not supported\n", mode);
   1598     }
   1599 
   1600     return rv;
   1601 }
   1602 
   1603 /*
   1604  * Function:
   1605  *      flexport_get_tsc_encap_by_mode
   1606  * Purpose:
   1607  *      Get tsc encap (HiGig or Enthernet) by tsc mode.
   1608  * Parameters:
   1609  *      unit: StrataSwitch Unit #.
   1610  *      tsc: TSC #
   1611  *      mode: target port speed/mode
   1612  *
   1613  * Returns:
   1614  *     BCM_E_XXXX
   1615  */
   1616 static bcm_error_t
   1617 flexport_get_tsc_encap_by_mode(int unit, uint32 tsc, char *mode, int *encap)
   1618 {
   1619     int rv = BCM_E_NONE;
   1620     int encap_enum = BCM_PORT_ENCAP_IEEE;
   1621 
   1622     if (sal_strstr(mode, "11G") || sal_strstr(mode, "21G") ||
   1623         sal_strstr(mode, "27G") || sal_strstr(mode, "53G") ||
   1624         sal_strstr(mode, "42G") || sal_strstr(mode, "106G") ||
   1625         sal_strstr(mode, "127G")) {
   1626         encap_enum = BCM_PORT_ENCAP_HIGIG2;
   1627     } else {
   1628         encap_enum = BCM_PORT_ENCAP_IEEE;
   1629     }
   1630     (*encap) = encap_enum;
   1631 
   1632     return rv;
   1633 }
   1634 
   1635 /*
   1636  * Function:
   1637  *      flexport_get_speed_lanes
   1638  * Purpose:
   1639  *      Converts hex string to 4-bit binary map
   1640  * Parameters:
   1641  *      unit - StrataSwitch Unit #.
   1642  *      num_subport: number of subports
   1643  *      speed: pointer to a port speed array
   1644  *      lanes: pointer to a lane array
   1645  *
   1646  * Returns:
   1647  *     Nothing
   1648  */
   1649 static void
   1650 flexport_get_speed_lanes(int unit, int num_subport, int *speed, int *lanes)
   1651 {
   1652     int i;
   1653 
   1654     for (i = 0; i < num_subport; i++) {
   1655         switch(speed[i]) {
   1656             case   1000 : lanes[i] = 1; break;
   1657             case  10000 : lanes[i] = 1; break;
   1658             case  20000 : lanes[i] = 2; break;
   1659             case  25000 : lanes[i] = 1; break;
   1660             case  40000 : lanes[i] = ((i==0) && (speed[2] == 0))? 4 : 2; break;
   1661             case  50000 : lanes[i] = 2; break;
   1662             case 100000 : lanes[i] = 4; break;
   1663             default     : lanes[i] = 0; break;
   1664         }
   1665     }
   1666 }
   1667 
   1668 /*
   1669  * Function:
   1670  *      flexport_assign_lport_by_pport
   1671  * Purpose:
   1672  *      Find an available logical port number for given physical up-port.
   1673  * Parameters:
   1674  *      unit - StrataSwitch Unit #.
   1675  *      pport: physical port number.
   1676  *
   1677  * Returns:
   1678  *     Return -1 if there is no available logical port.
   1679  *     Otherwise return a valid unused logial port number.
   1680  */
   1681 static int
   1682 flexport_assign_lport_by_pport(int unit, int pport)
   1683 {
   1684     int lport = -1;
   1685 
   1686     /* Maverick2: mv2 has flexed p2l mapping, 32 lport per halfpipe. */
   1687     if (SOC_IS_MAVERICK2(unit)) {
   1688         lport = ((pport >= 1  && pport <= 32) ||
   1689                  (pport >= 41 && pport <= 64)) ? pport : -1;
   1690     }
   1691     else if (SOC_IS_HELIX5(unit)) {
   1692         lport = (pport <= 68) ? (pport) : (-1);
   1693     }
   1694     /* Trident3: td3 has fixed p2l mapping */
   1695     else if (SOC_IS_TRIDENT3(unit)) {
   1696         lport = (pport > 64) ? (2 + pport) : (pport);
   1697     }
   1698     /* default */
   1699     else {
   1700         lport = (pport > 64) ? (2 + pport) : (pport);
   1701     }
   1702 
   1703     return lport;
   1704 }
   1705 
   1706 /*
   1707  * Function:
   1708  *      flexport_fill_resource_per_tsc
   1709  * Purpose:
   1710  *      Prepare port_dn_pbmp, port_up_pbmp and port_ch_pbmp for one TSC.
   1711  * Parameters:
   1712  *      unit - StrataSwitch Unit #.
   1713  *      num_subport: number of subports
   1714  *      first_phy_port: first physical port number of the TSC
   1715  *      encap: Ethernet or HiGig2
   1716  *
   1717  * Returns:
   1718  *     SOC_E_XXXX
   1719  */
   1720 static bcm_error_t
   1721 flexport_fill_resource_per_tsc(int unit, int num_subport, int first_phy_port,
   1722                                int *speed, int encap)
   1723 {
   1724     soc_info_t *si;
   1725     flexport_mc_t *flex_p = flexport_parray[unit];
   1726     int i, resource_idx;
   1727     int tsc = (num_subport > 0) ? ((first_phy_port - 1) / num_subport) : -1;
   1728     int cur_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1729     int cur_lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1730     int cur_encap = BCM_PORT_ENCAP_IEEE;
   1731     int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1732     int lanes_changed = 0;
   1733     bcm_port_t lport, pport;
   1734     int rv;
   1735 
   1736     si = &SOC_INFO(unit);
   1737 
   1738     LOG_INFO(BSL_LS_APPL_TESTS,
   1739              (BSL_META_U(unit, "\nFlexing TSC_%02d, port[%0d..%0d] to ["),
   1740              tsc, first_phy_port, first_phy_port + num_subport - 1));
   1741     for (i = 0; i < num_subport; i++) {
   1742         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " %0dG"), speed[i] / 1000));
   1743     }
   1744     if (encap == BCM_PORT_ENCAP_IEEE) {
   1745         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "] Ethernet")));
   1746     } else if (encap == BCM_PORT_ENCAP_HIGIG2) {
   1747         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "] Higig2")));
   1748     }
   1749 
   1750     lport = si->port_p2l_mapping[first_phy_port];
   1751     if (lport != -1 && IS_HG2_ENABLED_PORT(unit, lport)) {
   1752         cur_encap = BCM_PORT_ENCAP_HIGIG2;
   1753     }
   1754 
   1755     for (i = 0; i < num_subport; i++) {
   1756         pport = first_phy_port + i;
   1757         lport = si->port_p2l_mapping[pport];
   1758         if (lport != -1) {
   1759             rv = bcm_port_speed_get(unit, lport, &cur_speed[i]);
   1760             if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
   1761                 cli_out("\nbcm_port_speed_get %0d %0d: %s",
   1762                         lport, rv, bcm_errmsg(rv));
   1763                 return rv;
   1764             }
   1765         }
   1766     }
   1767 
   1768     flexport_get_speed_lanes(unit, num_subport, cur_speed, cur_lanes);
   1769     flexport_get_speed_lanes(unit, num_subport, speed, lanes);
   1770     for (i = 0; i < num_subport; i++) {
   1771         if (lanes[i] != cur_lanes[i]) {
   1772             lanes_changed = 1;
   1773             break;
   1774         }
   1775     }
   1776 
   1777     if (lanes_changed == 0 && encap == cur_encap &&
   1778         flex_p->flex_no_spd_ch_param == 0) {
   1779         for (i = 0; i < num_subport; i++) {
   1780             if (speed[i] != cur_speed[i]) {
   1781                 pport = first_phy_port + i;
   1782                 lport = si->port_p2l_mapping[pport];
   1783                 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   1784                     "\nTSC_%02d, Changing pport %0d, from %0dG to %0dG"),
   1785                     tsc, pport, cur_speed[i] / 1000, speed[i] / 1000));
   1786                 rv = bcm_port_speed_set(unit, lport, speed[i]);
   1787                 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) {
   1788                     cli_out("\nbcm_port_speed_set %0d %0d: %s",
   1789                             lport, speed[i], bcm_errmsg(rv));
   1790                     return rv;
   1791                 }
   1792                 SOC_PBMP_PORT_ADD(flex_p->flex_lport_ch_pbmp, lport);
   1793             }
   1794         }
   1795         return BCM_E_NONE;
   1796     }
   1797 
   1798     for (i = 0; i < num_subport; i++) {
   1799         pport = first_phy_port + i;
   1800         lport = si->port_p2l_mapping[pport];
   1801         if (lport != -1) {
   1802             if (cur_speed[i] > 0 &&
   1803                 (speed[i] != cur_speed[i] || encap != cur_encap ||
   1804                  lanes[i] != cur_lanes[i])) {
   1805                 LOG_INFO(BSL_LS_APPL_TESTS,
   1806                          (BSL_META_U(unit,
   1807                             "\nTSC_%02d, Removing pport %0d, speed %0dG"),
   1808                             tsc, pport, cur_speed[i] / 1000));
   1809                 resource_idx = flex_p->flex_num_del++;
   1810                 bcm_port_resource_t_init(
   1811                     &flex_p->flex_resource_del[resource_idx]);
   1812                 flex_p->flex_resource_del[resource_idx].physical_port = -1;
   1813                 flex_p->flex_resource_del[resource_idx].port = lport;
   1814                 SOC_PBMP_PORT_ADD(flex_p->flex_lport_dn_pbmp, lport);
   1815             }
   1816         }
   1817     }
   1818 
   1819     for (i = 0; i < num_subport; i++) {
   1820         if (speed[i] > 0 &&
   1821             (speed[i] != cur_speed[i] || encap != cur_encap ||
   1822              lanes[i] != cur_lanes[i])) {
   1823             pport = first_phy_port + i;
   1824             /* lport = (pport > 64) ? (2 + pport) : (pport); */
   1825             lport = flexport_assign_lport_by_pport(unit, pport);
   1826             if(lport == -1) {
   1827                 cli_out("\nERROR : Unable to find valid logical port for"
   1828                                               " physical port %0d", pport);
   1829                 return BCM_E_INTERNAL;
   1830             }
   1831             resource_idx = flex_p->flex_num_add++;
   1832             bcm_port_resource_t_init(
   1833                 &flex_p->flex_resource_add[resource_idx]);
   1834             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   1835                      "\nTSC_%02d, Adding   pport %0d, speed %0dG,  lane %0d"),
   1836                      tsc, pport, speed[i] / 1000, lanes[i]));
   1837             flex_p->flex_resource_add[resource_idx].physical_port = pport;
   1838             flex_p->flex_resource_add[resource_idx].port  = lport;
   1839             flex_p->flex_resource_add[resource_idx].speed =
   1840                                       stream_get_exact_speed(speed[i], encap);
   1841             flex_p->flex_resource_add[resource_idx].lanes = lanes[i];
   1842             flex_p->flex_resource_add[resource_idx].encap = encap;
   1843             SOC_PBMP_PORT_ADD(flex_p->flex_lport_up_pbmp, lport);
   1844         }
   1845     }
   1846 
   1847     return BCM_E_NONE;
   1848 }
   1849 
   1850 /*
   1851  * Function:
   1852  *      flexport_cfg_resource_per_tsc
   1853  * Purpose:
   1854  *      Configure resource for one tsc by tsc mode.
   1855  * Parameters:
   1856  *      unit: StrataSwitch Unit #.
   1857  *      tsc: TSC #
   1858  *      mode: target port speed/mode
   1859  *
   1860  * Returns:
   1861  *     BCM_E_XXXX
   1862  */
   1863 static bcm_error_t
   1864 flexport_cfg_resource_per_tsc(int unit, uint32 tsc, char *mode)
   1865 {
   1866     int rv = BCM_E_NONE;
   1867     int speed[NUM_LANES_PER_TSC];
   1868     int num_subport = 4;
   1869     int encap = BCM_PORT_ENCAP_IEEE;
   1870 
   1871     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   1872                 "\nFlexing TSC_%02d to %s"), tsc, mode));
   1873 
   1874     flexport_get_tsc_speed_by_mode(unit, tsc, mode, speed);
   1875     flexport_get_tsc_encap_by_mode(unit, tsc, mode, &encap);
   1876 
   1877     rv = flexport_fill_resource_per_tsc(unit, num_subport,
   1878                                         tsc * NUM_LANES_PER_TSC + 1,
   1879                                         speed, encap);
   1880     if (BCM_FAILURE(rv)) {
   1881         cli_out("\nflex_tsc %0d: %s", tsc , bcm_errmsg(rv));
   1882     }
   1883 
   1884     return rv;
   1885 }
   1886 
   1887 /*
   1888  * Function:
   1889  *      flexport_is_ovsb_cfg
   1890  * Purpose:
   1891  *      Configure resource for flexports.
   1892  * Parameters:
   1893  *      unit: StrataSwitch Unit #.
   1894  *
   1895  * Returns:
   1896  *     BCM_E_XXXX
   1897  */
   1898 static int
   1899 flexport_is_ovsb_cfg(int unit)
   1900 {
   1901     int is_ovsb = 0;
   1902     int port_speed, port;
   1903 
   1904     PBMP_ITER(PBMP_E_ALL(unit), port) {
   1905         if ((port < SOC_MAX_NUM_PORTS) &&
   1906             (flexport_is_ipmc_port(unit, port) ||
   1907              flexport_is_l3uc_port(unit, port)) ) {
   1908             bcm_port_speed_get(unit, port, &port_speed);
   1909             if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port) && port_speed > 0) {
   1910                 is_ovsb = 1;
   1911                 break;
   1912             }
   1913         }
   1914     }
   1915 
   1916     return  is_ovsb;
   1917 }
   1918 
   1919 /*
   1920  * Function:
   1921  *      flexport_rand_tsc_mode
   1922  * Purpose:
   1923  *      Randomly select TSCs for flexing.
   1924  * Parameters:
   1925  *      unit: StrataSwitch Unit #.
   1926  *      min_tsc: lowest tsc number.
   1927  *      max_tsc: highest tsc number.
   1928  *      num_req_tsc: number of required tsc.
   1929  *      tsc_selected: ptr to tsc selected status. 1:selected, 0:available.
   1930  *
   1931  * Returns:
   1932  *     BCM_E_XXXX
   1933  */
   1934 static void
   1935 flexport_rand_tsc_mode(int unit, int min_tsc, int max_tsc, int num_req_tsc,
   1936                        uint32 *tsc_selected)
   1937 {
   1938     int tsc_cnt = 0, tsc = 1, num_tsc, num_avail_tsc;
   1939 
   1940     num_avail_tsc = max_tsc - min_tsc + 1;
   1941     if (min_tsc >= 0 && min_tsc < MAX_NUM_TSC &&
   1942         max_tsc >= 0 && max_tsc < MAX_NUM_TSC &&
   1943         num_avail_tsc > 0 && num_req_tsc > 0) {
   1944         num_tsc = (num_req_tsc <= num_avail_tsc) ? num_req_tsc : num_avail_tsc;
   1945         for (tsc_cnt = 0; tsc_cnt < num_tsc; tsc_cnt++) {
   1946             do {
   1947                 /* coverity[dont_call : FALSE] */
   1948                 tsc = (sal_rand() % num_avail_tsc) + min_tsc;
   1949             } while (tsc_selected[tsc % MAX_NUM_TSC]);
   1950             tsc_selected[tsc] = 1;
   1951         }
   1952     }
   1953 }
   1954 
   1955 /*
   1956  * Function:
   1957  *      flexport_cfg_test_case
   1958  * Purpose:
   1959  *      Configure resource for flexports.
   1960  * Parameters:
   1961  *      unit: StrataSwitch Unit #.
   1962  *
   1963  * Returns:
   1964  *     BCM_E_XXXX
   1965  */
   1966 static void
   1967 flexport_cfg_test_case(int unit, int case_num)
   1968 {
   1969     int i;
   1970     int tsc_cnt;
   1971     uint32 tsc_selected[MAX_NUM_TSC];
   1972     int tsc_lo, tsc_hi, tsc_mid;
   1973     int tsc_lo_ipmc = -1, tsc_hi_ipmc = -1;
   1974     int tsc_lo_l3uc = -1, tsc_hi_l3uc = -1;
   1975     flexport_mc_t *flex_p = flexport_parray[unit];
   1976 
   1977     for (i = 0; i < MAX_NUM_TSC; i++) flex_p->flex_tsc_mode[i] = NULL;
   1978 
   1979     if (SOC_IS_MAVERICK2(unit)) {
   1980         tsc_lo  = 0;
   1981         tsc_hi  = 19;
   1982         tsc_mid = (tsc_lo + tsc_hi + 1) / 2;
   1983 
   1984         tsc_lo_ipmc = 0;
   1985         tsc_hi_ipmc = 7;
   1986         tsc_lo_l3uc = 10;
   1987         tsc_hi_l3uc = 14;
   1988     } else if (SOC_IS_HELIX5(unit)) {
   1989         /* Only test TSCf */
   1990         tsc_lo  = 17;
   1991         tsc_hi  = 19;
   1992         tsc_mid = (tsc_lo + tsc_hi + 1) / 2;
   1993     } else if (SOC_IS_TRIDENT3X(unit)) {
   1994         tsc_lo  = 0;
   1995         tsc_hi  = 31;
   1996         tsc_mid = (tsc_lo + tsc_hi + 1) / 2;
   1997         tsc_hi  = 30; /* ignore the last PM due to 2nd mgmt port */
   1998     } else {
   1999         tsc_lo  = 0;
   2000         tsc_hi  = 31;
   2001         tsc_mid = (tsc_lo + tsc_hi + 1) / 2;
   2002     }
   2003 
   2004     if (tsc_lo_ipmc == -1 || tsc_hi_ipmc == -1 ||
   2005         tsc_lo_l3uc == -1 || tsc_hi_l3uc == -1) {
   2006         if (tsc_lo_ipmc == -1) tsc_lo_ipmc = tsc_lo;
   2007         if (tsc_hi_ipmc == -1) tsc_hi_ipmc = tsc_mid - 1;
   2008         if (tsc_lo_l3uc == -1) tsc_lo_l3uc = tsc_mid;
   2009         if (tsc_hi_l3uc == -1) tsc_hi_l3uc = tsc_hi;
   2010     }
   2011 
   2012     if (case_num == 0) {
   2013         if (SOC_IS_MAVERICK2(unit)) {
   2014             /* Maverick 2 has mixed 10G/25G PM config */
   2015             for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++)
   2016                 flex_p->flex_tsc_mode[i] = "10G_25G_mix";
   2017             for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++)
   2018                 flex_p->flex_tsc_mode[i] = "10G_25G_mix";
   2019         }
   2020         else {
   2021             /* oversub */
   2022             if(flexport_is_ovsb_cfg(unit)) {
   2023                 for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++)
   2024                     flex_p->flex_tsc_mode[i] = "4x25G";
   2025                 for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++)
   2026                     flex_p->flex_tsc_mode[i] = "4x25G";
   2027             }
   2028             /* linerate */
   2029             else {
   2030                 if (tsc_mid > 0) {
   2031                     for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++)
   2032                         flex_p->flex_tsc_mode[i] = ((i % tsc_mid) < 6) ?
   2033                                                    "4x25G" : "4x0G";
   2034                     for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++)
   2035                         flex_p->flex_tsc_mode[i] = ((i % tsc_mid) < 6) ?
   2036                                                    "4x25G" : "4x0G";
   2037                 }
   2038             }
   2039         }
   2040 
   2041         if ((!flexport_is_ovsb_cfg(unit)) ||
   2042             (flexport_is_ovsb_cfg(unit) && SOC_IS_MAVERICK2(unit))) {
   2043             for (i = tsc_lo; i <= tsc_hi ; i++) {
   2044                 if (!((i >= tsc_lo_ipmc && i <= tsc_hi_ipmc) ||
   2045                       (i >= tsc_lo_l3uc && i <= tsc_hi_l3uc)))
   2046                     flex_p->flex_tsc_mode[i] = "4x0G";
   2047             }
   2048         }
   2049     }
   2050     else if (case_num == 1) {
   2051         /* randomly select tsc for flexport */
   2052         sal_memset(tsc_selected, 0, sizeof(uint32) * MAX_NUM_TSC);
   2053         flexport_rand_tsc_mode(unit, 1, tsc_hi_ipmc, 6, tsc_selected);
   2054         flexport_rand_tsc_mode(unit, tsc_lo_l3uc, tsc_hi_l3uc, 6, tsc_selected);
   2055 
   2056         /* oversub */
   2057         if(flexport_is_ovsb_cfg(unit)) {
   2058             /* ipmc */
   2059             tsc_cnt = 0;
   2060             for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc; i++) {
   2061                 if (tsc_selected[i] == 0) continue;
   2062                 tsc_cnt++;
   2063                 switch (tsc_cnt) {
   2064                    case 1: flex_p->flex_tsc_mode[i] = "1x50G";   break;
   2065                    case 2: flex_p->flex_tsc_mode[i] = "1x100G"; break;
   2066                    case 3: flex_p->flex_tsc_mode[i] = "2x50G";  break;
   2067                    case 4: flex_p->flex_tsc_mode[i] = "4x25G";  break;
   2068                    case 5: flex_p->flex_tsc_mode[i] = "2x40G";  break;
   2069                    case 6: flex_p->flex_tsc_mode[i] = "1x40G";  break;
   2070                    default:flex_p->flex_tsc_mode[i] = NULL;    break;
   2071                }
   2072             }
   2073             /* l3uc */
   2074             tsc_cnt = 0;
   2075             for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc; i++) {
   2076                 if (tsc_selected[i] == 0 || i == 22) {
   2077                     flex_p->flex_tsc_mode[i] = "4x0G";
   2078                     continue;
   2079                 }
   2080                 tsc_cnt++;
   2081                 switch (tsc_cnt) {
   2082                    case 1: flex_p->flex_tsc_mode[i] = "1x100G"; break;
   2083                    case 2: flex_p->flex_tsc_mode[i] = "2x53G";  break;
   2084                    case 3: flex_p->flex_tsc_mode[i] = "4x25G";  break;
   2085                    case 4: flex_p->flex_tsc_mode[i] = "4x27G";  break;
   2086                    case 5: flex_p->flex_tsc_mode[i] = "1x40G";  break;
   2087                    default:flex_p->flex_tsc_mode[i] = "4x0G";   break;
   2088                }
   2089             }
   2090         }
   2091         /* linerate */
   2092         else {
   2093             /* ipmc: The 1st tsc is reserved for traffic gen */
   2094             tsc_cnt = 0;
   2095             for (i = tsc_lo_ipmc + 1; i <= tsc_hi_ipmc; i++) {
   2096                 if (tsc_selected[i] == 0) {
   2097                     flex_p->flex_tsc_mode[i] = "4x0G";
   2098                     continue;
   2099                 }
   2100                 tsc_cnt++;
   2101                 switch (tsc_cnt) {
   2102                    case 1: flex_p->flex_tsc_mode[i] = NULL;        break;
   2103                    case 2: flex_p->flex_tsc_mode[i] = "2x25G+50G"; break;
   2104                    case 3: flex_p->flex_tsc_mode[i] = "4x0G";      break;
   2105                    case 4: flex_p->flex_tsc_mode[i] = "2x50G";     break;
   2106                    case 5: flex_p->flex_tsc_mode[i] = "2x40G";     break;
   2107                    case 6: flex_p->flex_tsc_mode[i] = "1x50G";     break;
   2108                    default:flex_p->flex_tsc_mode[i] = "4x0G";      break;
   2109                }
   2110             }
   2111 
   2112             /* l3uc */
   2113             tsc_cnt = 0;
   2114             for (i = tsc_lo_l3uc + 1; i <= tsc_hi_l3uc; i++) {
   2115                 if (tsc_selected[i] == 0) {
   2116                     flex_p->flex_tsc_mode[i] = "4x0G";
   2117                     continue;
   2118                 }
   2119                 tsc_cnt++;
   2120                 switch (tsc_cnt) {
   2121                    /* case 1: flex_p->flex_tsc_mode[i] = "4x27G";    break; */
   2122                    case 1: flex_p->flex_tsc_mode[i] = "4x25G";    break;
   2123                    case 2: flex_p->flex_tsc_mode[i] = "50G+2x25G";break;
   2124                    case 3: flex_p->flex_tsc_mode[i] = "2x40G";    break;
   2125                    /* case 4: flex_p->flex_tsc_mode[i] = "1x53G";    break; */
   2126                    case 4: flex_p->flex_tsc_mode[i] = "1x50G";    break;
   2127                    case 5: flex_p->flex_tsc_mode[i] = "2x50G";    break;
   2128                    case 6: flex_p->flex_tsc_mode[i] = "1x40G";    break;
   2129                    default:flex_p->flex_tsc_mode[i] = "4x0G";     break;
   2130                }
   2131             }
   2132         }
   2133     }
   2134 
   2135     /* print */
   2136     cli_out("\nFlexport Config: case_num = %0d\n", case_num);
   2137     cli_out("%4s\t%s\n","Tsc ", "TscMode");
   2138     for (i = 0; i < MAX_NUM_TSC; i++) {
   2139         if (flex_p->flex_tsc_mode[i] != NULL)
   2140             cli_out("%4d, \t%s\n", i, flex_p->flex_tsc_mode[i]);
   2141     }
   2142 
   2143 }
   2144 
   2145 /*
   2146  * Function:
   2147  *      flexport_cfg_resource
   2148  * Purpose:
   2149  *      Configure resource for flexports.
   2150  * Parameters:
   2151  *      unit: StrataSwitch Unit #.
   2152  *
   2153  * Returns:
   2154  *     BCM_E_XXXX
   2155  */
   2156 static bcm_error_t
   2157 flexport_cfg_resource(int unit)
   2158 {
   2159     int i, rv = BCM_E_NONE;
   2160     char *mode;
   2161     flexport_mc_t *flex_p = flexport_parray[unit];
   2162 
   2163     /* init */
   2164     flex_p->flex_num_del = 0;
   2165     flex_p->flex_num_add = 0;
   2166 
   2167     SOC_PBMP_CLEAR(flex_p->flex_lport_dn_pbmp);
   2168     SOC_PBMP_CLEAR(flex_p->flex_lport_up_pbmp);
   2169     SOC_PBMP_CLEAR(flex_p->flex_lport_ch_pbmp);
   2170 
   2171     for (i = 0; i < MAX_NUM_TSC; i++) {
   2172         mode = flex_p->flex_tsc_mode[i];
   2173         if (mode != NULL) {
   2174             BCM_IF_ERROR_RETURN(flexport_cfg_resource_per_tsc(unit, i, mode));
   2175         }
   2176     }
   2177 
   2178     /* print */
   2179     flexport_print_ports(unit, flex_p->flex_lport_dn_pbmp, "Down Ports");
   2180     flexport_print_ports(unit, flex_p->flex_lport_up_pbmp, "UP Ports");
   2181     flexport_print_ports(unit, flex_p->flex_lport_ch_pbmp, "Changed Ports");
   2182 
   2183     return rv;
   2184 }
   2185 
   2186 
   2187 /*
   2188  * Function:
   2189  *      flexport_l3uc_set_port_property
   2190  * Purpose:
   2191  *      Set rand_pkt_sizes, port_oversub, and exp_rates arrays.
   2192  * Parameters:
   2193  *      unit: StrataSwitch Unit #.
   2194  *      pbmp - Device port bitmap
   2195  *      pkt_size_param - Packet size in bytes
   2196  *      max_num_cells_param - Maximum number of cells
   2197  *
   2198  * Returns:
   2199  *     BCM_E_XXXX
   2200  */
   2201 static bcm_error_t
   2202 flexport_l3uc_set_port_property(int unit, pbmp_t pbmp, int pkt_size_param,
   2203                          int max_num_cells_param)
   2204 {
   2205   int p, j, pkt_size;
   2206   stream_rate_t *stream_rate_calc_p;
   2207   flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   2208   flexport_mc_t *flex_p = flexport_parray[unit];
   2209 
   2210   stream_rate_calc_p = sal_alloc(sizeof(stream_rate_t), "streaming_rate");
   2211   sal_memset(stream_rate_calc_p, 0, sizeof(stream_rate_t));
   2212 
   2213   stream_rate_calc_p->mode         = 0;
   2214   stream_rate_calc_p->tolerance_lr = flex_p->rate_tolerance_lr_param;
   2215   stream_rate_calc_p->tolerance_os = flex_p->rate_tolerance_os_param;
   2216   SOC_PBMP_CLEAR(stream_rate_calc_p->pbmp);
   2217   PBMP_ITER(PBMP_E_ALL(unit), p) {
   2218       if (p < SOC_MAX_NUM_PORTS && p < TEST_COVERITY_PBMP_WID) {
   2219           stream_rate_calc_p->pkt_size = flexport_get_port_pkt_size(unit, p);
   2220           SOC_PBMP_PORT_ADD(stream_rate_calc_p->pbmp, p);
   2221       }
   2222   }
   2223 
   2224   if (SOC_FAILURE(stream_calc_exp_rate_by_rx(unit, rate_calc_p->exp_rate,
   2225                                              stream_rate_calc_p))) {
   2226       cli_out("\n*ERROR, stream_calc_exp_rate_by_rx failed.\n");
   2227       sal_free(stream_rate_calc_p);
   2228       return BCM_E_FAIL;
   2229   }
   2230   sal_free(stream_rate_calc_p);
   2231 
   2232   PBMP_ITER(pbmp, p) {
   2233       if (p < SOC_MAX_NUM_PORTS) {
   2234           for (j = 0; j < TARGET_CELL_COUNT; j++) {
   2235               do {
   2236                   /* coverity[dont_call : FALSE] */
   2237                   pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) +
   2238                              MIN_PKT_SIZE;
   2239               } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) >
   2240                        max_num_cells_param);
   2241               rate_calc_p->rand_pkt_sizes[p][j] = pkt_size;
   2242           }
   2243       }
   2244   }
   2245 
   2246   return BCM_E_NONE;
   2247 }
   2248 
   2249 /*
   2250  * Function:
   2251  *      flexport_l3uc_set_up_ports
   2252  * Purpose:
   2253  *      Enable port bridging and HiGig lookup for HG2 ports
   2254  * Parameters:
   2255  *      unit - StrataSwitch Unit #.
   2256  *      pbmp - Device port bitmap
   2257  *
   2258  * Returns:
   2259  *     Nothing
   2260  */
   2261 static void
   2262 flexport_l3uc_set_up_ports(int unit, pbmp_t pbmp)
   2263 {
   2264     int i, p;
   2265     lport_tab_entry_t lport_tab_entry;
   2266     port_tab_entry_t port_tab_entry;
   2267     soc_field_t ihg_lookup_fields[] =
   2268         { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf,
   2269         REMOVE_MH_SRC_PORTf
   2270     };
   2271     uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 };
   2272 
   2273     cli_out("\nEnabling HG_LOOKUP on HG ports");
   2274 
   2275     PBMP_ITER(pbmp, p) {
   2276         if (p < SOC_MAX_NUM_PORTS && IS_HG_PORT(unit, p)) {
   2277             soc_reg_fields32_modify(unit, IHG_LOOKUPr, p, 5,
   2278                                     ihg_lookup_fields, ihg_lookup_values);
   2279         }
   2280     }
   2281 
   2282     cli_out("\nEnabling Port bridging");
   2283 
   2284     for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) {
   2285         (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i,
   2286                      lport_tab_entry.entry_data);
   2287         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   2288                             ALLOW_SRC_MODf, 0x1);
   2289         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   2290                             PORT_BRIDGEf, 0x1);
   2291         (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i,
   2292                       lport_tab_entry.entry_data);
   2293     }
   2294 
   2295     for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) {
   2296         (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i,
   2297                      port_tab_entry.entry_data);
   2298         soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data,
   2299                             PORT_BRIDGEf, 0x1);
   2300         (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i,
   2301                           port_tab_entry.entry_data);
   2302     }
   2303 }
   2304 
   2305 /*
   2306  * Function:
   2307  *      flexport_l3uc_set_up_streams
   2308  * Purpose:
   2309  *      VLAN programming. Each port is put on an unique VLAN.
   2310  * Parameters:
   2311  *      unit: StrataSwitch Unit #.
   2312  *      pbmp - Device port bitmap
   2313  *      vlan_bmp - bitmap of device ports that have vlan set up
   2314  *
   2315  * Returns:
   2316  *     vlan_pbmp - bitmap of device ports that have vlan set up.
   2317  */
   2318 static pbmp_t
   2319 flexport_l3uc_set_up_streams(int unit, pbmp_t pbmp, pbmp_t vlan_pbmp)
   2320 {
   2321     int p;
   2322     pbmp_t pbm, ubm;
   2323     bcm_vlan_t vlan;
   2324 
   2325     BCM_PBMP_CLEAR(ubm);
   2326 
   2327     PBMP_ITER(pbmp, p) {
   2328         if (p < SOC_MAX_NUM_PORTS) {
   2329             vlan = VLAN + p;
   2330             if (SOC_PBMP_MEMBER(vlan_pbmp, p)) {
   2331                 stream_set_vlan(unit, vlan, 1);
   2332             } else {
   2333                 BCM_PBMP_CLEAR(pbm);
   2334                 bcm_vlan_create(unit, vlan);
   2335                 BCM_PBMP_PORT_ADD(pbm, p);
   2336                 bcm_vlan_port_add(unit, vlan, pbm, ubm);
   2337             }
   2338         }
   2339     }
   2340 
   2341     SOC_PBMP_OR(vlan_pbmp, pbmp);
   2342 
   2343     return vlan_pbmp;
   2344 }
   2345 
   2346 /*
   2347  * Function:
   2348  *     flexport_l3uc_send_pkts
   2349  * Purpose:
   2350  *     Sends packet for all the ports in the port bitmap
   2351  * Parameters:
   2352  *      unit: StrataSwitch Unit #.
   2353  *      pbmp - port bitmap
   2354  *      pkt_size_param -
   2355  *      pkt_seed -
   2356  *
   2357  * Returns:
   2358  *     flood packet count for the given port.
   2359  */
   2360 static void
   2361 flexport_l3uc_send_pkts(int unit, pbmp_t pbmp, uint32 pkt_size_param,
   2362                    uint32 pkt_seed)
   2363 {
   2364 	int port;
   2365     uint8 mac_da[] = MAC_DA;
   2366     uint8 mac_sa[] = MAC_SA;
   2367 	uint32 pkt_size;
   2368     stream_pkt_t *tx_pkt;
   2369 	flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   2370 
   2371     tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt");
   2372     sal_memset(tx_pkt, 0, sizeof(stream_pkt_t));
   2373 
   2374     cli_out("\n==================================================\n");
   2375     cli_out("\nSending packets ...\n\n");
   2376     PBMP_ITER(pbmp, port) {
   2377         if (port < SOC_MAX_NUM_PORTS) {
   2378 /*             if (pkt_size_param == 0) {
   2379                 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port));
   2380             } else {
   2381                 pkt_size = pkt_size_param;
   2382             } */
   2383             pkt_size = flexport_get_port_pkt_size(unit, port);
   2384 
   2385             tx_pkt->port = port;
   2386             tx_pkt->num_pkt = flexport_get_lossless_flood_cnt(unit, port);
   2387             tx_pkt->pkt_seed = pkt_seed;
   2388             tx_pkt->pkt_size = pkt_size;
   2389     		cli_out("\nSending packets on port %0d size %0d num %0d.",
   2390                     port, pkt_size, tx_pkt->num_pkt);
   2391 			if(pkt_size_param == 1) {
   2392               tx_pkt->rand_pkt_size_en = 1;
   2393               tx_pkt->rand_pkt_size = rate_calc_p->rand_pkt_sizes[port];
   2394             } else {
   2395               tx_pkt->rand_pkt_size_en = 0;
   2396               tx_pkt->rand_pkt_size = NULL;
   2397             }
   2398             tx_pkt->tx_vlan = VLAN + port;
   2399             sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR);
   2400             sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR);
   2401             stream_tx_pkt(unit, tx_pkt);
   2402         }
   2403     }
   2404 	sal_free(tx_pkt);
   2405 }
   2406 
   2407 /*
   2408  * Function:
   2409  *      flexport_l3uc_start_rate_record
   2410  * Purpose:
   2411  *      Get current time, packet count & byte count needed to calculate port
   2412  *      rate
   2413  * Parameters:
   2414  *      unit - StrataSwitch Unit #.
   2415  *      pbmp - Device port bitmap to be used
   2416  *      emulation_param - 1: test run in emulator platform
   2417  *                        0: test run is actual hardware(chip)
   2418  *
   2419  * Returns:
   2420  *     SOC_E_XXXX
   2421  */
   2422 static bcm_error_t
   2423 flexport_l3uc_start_rate_record(int unit, pbmp_t pbmp, uint32 emulation_param)
   2424 {
   2425     flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   2426 
   2427     return record_rate_information(unit, emulation_param, pbmp,
   2428                                    rate_calc_p->stime,
   2429                                    rate_calc_p->tpkt_start,
   2430                                    rate_calc_p->tbyt_start);
   2431 
   2432 }
   2433 
   2434 
   2435 /*
   2436  * Function:
   2437  *      flexport_l3uc_chk_rate_run
   2438  * Purpose:
   2439  *      Check rates against expected rates.
   2440  * Parameters:
   2441  *      unit - StrataSwitch Unit #.
   2442  *      pbmp - Device port bitmap to be checked
   2443  *      tolerance_lr - Percentage of rate tolerance for line rate ports
   2444  *      tolerance_os - Percentage of rate tolerance for oversub ports
   2445  *
   2446  * Returns:
   2447  *     SOC_E_XXXX
   2448  */
   2449 static bcm_error_t
   2450 flexport_l3uc_chk_rate_run(int unit, pbmp_t pbmp, uint32 tolerance_lr,
   2451              uint32 tolerance_os, uint32 emulation_param)
   2452 {
   2453     uint64 *etime;
   2454     uint64 *tpkt_end;
   2455     uint64 *tbyt_end;
   2456     uint64 *rate;
   2457     flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   2458     bcm_error_t rv = BCM_E_NONE;
   2459 
   2460     etime = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2461                                       "etime");
   2462     tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2463                                     "tpkt_end");
   2464     tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2465                                     "tbyt_end");
   2466     rate = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2467                                 "rate");
   2468 
   2469     sal_memset(etime,    0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   2470     sal_memset(tpkt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   2471     sal_memset(tbyt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   2472     sal_memset(rate,     0, sizeof(uint64) * SOC_MAX_NUM_PORTS);
   2473 
   2474     rv = record_rate_information(unit, emulation_param, pbmp, etime,
   2475                                      tpkt_end, tbyt_end);
   2476 
   2477     calc_act_port_rate(unit, pbmp, rate_calc_p->stime, etime,
   2478                        rate_calc_p->tpkt_start, tpkt_end,
   2479                        rate_calc_p->tbyt_start, tbyt_end, rate);
   2480 
   2481     rv = compare_rates(unit, pbmp, tolerance_lr, tolerance_os,
   2482                   rate_calc_p->exp_rate, rate);
   2483 
   2484     if (rv != BCM_E_NONE) {
   2485         test_error(unit, "********** [L3UC] RATE CHECK FAILED ***********\n");
   2486     } else {
   2487         cli_out("\n********** [L3UC] RATE CHECK PASSED ***********");
   2488     }
   2489 
   2490     sal_free(etime);
   2491     sal_free(tpkt_end);
   2492     sal_free(tbyt_end);
   2493     sal_free(rate);
   2494     return rv;
   2495 }
   2496 
   2497 /*
   2498  * Function:
   2499  *      flexport_l3uc_chk_counter
   2500  * Purpose:
   2501  *      Check rate for ports in L3UC categories.
   2502  * Parameters:
   2503  *      unit - StrataSwitch Unit #.
   2504  *      a - Pointer to arguments
   2505  *
   2506  * Returns:
   2507  *     SOC_E_XXXX
   2508  */
   2509 static void
   2510 flexport_l3uc_chk_rate(int unit, pbmp_t pbmp)
   2511 {
   2512     flexport_mc_t *flex_p = flexport_parray[unit];
   2513 
   2514     /* check mib counter */
   2515     if (flex_p->check_mib_param == 1) {
   2516         if (stream_chk_mib_counters(unit, pbmp, 0) != BCM_E_NONE) {
   2517             flex_p->test_fail = 1;
   2518         }
   2519     }
   2520 
   2521     /* check rate */
   2522     if (flex_p->check_rate_param == 1) {
   2523         cli_out("\nWait 2s for traffic to stabilize");
   2524         sal_sleep(2);
   2525         /* start rate measurement */
   2526         flexport_l3uc_start_rate_record(unit, pbmp, flex_p->emulation_param);
   2527         cli_out("\nMeasuring Rate over a period of %0ds",
   2528                 flex_p->rate_calc_interval_param);
   2529         sal_sleep(flex_p->rate_calc_interval_param);
   2530 
   2531         /* start rate checking */
   2532         if (flexport_l3uc_chk_rate_run(unit, pbmp,
   2533                        flex_p->rate_tolerance_lr_param,
   2534                        flex_p->rate_tolerance_os_param,
   2535                        flex_p->emulation_param) != BCM_E_NONE) {
   2536             flex_p->test_fail = 1;
   2537         }
   2538     }
   2539 }
   2540 
   2541 /*
   2542  * Function:
   2543  *      flexport_l3uc_chk_integrity
   2544  * Purpose:
   2545  *      Check integrity for ports in L3UC categories.
   2546  * Parameters:
   2547  *      unit - StrataSwitch Unit #.
   2548  *      a - Pointer to arguments
   2549  *
   2550  * Returns:
   2551  *     SOC_E_XXXX
   2552  */
   2553 static void
   2554 flexport_l3uc_chk_integrity(int unit, pbmp_t pbmp)
   2555 {
   2556     int p;
   2557     uint8 mac_da[] = MAC_DA;
   2558     uint8 mac_sa[] = MAC_SA;
   2559     flexport_mc_t *flex_p = flexport_parray[unit];
   2560     stream_integrity_t *pkt_intg;
   2561     int rv = BCM_E_NONE;
   2562 
   2563     cli_out("\nWait 2s for traffic to stabilize");
   2564     sal_sleep(2);
   2565 
   2566     /* check integrity */
   2567     if (flex_p->check_integrity_param != 0) {
   2568         pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity");
   2569         sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
   2570 
   2571         pkt_intg->rx_pbmp = pbmp;
   2572         PBMP_ITER(pbmp, p) {
   2573             if (p < SOC_MAX_NUM_PORTS) {
   2574                 pkt_intg->port_pkt_seed[p] = flex_p->pkt_seed;
   2575                 pkt_intg->port_flood_cnt[p] =
   2576                     flexport_get_lossless_flood_cnt(unit, p);
   2577                 pkt_intg->rx_vlan[p] = VLAN + p;
   2578                 pkt_intg->tx_vlan[p] = VLAN + p;
   2579                 sal_memcpy(pkt_intg->mac_da[p], mac_da, NUM_BYTES_MAC_ADDR);
   2580                 sal_memcpy(pkt_intg->mac_sa[p], mac_sa, NUM_BYTES_MAC_ADDR);
   2581             }
   2582 		}
   2583 
   2584         rv = stream_chk_pkt_integrity(unit, pkt_intg);
   2585         if (rv != BCM_E_NONE) {
   2586             flex_p->test_fail = 1;
   2587         }
   2588         sal_free(pkt_intg);
   2589     }
   2590 }
   2591 
   2592 /*
   2593  * Function:
   2594  *      flexport_l3uc_update_stream
   2595  * Purpose:
   2596  *      flex ports.
   2597  *        -- do flex by calling bcm apis.
   2598  *        -- set test env for up-ports.
   2599  *        -- send traffic
   2600  *        -- measure rate
   2601  *        --
   2602  *        --
   2603  * Parameters:
   2604  *      unit: StrataSwitch Unit #.
   2605  *      port_pbmp: port bitmap for down ports.
   2606  *
   2607  * Returns:
   2608  *     BCM_E_XXXX
   2609  */
   2610 static bcm_error_t
   2611 flexport_l3uc_update_stream(int unit, pbmp_t pbmp)
   2612 {
   2613     flexport_mc_t *flex_p = flexport_parray[unit];
   2614     int rv = BCM_E_NONE;
   2615 
   2616     /* set port property: rand_pkt_size */
   2617     flexport_l3uc_set_port_property(unit, pbmp,
   2618                              flex_p->pkt_size_param,
   2619                              flex_p->max_num_cells_param);
   2620     /* enable port bridging for loopback */
   2621     flexport_l3uc_set_up_ports(unit, flex_p->flex_lport_up_pbmp);
   2622 
   2623     /* set stream */
   2624     flex_p->l3uc_vlan_pbmp = flexport_l3uc_set_up_streams(unit, pbmp,
   2625                                            flex_p->l3uc_vlan_pbmp);
   2626 
   2627     /* send traffic */
   2628     flexport_l3uc_send_pkts(unit, pbmp, flex_p->pkt_size_param,
   2629                             flex_p->pkt_seed);
   2630 
   2631     return rv;
   2632 }
   2633 
   2634 
   2635 
   2636 /*
   2637  * Function:
   2638  *      flexport_divide_ports_for_l3uc_ipmc
   2639  * Purpose:
   2640  *      Divide ports into IPMC and L3UC categories.
   2641  * Parameters:
   2642  *      unit: StrataSwitch Unit #.
   2643  *
   2644  * Returns:
   2645  *     BCM_E_XXXX
   2646  */
   2647 static void
   2648 flexport_divide_ports_for_l3uc_ipmc(int unit)
   2649 {
   2650     int p;
   2651     flexport_mc_t *flex_p = flexport_parray[unit];
   2652 
   2653     cli_out("\nDivide ports into l3uc and ipmc groups\n");
   2654     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   2655                 "SOC_MAX_NUM_PORTS %3d\n"), SOC_MAX_NUM_PORTS));
   2656     BCM_PBMP_CLEAR(flex_p->ipmc_pbmp);
   2657     BCM_PBMP_CLEAR(flex_p->l3uc_pbmp);
   2658 
   2659     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
   2660         if (flexport_is_ipmc_port(unit, p)) {
   2661             BCM_PBMP_PORT_ADD(flex_p->ipmc_pbmp, p);
   2662         } else if (flexport_is_l3uc_port(unit, p)) {
   2663             BCM_PBMP_PORT_ADD(flex_p->l3uc_pbmp, p);
   2664         }
   2665     }
   2666 
   2667     /* print */
   2668     flexport_print_ports(unit, flex_p->ipmc_pbmp,
   2669                              "Ports reserved for IMPC traffic");
   2670     flexport_print_ports(unit, flex_p->l3uc_pbmp,
   2671                              "Ports reserved for L3UC traffic");
   2672 }
   2673 
   2674 /*
   2675  * Function:
   2676  *      flexport_l3uc_init_env
   2677  * Purpose:
   2678  *      Test init function. Parse CLI params and do necessary init.
   2679  * Parameters:
   2680  *      unit - StrataSwitch Unit #.
   2681  *      a - Pointer to arguments
   2682  *
   2683  * Returns:
   2684  *     SOC_E_XXXX
   2685  */
   2686 static int
   2687 flexport_l3uc_init_env(int unit, args_t *a, void **pa)
   2688 {
   2689     flexport_mc_t *flex_p = flexport_parray[unit];
   2690 
   2691     cli_out("\nCalling flexport_l3uc_init_env");
   2692 
   2693     /* counter */
   2694     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flex_p->env_counter_flags,
   2695                                                  &flex_p->env_counter_interval,
   2696                                                  &flex_p->env_counter_pbm));
   2697     if (flex_p->env_counter_interval > 0) {
   2698         cli_out("\nDisabling counter collection");
   2699         soc_counter_stop(unit);
   2700     }
   2701 
   2702     /* linkscan */
   2703     BCM_IF_ERROR_RETURN(bcm_linkscan_enable_get(unit,
   2704                         &flex_p->env_linkscan_enable));
   2705     if (flex_p->env_linkscan_enable) {
   2706         cli_out("\nDisabling linkscan");
   2707         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0));
   2708     }
   2709 
   2710     return BCM_E_NONE;
   2711 }
   2712 
   2713 /*
   2714  * Function:
   2715  *      flexport_run_flex
   2716  * Purpose:
   2717  *      flex ports.
   2718  *        -- do flex by calling bcm apis.
   2719  *        -- set test env for up-ports.
   2720  *        -- send traffic
   2721  *        -- measure rate
   2722  *        --
   2723  *        --
   2724  * Parameters:
   2725  *      unit: StrataSwitch Unit #.
   2726  *      case_num: flex case number. 0 is reserved for init.
   2727  *
   2728  * Returns:
   2729  *     BCM_E_XXXX
   2730  */
   2731 static void
   2732 flexport_run_flex(int unit, int case_num)
   2733 {
   2734     pbmp_t pbm;
   2735     flexport_mc_t *flex_p = flexport_parray[unit];
   2736 
   2737     /* config tsc mode for flexports */
   2738     flexport_cfg_test_case(unit, case_num);
   2739 
   2740     /* prepare resource struct for flexports */
   2741     flexport_cfg_resource(unit);
   2742 
   2743     /* cal bcm api to flex ports */
   2744     flexport_flex_ports(unit);
   2745 
   2746     /* print: for non-initial flex, only print up/changed ports */
   2747     if (case_num == 0) {
   2748         pbm = PBMP_PORT_ALL(unit);
   2749     } else {
   2750         pbm = flex_p->flex_lport_up_pbmp;
   2751         SOC_PBMP_OR(pbm, flex_p->flex_lport_ch_pbmp);
   2752     }
   2753     stream_print_port_config(unit, pbm);
   2754 }
   2755 
   2756 /*
   2757  * Function:
   2758  *      flexport_td3_test_init
   2759  * Purpose:
   2760  *      Test init function. Parse CLI params and do necessary init.
   2761  * Parameters:
   2762  *      unit - StrataSwitch Unit #.
   2763  *
   2764  * Returns:
   2765  *     Nothing
   2766  */
   2767 int
   2768 flexport_td3_test_init(int unit, args_t *a, void **pa)
   2769 {
   2770     flexport_mc_t *flex_p;
   2771     flexport_l3uc_rate_calc_t *rate_calc_p;
   2772 
   2773     flex_p = flexport_parray[unit];
   2774     flex_p = sal_alloc(sizeof(flexport_mc_t), "ipmc_test");
   2775     sal_memset(flex_p, 0, sizeof(flexport_mc_t));
   2776     flexport_parray[unit] = flex_p;
   2777 
   2778 
   2779     rate_calc_p = rate_calc_parray[unit];
   2780     rate_calc_p = sal_alloc(sizeof(flexport_l3uc_rate_calc_t), "rac_calc_p");
   2781     sal_memset(rate_calc_p, 0, sizeof(flexport_l3uc_rate_calc_t));
   2782     rate_calc_parray[unit] = rate_calc_p;
   2783 
   2784 
   2785     stream_print_port_config(unit, PBMP_PORT_ALL(unit));
   2786     cli_out("\n==================================================");
   2787     cli_out("\nCalling flexport_test_init ...\n");
   2788     flexport_parse_test_params(unit, a);
   2789     flexport_l3uc_init_env(unit, a, pa);
   2790     flexport_set_chip_dependent_params(unit);
   2791 
   2792     flex_p->test_fail = 0;
   2793 
   2794     if (flex_p->bad_input == 1 ||
   2795         flex_p->test_fail == 1) {
   2796         goto done;
   2797     }
   2798 
   2799     stream_set_mac_lpbk(unit, PBMP_PORT_ALL(unit));
   2800     stream_turn_off_cmic_mmu_bkp(unit);
   2801     stream_turn_off_fc(unit, PBMP_PORT_ALL(unit));
   2802 
   2803 done:
   2804     return 0;
   2805 }
   2806 
   2807 /*
   2808  * Function:
   2809  *      flexport_td3_test
   2810  * Purpose:
   2811  *      Set up ports/streams and send packets.
   2812  * Parameters:
   2813  *      unit - StrataSwitch Unit #.
   2814  *
   2815  * Returns:
   2816  *     Nothing
   2817  */
   2818 int
   2819 flexport_td3_test(int unit, args_t *a, void *pa)
   2820 {
   2821     int p;
   2822     pbmp_t pbm;
   2823     flexport_mc_t *flex_p = flexport_parray[unit];
   2824 
   2825     if (flex_p->bad_input == 1 ||
   2826         flex_p->test_fail == 1) {
   2827         goto done;
   2828     }
   2829 
   2830     cli_out("\n==================================================");
   2831     cli_out("\nCalling flexport_test ... \n");
   2832     /* init port config */
   2833     flexport_run_flex(unit, 0);
   2834 
   2835     /* divide ports into l3uc usage and impc usage */
   2836     flexport_divide_ports_for_l3uc_ipmc(unit);
   2837 
   2838     /* 1.1 set traffic for ipmc */
   2839     flexport_ipmc_set_port_property(unit);
   2840     flexport_ipmc_set_up_streams(unit);
   2841     flexport_ipmc_send_pkts(unit);
   2842 
   2843     /* 1.2 set traffic for l3uc */
   2844     flexport_l3uc_update_stream(unit, flex_p->l3uc_pbmp);
   2845 
   2846     /* 1.3 check port rate for l3uc and ipmc */
   2847     flexport_l3uc_chk_rate(unit, flex_p->l3uc_pbmp);
   2848     flexport_ipmc_chk_rate(unit);
   2849 
   2850     /* 2 flex port */
   2851     flexport_run_flex(unit, 1);
   2852 
   2853     /* 3.1 update ipmc stream */
   2854     flexport_ipmc_update_stream(unit);
   2855 
   2856     /* 3.2 update l3uc stream*/
   2857     BCM_PBMP_CLEAR(pbm);
   2858     PBMP_ITER(flex_p->flex_lport_up_pbmp, p) {
   2859         if (flexport_is_l3uc_port(unit, p)) SOC_PBMP_PORT_ADD(pbm, p);
   2860     }
   2861     PBMP_ITER(flex_p->flex_lport_ch_pbmp, p) {
   2862         if (flexport_is_l3uc_port(unit, p)) SOC_PBMP_PORT_ADD(pbm, p);
   2863     }
   2864     flexport_l3uc_update_stream(unit, pbm);
   2865 
   2866     /* 4.1 check counter, rate, integrity for l3uc */
   2867     flexport_l3uc_chk_rate(unit, pbm);
   2868     flexport_l3uc_chk_integrity(unit, pbm);
   2869 
   2870     /* 4.2 check counter, rate, integrity for ipmc */
   2871     flexport_ipmc_chk_rate(unit);
   2872     flexport_ipmc_chk_integrity(unit);
   2873 
   2874 
   2875 done:
   2876     return 0;
   2877 }
   2878 
   2879 /*
   2880  * Function:
   2881  *      flexport_td3_test_cleanup
   2882  * Purpose:
   2883  *      Do test end checks and free all allocated memory.
   2884  * Parameters:
   2885  *      unit - StrataSwitch Unit #.
   2886  *
   2887  * Returns:
   2888  *     Nothing
   2889  */
   2890 int
   2891 flexport_td3_test_cleanup(int unit, void *pa)
   2892 {
   2893     int rv;
   2894     flexport_mc_t *flex_p = flexport_parray[unit];
   2895     flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit];
   2896 
   2897     if (flex_p->bad_input == 1) {
   2898         flex_p->test_fail = 1;
   2899         goto done;
   2900     }
   2901     cli_out("\nCalling flexport_test_cleanup");
   2902 
   2903 done:
   2904 
   2905     /* reset env to initial state */
   2906     if (flex_p->env_linkscan_enable) {
   2907         cli_out("\nEnabling linkscan");
   2908         BCM_IF_ERROR_RETURN(bcm_linkscan_mode_set_pbm(unit,
   2909                             PBMP_PORT_ALL(unit), BCM_LINKSCAN_MODE_SW));
   2910         BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 1));
   2911     }
   2912     if (flex_p->env_counter_interval > 0) {
   2913         cli_out("\nEnabling counter collection with interval %0d",
   2914                 flex_p->env_counter_interval);
   2915         BCM_IF_ERROR_RETURN(soc_counter_start(unit, flex_p->env_counter_flags,
   2916                                                  flex_p->env_counter_interval,
   2917                                                  PBMP_PORT_ALL(unit)));
   2918     }
   2919     bcm_vlan_init(unit);
   2920 
   2921     /* print */
   2922     rv = (flex_p->test_fail == 1) ? BCM_E_FAIL : BCM_E_NONE;
   2923     cli_out("\n==================================================");
   2924     cli_out("\n==================================================");
   2925     if (flex_p->test_fail == 1) {
   2926         cli_out("\n[Flexport test failed]\n\n");
   2927     } else {
   2928         cli_out("\n[Flexport test passed]\n\n");
   2929     }
   2930 
   2931     /* free mem */
   2932     sal_free(rate_calc_p);
   2933     sal_free(flex_p->ipmc_exp_rate);
   2934     sal_free(flex_p->ipmc_tpkt_start);
   2935     sal_free(flex_p->ipmc_tpkt_end);
   2936     sal_free(flex_p);
   2937 
   2938     return rv;
   2939 }
   2940 
   2941 #endif /* BCM_ESW_SUPPORT */