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

latency.c (25432B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * The purpose of this test is to measure the latency of the chip according to RFC2544. Since this
      8  * test uses 1588 timestamps to measure the latency and timestamping is added at the TSC, this
      9  * test requires one external cable to loop back the packets between a port pair being measured.
     10  * Thus, the speeds of the port pair have to be the same as the port speed being measured.
     11  * In order to cover all available port speeds, the cable may need to be moved to port pairs of
     12  * different speed and the chip may need to be rebooted into a different TDM.
     13  *
     14  * First, this test creates an infinite loop in an swirling port. After the CPU has deposited enough
     15  * packets into the swirl to achieve line rate, the packets will be redirected to the port pair via egress
     16  * VLAN translate and L2 switching. Then, the packets get ingress or egress time stamped twiced at
     17  * the externally connected port pair. Finally, the packets are redirected back to the CPU via
     18  * egress VLAN translate and L2 switching. The CPU checks the packet integrity and computes the
     19  * latencies by substracting the second timestamp with the first timestamp of each packet
     20  *
     21  * Configuration parameters passed from CLI:
     22  * IngEgrTs: Set to 0 for ingress timestamping (default), 1 to egress timestamping.
     23  * PktSize: Packet size in bytes.
     24  * FloodCnt: Number of packets in each swill.
     25  * SwirlInt: Interval in seconds over which rate is to be calculated
     26  * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default).
     27  */
     28 
     29 #include <appl/diag/system.h>
     30 #include <shared/alloc.h>
     31 #include <shared/bsl.h>
     32 
     33 #include <soc/cm.h>
     34 #include <soc/dma.h>
     35 #include <soc/drv.h>
     36 #include <soc/dcb.h>
     37 #include <soc/cmicm.h>
     38 #include <soc/cmic.h>
     39 
     40 #include <sal/types.h>
     41 #include <appl/diag/parse.h>
     42 #include <bcm/port.h>
     43 #include <bcm/vlan.h>
     44 #include <bcm/time.h>
     45 
     46 #include "testlist.h"
     47 #include "gen_pkt.h"
     48 #include "streaming_lib.h"
     49 
     50 #define MAC_DA {0x12,0x34,0x56,0x78,0x9a,0xbc}
     51 #define MAC_SA {0xfe,0xdc,0xba,0x98,0x76,0x54}
     52 #define PKT_VLAN 0xa
     53 
     54 #define XLATE_VLAN0 0xb
     55 #define XLATE_VLAN1 0xc
     56 #define CPU_VLAN 0xd
     57 
     58 #define MAX_FP_PORTS 130
     59 
     60 #define NULL_DEST 999
     61 
     62 #define EGR_TS_PARAM_DEFAULT 0
     63 #define PKT_SIZE_PARAM_DEFAULT 64
     64 #define FLOOD_PKT_CNT_PARAM_DEFAULT 100
     65 #define SWIRL_INTERVAL_PARAM_DEFAULT 10
     66 #define SWIRL_PORT_PARAM_DEFAULT 1
     67 #define TIMESTAMP_PORT1_PARAM_DEFAULT 5
     68 #define TIMESTAMP_PORT2_PARAM_DEFAULT 9
     69 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1
     70 
     71 #if defined(BCM_ESW_SUPPORT) && \
     72   (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT))
     73 
     74 typedef struct latency_s {
     75     uint32 num_fp_ports;
     76     uint32 num_streams;
     77     int *port_speed;
     78     int *port_list;
     79     int *dest_port;
     80     uint32 *stream;
     81     uint32 *port_oversub;
     82     uint32 num_pipes;
     83     uint32 total_chip_bw;
     84     uint32 bw_per_pipe;
     85     uint32 *ovs_ratio_x1000;
     86     uint64 *rate;
     87     uint64 *exp_rate;
     88     uint64 *tpkt_start;
     89     uint64 *tpkt_end;
     90     uint64 *tbyt_start;
     91     uint64 *tbyt_end;
     92     uint32 egr_ts_param;
     93     uint32 pkt_size_param;
     94     uint32 flood_pkt_cnt_param;
     95     uint32 swirl_interval_param;
     96     uint32 swirl_port_param;
     97     uint32 timestamp_port1_param;
     98     uint32 timestamp_port2_param;
     99     uint32 check_packet_integrity_param;
    100     uint32 bad_input;
    101     int test_fail;
    102     uint32 pkt_seed;
    103 } latency_t;
    104 
    105 static latency_t *latency_parray[SOC_MAX_NUM_DEVICES];
    106 
    107 
    108 /*
    109  * Function:
    110  *      latency_chk_port_rate
    111  * Purpose:
    112  *      Check actual port rates against expected port rates.
    113  * Parameters:
    114  *      unit - StrataSwitch Unit #.
    115  *
    116  * Returns:
    117  *     SOC_E_XXXX
    118  */
    119 static bcm_error_t
    120 latency_chk_port_rate(int unit)
    121 {
    122     int port;
    123     bcm_error_t rv = BCM_E_NONE;
    124     stream_rate_t *rate_calc;
    125     latency_t *latency_p = latency_parray[unit];
    126 
    127     rate_calc = (stream_rate_t *)
    128                  sal_alloc(sizeof(stream_rate_t), "rate_calc");
    129     if (rate_calc == NULL) {
    130         test_error(unit, "Failed to allocate memory for rate_calc\n");
    131         return BCM_E_FAIL;
    132     }
    133     sal_memset(rate_calc, 0, sizeof(stream_rate_t));
    134 
    135     rate_calc->mode         = 1; /* check act_rate by tx_rate */
    136     rate_calc->pkt_size     = latency_p->pkt_size_param;
    137     rate_calc->interval_len = latency_p->swirl_interval_param;
    138 
    139     SOC_PBMP_CLEAR(rate_calc->pbmp);
    140     port = latency_p->swirl_port_param;
    141     SOC_PBMP_PORT_ADD(rate_calc->pbmp, port);
    142     /* src_port */
    143     rate_calc->src_port[port] = port;
    144 
    145     rv = stream_chk_port_rate(unit, PBMP_PORT_ALL(unit), rate_calc);
    146 
    147     sal_free(rate_calc);
    148     return rv;
    149 }
    150 
    151 /*
    152  * Function:
    153  *      latency_chk_pkt_integrity
    154  * Purpose:
    155  *      Redirect all packets back to CPU and check packet integrity
    156  * Parameters:
    157  *      unit - StrataSwitch Unit #.
    158  *
    159  * Returns:
    160  *     SOC_E_XXXX
    161  */
    162 static bcm_error_t
    163 latency_chk_pkt_integrity(int unit)
    164 {
    165     int port;
    166     int param_pkt_seed;
    167     uint8 mac_da[] = MAC_DA;
    168     uint8 mac_sa[] = MAC_SA;
    169     stream_integrity_t *pkt_intg;
    170     bcm_error_t rv = BCM_E_NONE;
    171     latency_t *latency_p = latency_parray[unit];
    172 
    173     param_pkt_seed = latency_p->pkt_seed;
    174 
    175     pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg");
    176     if (pkt_intg == NULL) {
    177         test_error(unit, "Failed to allocate memory for pkt_intg\n");
    178         return BCM_E_FAIL;
    179     }
    180     sal_memset(pkt_intg, 0, sizeof(stream_integrity_t));
    181 
    182     pkt_intg->type = PKT_TYPE_L2_TS;
    183     SOC_PBMP_CLEAR(pkt_intg->rx_pbmp);
    184     port = latency_p->timestamp_port1_param;
    185      /* rx_pbmp */
    186      SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port);
    187      /* rx_vlan */
    188      pkt_intg->rx_vlan[port] = CPU_VLAN;
    189      /* tx_vlan */
    190      pkt_intg->tx_vlan[port] = CPU_VLAN;
    191      /* port_flood_cnt */
    192      pkt_intg->port_flood_cnt[port] = latency_p->flood_pkt_cnt_param;
    193      /* port_pkt_seed */
    194      pkt_intg->port_pkt_seed[port] = param_pkt_seed;
    195      /* mac_da, mac_sa */
    196      sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR);
    197      sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR);
    198 
    199     if (stream_chk_pkt_integrity(unit, pkt_intg) != BCM_E_NONE) {
    200         rv = BCM_E_FAIL;
    201     }
    202 
    203     sal_free(pkt_intg);
    204     return rv;
    205 }
    206 
    207 /*
    208  * Function:
    209  *      latency_parse_test_params
    210  * Purpose:
    211  *      Parse CLI parameters, create test structure and flag bad inputs.
    212  * Parameters:
    213  *      unit - StrataSwitch Unit #.
    214  *      a - Pointer to arguments
    215  *
    216  * Returns:
    217  *     Nothing
    218  * Notes:
    219  *      latency_p->bad_input set from here - tells test to crash out in case
    220  *      CLI input combination is invalid.
    221  */
    222 static void
    223 latency_parse_test_params(int unit, args_t *a)
    224 {
    225     parse_table_t parse_table;
    226     latency_t *latency_p = latency_parray[unit];
    227 
    228     const char tr510_test_usage[] =
    229 #ifdef COMPILER_STRING_CONST_LIMIT
    230     "\nDocumentation too long to be displayed with -pedantic compiler\n";
    231 #else
    232     "\nLatency test to check basic L2 packet switching. The test pairs up\n"
    233     "same speed ports and creates L2UC traffic swills. Test also\n"
    234     "calculates expected rates based on port config and oversub ratio, measures\n"
    235     "actual rate over a period of time and conducts rate checks. Finally all\n"
    236     "packets in each swill will be redirected to the CPU and checked for integrity.\n"
    237     "\n"
    238     "Configuration parameters passed from CLI:\n"
    239     "IngEgrTs: Set to 0 for ingress timestamping (default), 1 to egress timestamping.\n"
    240     "PktSize: Packet size in bytes.\n"
    241     "FloodCnt: Number of packets in each swill.\n"
    242     "SwirlInt: Interval in seconds over which rate is to be calculated\n"
    243     "ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default).\n";
    244 #endif
    245 
    246     latency_p->bad_input = 0;
    247 
    248     latency_p->egr_ts_param = EGR_TS_PARAM_DEFAULT;
    249     latency_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT;
    250     latency_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT;
    251     latency_p->swirl_interval_param = SWIRL_INTERVAL_PARAM_DEFAULT;
    252     latency_p->swirl_port_param = SWIRL_PORT_PARAM_DEFAULT;
    253     latency_p->timestamp_port1_param = TIMESTAMP_PORT1_PARAM_DEFAULT;
    254     latency_p->timestamp_port2_param = TIMESTAMP_PORT2_PARAM_DEFAULT;
    255     latency_p->check_packet_integrity_param
    256                             = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT;
    257 
    258     /*Parse CLI opts */
    259 
    260     parse_table_init(unit, &parse_table);
    261     parse_table_add(&parse_table, "EgrTs", PQ_INT|PQ_DFL, 0,
    262                     &(latency_p->egr_ts_param), NULL);
    263     parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0,
    264                     &(latency_p->pkt_size_param), NULL);
    265     parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0,
    266                     &(latency_p->flood_pkt_cnt_param), NULL);
    267     parse_table_add(&parse_table, "SwirlInt", PQ_INT|PQ_DFL, 0,
    268                     &(latency_p->swirl_interval_param), NULL);
    269     parse_table_add(&parse_table, "SwirlPort", PQ_INT|PQ_DFL, 0,
    270                     &(latency_p->swirl_port_param), NULL);
    271     parse_table_add(&parse_table, "TimeStampPort1", PQ_INT|PQ_DFL, 0,
    272                     &(latency_p->timestamp_port1_param), NULL);
    273     parse_table_add(&parse_table, "TimeStampPort2", PQ_INT|PQ_DFL, 0,
    274                     &(latency_p->timestamp_port2_param), NULL);
    275     parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0,
    276                     &(latency_p->check_packet_integrity_param), NULL);
    277 
    278     if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) {
    279         test_msg("%s", tr510_test_usage);
    280         test_error(unit,
    281                    "%s: Invalid option: %s\n",
    282                    ARG_CMD(a),
    283                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    284         latency_p->bad_input = 1;
    285         parse_arg_eq_done(&parse_table);
    286     } else {
    287         cli_out("\n");
    288         cli_out("------------- PRINTING TEST PARAMS ------------------\n");
    289         cli_out("EgrTS          = %0d\n", latency_p->egr_ts_param);
    290         cli_out("PktSize        = %0d\n", latency_p->pkt_size_param);
    291         cli_out("SwirlInt       = %0d\n", latency_p->swirl_interval_param);
    292         cli_out("SwirlPort      = %0d\n", latency_p->swirl_port_param);
    293         cli_out("TimeStampPort1 = %0d\n", latency_p->timestamp_port1_param);
    294         cli_out("TimeStampPort2 = %0d\n", latency_p->timestamp_port2_param);
    295         cli_out("FloodCnt       = %0d\n", latency_p->flood_pkt_cnt_param);
    296         cli_out("ChkPktInteg    = %0d\n", latency_p->check_packet_integrity_param);
    297         cli_out("-----------------------------------------------------\n");
    298     }
    299 
    300     if (latency_p->pkt_size_param < MIN_PKT_SIZE) {
    301         test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n",
    302                 MIN_PKT_SIZE);
    303         latency_p->bad_input = 1;
    304     } else if (latency_p->pkt_size_param > MTU) {
    305         test_error(unit,"\n*ERROR: Packet size cannot be higher than %0dB (Device MTU)\n",
    306                 MTU);
    307         latency_p->bad_input = 1;
    308     }
    309 }
    310 
    311 /*
    312  * Function:
    313  *      latency_enable_ingress_egress_timestamp
    314  * Purpose:
    315  *      Enable ingress timestamp generation for the timstamp ports
    316  * Parameters:
    317  *      unit: StrataSwitch Unit #.
    318  *
    319  * Returns:
    320  *     SOC_E_XXXX
    321  */
    322 bcm_error_t
    323 latency_enable_ingress_egress_timestamp(int unit)
    324 {
    325     uint32 rval;
    326     latency_t *latency_p = latency_parray[unit];
    327 
    328     /* Enable Timestamp Generation */
    329     start_cmic_timesync(unit);
    330     READ_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &rval);
    331     soc_reg_field_set(unit, CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr, &rval,
    332                                 ENABLE_COMMON_CONTROLf, 1);
    333     WRITE_CMIC_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, rval);
    334 
    335     /* Enable Ingress Timestamp for timestamp port 1 and 2 */
    336     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port1_param,
    337                                 bcmPortControlPacketTimeStampInsertRx, !latency_p->egr_ts_param));
    338     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port1_param,
    339                                 bcmPortControlPacketTimeStampInsertTx, latency_p->egr_ts_param));
    340     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port1_param,
    341                                 bcmPortControlPacketTimeStampRxId, latency_p->timestamp_port1_param));
    342     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port2_param,
    343                                 bcmPortControlPacketTimeStampInsertRx, !latency_p->egr_ts_param));
    344     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port2_param,
    345                                 bcmPortControlPacketTimeStampInsertTx, latency_p->egr_ts_param));
    346     BCM_IF_ERROR_RETURN(bcm_port_control_set(unit, latency_p->timestamp_port2_param,
    347                                 bcmPortControlPacketTimeStampRxId, latency_p->timestamp_port2_param));
    348     return BCM_E_NONE;
    349 }
    350 
    351 /*
    352  * Function:
    353  *      latency_set_port_property
    354  * Purpose:
    355  *      Set port_list, port_speed and port_oversub arrays. Also call set_exp_rates
    356  * Parameters:
    357  *      unit: StrataSwitch Unit #.
    358  *
    359  * Returns:
    360  *     Safe packet size.
    361  */
    362 static void
    363 latency_set_port_property(int unit)
    364 {
    365     int p, i, j, paired_port;
    366     uint32 can_be_paired = 0;
    367     soc_info_t *si = &SOC_INFO(unit);
    368     latency_t *latency_p = latency_parray[unit];
    369 
    370     latency_p->num_fp_ports = 0;
    371     latency_p->num_streams = 0;
    372 
    373     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
    374         latency_p->num_fp_ports++;
    375     }
    376 
    377     latency_p->port_list =
    378         (int *)sal_alloc(latency_p->num_fp_ports * sizeof(int),
    379                          "port_list");
    380     latency_p->port_speed =
    381         (int *)sal_alloc(latency_p->num_fp_ports * sizeof(int),
    382                          "port_speed_array");
    383     latency_p->dest_port =
    384         (int *)sal_alloc(latency_p->num_fp_ports * sizeof(int),
    385                           "dest_port_array");
    386     latency_p->stream =
    387         (uint32 *)sal_alloc(latency_p->num_fp_ports * sizeof(uint32),
    388                           "stream");
    389     latency_p->port_oversub =
    390         (uint32 *) sal_alloc(latency_p->num_fp_ports * sizeof(uint32),
    391                            "port_oversub_array");
    392 
    393     i = 0;
    394     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
    395         latency_p->port_list[i] = p;
    396         i++;
    397     }
    398 
    399     for (i = 0; i < latency_p->num_fp_ports; i++) {
    400         latency_p->port_speed[i] =
    401             si->port_speed_max[latency_p->port_list[i]];
    402 
    403         switch(latency_p->port_speed[i]) {
    404             case 11000: latency_p->port_speed[i] = 10600; break;
    405             case 27000: latency_p->port_speed[i] = 26500; break;
    406             case 42000: latency_p->port_speed[i] = 42400; break;
    407             default: break;
    408         }
    409     }
    410 
    411     for (i = 0; i < latency_p->num_fp_ports; i++) {
    412         if (SOC_PBMP_MEMBER(si->oversub_pbm, latency_p->port_list[i]) &&
    413             (!(SOC_PBMP_MEMBER(si->management_pbm, latency_p->port_list[i])))) {
    414             latency_p->port_oversub[i] = 1;
    415         } else {
    416             latency_p->port_oversub[i] = 0;
    417         }
    418     }
    419 
    420     for (i = 0; i < latency_p->num_fp_ports; i++) {
    421         latency_p->dest_port[i] = NULL_DEST;
    422     }
    423 
    424     /* set src and dst ports for each stream */
    425     for (i = 0; i < latency_p->num_fp_ports; i++) {
    426         can_be_paired = 0;
    427         if(latency_p->dest_port[i] == NULL_DEST) {
    428             for (j = 0;j < latency_p->num_fp_ports; j++) {
    429                 if((latency_p->dest_port[j] == NULL_DEST)
    430                         && (latency_p->port_speed[i]
    431                                     == latency_p->port_speed[j])
    432                         && (i!=j)) {
    433                     can_be_paired = 1;
    434                 }
    435             }
    436 
    437             if(can_be_paired) {
    438                 do {
    439                     paired_port = sal_rand() % latency_p->num_fp_ports;
    440                 }while((latency_p->port_speed[i] !=
    441                                 latency_p->port_speed[paired_port])
    442                         || (latency_p->dest_port[paired_port] != NULL_DEST)
    443                                                         || (i == paired_port));
    444 
    445                 latency_p->dest_port[i] = paired_port;
    446                 latency_p->dest_port[paired_port] = i;
    447                 latency_p->stream[latency_p->num_streams] = i;
    448                 latency_p->num_streams++;
    449             }
    450         }
    451     }
    452 
    453     {
    454         /* print */
    455         LOG_INFO(BSL_LS_APPL_TESTS,
    456                  (BSL_META_U(unit, "\n==== STREAM INFO (VERBOSE) =====\n")));
    457         LOG_INFO(BSL_LS_APPL_TESTS,
    458                  (BSL_META_U(unit, "\n%8s%8s%8s%8s%8s%8s\n"),
    459                              "idx", "port", "dst", "speed", "ovsb", "HiGig"));
    460         for (i = 0; i < latency_p->num_fp_ports; i++) {
    461             LOG_INFO(BSL_LS_APPL_TESTS,
    462                      (BSL_META_U(unit, "%8d%8d%8d%7dG"),
    463                                  i,
    464                                  latency_p->port_list[i],
    465                                  latency_p->port_list[latency_p->dest_port[i]],
    466                                  latency_p->port_speed[i]/1000));
    467             if (SOC_PBMP_MEMBER(si->oversub_pbm, latency_p->port_list[i])) {
    468                 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "OS"));
    469             } else {
    470                 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "--"));
    471             }
    472             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "--"));
    473             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
    474         }
    475     }
    476 }
    477 
    478 /*
    479  * Function:
    480  *      latency_set_up_streams
    481  * Purpose:
    482  *      Program switch to set up L2UC streams between port pairs. For Ethernet
    483  *      ports this involves setting up VLAN translations and L2 entries to get
    484  *      a packet flow of CPU -> P0 (Vlan0, Xlate_Vlan0) -> P1(Xlate_vlan1) -> P0 ...
    485  *
    486  * Parameters:
    487  *      unit: StrataSwitch Unit #.
    488  *
    489  *
    490  * Returns:
    491  *     SOC_E_XXXX
    492  */
    493 bcm_error_t
    494 latency_set_up_streams(int unit)
    495 {
    496     pbmp_t pbm, ubm;
    497     latency_t *latency_p = latency_parray[unit];
    498     bcm_l2_addr_t l2_addr;
    499     bcm_mac_t mac_da = MAC_DA;
    500     port_tab_entry_t port_tab_entry;
    501 
    502     if (!SOC_MEM_IS_VALID(unit, PORT_TABm)) {
    503         uint32 entry[SOC_MAX_MEM_WORDS];
    504         soc_pbmp_t pbmp;
    505 
    506         SOC_PBMP_PORT_SET(pbmp, latency_p->swirl_port_param);
    507         sal_memset(entry, 0, sizeof(port_bridge_bmap_entry_t));
    508         soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry, BITMAPf, &pbmp);
    509         BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm, COPYNO_ALL, 0, entry));
    510     } else {
    511         BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, COPYNO_ALL, latency_p->swirl_port_param,
    512                             port_tab_entry.entry_data));
    513         soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, PORT_BRIDGEf, 1);
    514         BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, COPYNO_ALL, latency_p->swirl_port_param,
    515                             port_tab_entry.entry_data));
    516     }
    517 
    518     BCM_PBMP_CLEAR(ubm);
    519     bcm_vlan_destroy_all(unit);
    520     bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE);
    521 
    522     bcm_vlan_create(unit, (bcm_vlan_t) (PKT_VLAN));
    523     BCM_PBMP_CLEAR(pbm);
    524     BCM_PBMP_PORT_ADD(pbm, latency_p->swirl_port_param);
    525     bcm_vlan_port_add(unit, (bcm_vlan_t) (PKT_VLAN), pbm, ubm);
    526     /* set mac loopback on the swriling port */
    527     stream_set_mac_lpbk(unit, pbm);
    528 
    529     bcm_vlan_create(unit, (bcm_vlan_t) (XLATE_VLAN0));
    530     bcm_vlan_create(unit, (bcm_vlan_t) (XLATE_VLAN1));
    531     BCM_PBMP_CLEAR(pbm);
    532     BCM_PBMP_PORT_ADD(pbm, latency_p->timestamp_port1_param);
    533     BCM_PBMP_PORT_ADD(pbm, latency_p->timestamp_port2_param);
    534     bcm_vlan_port_add(unit, (bcm_vlan_t) (XLATE_VLAN0), pbm, ubm);
    535     bcm_vlan_port_add(unit, (bcm_vlan_t) (XLATE_VLAN1), pbm, ubm);
    536 
    537     bcm_vlan_create(unit, (bcm_vlan_t) (CPU_VLAN));
    538     BCM_PBMP_CLEAR(pbm);
    539     BCM_PBMP_PORT_ADD(pbm, 0);
    540     bcm_vlan_port_add(unit, (bcm_vlan_t) (CPU_VLAN), pbm, ubm);
    541 
    542     bcm_vlan_translate_egress_add(unit, latency_p->timestamp_port1_param,
    543                             (bcm_vlan_t)(XLATE_VLAN0),
    544                             (bcm_vlan_t)(XLATE_VLAN1), 0);
    545     bcm_vlan_translate_egress_add(unit, latency_p->timestamp_port1_param,
    546                             (bcm_vlan_t)(XLATE_VLAN1),
    547                             (bcm_vlan_t)(CPU_VLAN), 0);
    548 
    549     bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(XLATE_VLAN0));
    550     l2_addr.port = latency_p->timestamp_port1_param;
    551     l2_addr.flags = 0;
    552     bcm_l2_addr_add(unit, &l2_addr);
    553 
    554     bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(XLATE_VLAN1));
    555     l2_addr.port = latency_p->timestamp_port1_param;
    556     l2_addr.flags = 0;
    557     bcm_l2_addr_add(unit, &l2_addr);
    558 
    559     bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(CPU_VLAN));
    560     l2_addr.port = 0;
    561     l2_addr.flags = 0;
    562     bcm_l2_addr_add(unit, &l2_addr);
    563     return BCM_E_NONE;
    564 }
    565 
    566 /*
    567  * Function:
    568  *      latency_send_pkts
    569  * Purpose:
    570  *      Send packets to flood the swirl port.
    571  * Parameters:
    572  *      unit - StrataSwitch Unit #.
    573  *
    574  * Returns:
    575  *     Nothing
    576  */
    577 static void
    578 latency_send_pkts(int unit)
    579 {
    580     uint8 mac_da[] = MAC_DA;
    581     uint8 mac_sa[] = MAC_SA;
    582     latency_t *latency_p = latency_parray[unit];
    583     stream_pkt_t *tx_pkt;
    584 
    585     tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt");
    586     sal_memset(tx_pkt, 0, sizeof(stream_pkt_t));
    587 
    588     cli_out("\nSending %0d packets to swirl port %0d\n",
    589               latency_p->flood_pkt_cnt_param, latency_p->swirl_port_param);
    590 
    591     tx_pkt->port = latency_p->swirl_port_param;
    592     tx_pkt->num_pkt  = latency_p->flood_pkt_cnt_param;
    593     tx_pkt->pkt_seed = latency_p->pkt_seed;
    594     tx_pkt->pkt_size = latency_p->pkt_size_param;
    595     tx_pkt->tx_vlan = PKT_VLAN;
    596     sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR);
    597     sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR);
    598     stream_tx_pkt(unit, tx_pkt);
    599 
    600     sal_free(tx_pkt);
    601 }
    602 
    603 /*
    604  * Function:
    605  *      latency_test_init
    606  * Purpose:
    607  *      Test init function. Parse CLI params and do necessary init.
    608  * Parameters:
    609  *      unit - StrataSwitch Unit #.
    610  *
    611  * Returns:
    612  *     Nothing
    613  */
    614 int
    615 latency_test_init(int unit, args_t *a, void **pa)
    616 {
    617     latency_t *latency_p;
    618 
    619     latency_p = latency_parray[unit];
    620     latency_p = sal_alloc(sizeof(latency_t), "latency_test");
    621     sal_memset(latency_p, 0, sizeof(latency_t));
    622     latency_parray[unit] = latency_p;
    623     cli_out("\nCalling latency_test_init");
    624     latency_parse_test_params(unit, a);
    625 
    626     latency_p->test_fail = 0;
    627     if (latency_p->bad_input == 1) {
    628         goto done;
    629     }
    630 
    631     /* coverity[dont_call : FALSE] */
    632     latency_p->pkt_seed = sal_rand();
    633 
    634 done:
    635     return 0;
    636 }
    637 
    638 /*
    639  * Function:
    640  *      latency_test
    641  * Purpose:
    642  *      Set up ports/streams and send packets.
    643  * Parameters:
    644  *      unit - StrataSwitch Unit #.
    645  *
    646  * Returns:
    647  *     Nothing
    648  */
    649 int
    650 latency_test(int unit, args_t *a, void *pa)
    651 {
    652     latency_t *latency_p = latency_parray[unit];
    653 
    654     if (latency_p->bad_input == 1) {
    655         goto done;
    656     }
    657 
    658     cli_out("\nCalling latency_test");
    659     /* turn off cmic to mmu backpressure */
    660     stream_turn_off_cmic_mmu_bkp(unit);
    661     /* turn off flow control */
    662     stream_turn_off_fc(unit, PBMP_PORT_ALL(unit));
    663     latency_set_port_property(unit);
    664     if (latency_enable_ingress_egress_timestamp(unit) != BCM_E_NONE) {
    665         latency_p->test_fail = 1;
    666     }
    667     if (latency_set_up_streams(unit) != BCM_E_NONE) {
    668         latency_p->test_fail = 1;
    669     }
    670     latency_send_pkts(unit);
    671 
    672     /* check counter */
    673     if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) {
    674         latency_p->test_fail = 1;
    675     }
    676     /* check rate */
    677     if (latency_chk_port_rate(unit) != BCM_E_NONE) {
    678         latency_p->test_fail = 1;
    679     }
    680     bcm_vlan_translate_egress_add(unit, latency_p->swirl_port_param,
    681                             (bcm_vlan_t)(PKT_VLAN),
    682                             (bcm_vlan_t)(XLATE_VLAN0), 0);
    683     /* check integrity */
    684     if (latency_p->check_packet_integrity_param != 0) {
    685         if (latency_chk_pkt_integrity(unit) != BCM_E_NONE) {
    686             latency_p->test_fail = 1;
    687         }
    688     }
    689 
    690 done:
    691     return 0;
    692 }
    693 
    694 /*
    695  * Function:
    696  *      latency_test_cleanup
    697  * Purpose:
    698  *      Do test end checks and free all allocated memory.
    699  * Parameters:
    700  *      unit - StrataSwitch Unit #.
    701  *
    702  * Returns:
    703  *     Nothing
    704  */
    705 int
    706 latency_test_cleanup(int unit, void *pa)
    707 {
    708     latency_t *latency_p = latency_parray[unit];
    709     int rv;
    710 
    711     if (latency_p->bad_input == 1) {
    712         goto done;
    713     }
    714     LOG_INFO(BSL_LS_APPL_TESTS,
    715              (BSL_META_U(unit, "\nCalling latency_test_cleanup\n")));
    716 
    717     sal_free(latency_p->port_speed);
    718     sal_free(latency_p->port_list);
    719     sal_free(latency_p->dest_port);
    720     sal_free(latency_p->stream);
    721     sal_free(latency_p->port_oversub);
    722     sal_free(latency_p->ovs_ratio_x1000);
    723     sal_free(latency_p->rate);
    724     sal_free(latency_p->exp_rate);
    725     sal_free(latency_p->tpkt_start);
    726     sal_free(latency_p->tpkt_end);
    727     sal_free(latency_p->tbyt_start);
    728     sal_free(latency_p->tbyt_end);
    729 
    730 done:
    731     if (latency_p->bad_input == 1) {
    732         latency_p->test_fail = 1;
    733     }
    734 
    735     if (latency_p->test_fail == 1) {
    736         rv = BCM_E_FAIL;
    737     } else {
    738         rv = BCM_E_NONE;
    739     }
    740 
    741     cli_out("\n==================================================");
    742     cli_out("\n==================================================");
    743     if (latency_p->test_fail == 1) {
    744         cli_out("\n[Latency test failed]\n\n");
    745     } else {
    746         cli_out("\n[Latency test passed]\n\n");
    747     }
    748 
    749     sal_free(latency_p);
    750 
    751     return rv;
    752 }
    753 #endif /* BCM_ESW_SUPPORT */